ohif-viewer/platform/ui/src/components/SidePanel/SidePanel.jsx

132 lines
3.2 KiB
React
Raw Normal View History

import React, { useState, useCallback } from 'react';
2020-04-06 22:39:49 +02:00
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { Button, Icon } from '@ohif/ui';
2020-04-07 19:03:47 +02:00
const borderSize = 4;
const expandedWidth = 320;
const collapsedWidth = 60;
2020-04-06 22:39:49 +02:00
const baseStyle = {
2020-04-07 19:03:47 +02:00
maxWidth: `${expandedWidth}px`,
width: `${expandedWidth}px`,
2020-04-06 22:39:49 +02:00
};
2020-04-07 19:03:47 +02:00
const styleMap = {
2020-04-06 22:39:49 +02:00
open: {
2020-04-07 19:03:47 +02:00
left: { marginLeft: '0px' },
right: { marginRight: '0px' },
2020-04-06 22:39:49 +02:00
},
closed: {
2020-04-07 19:03:47 +02:00
left: { marginLeft: `-${expandedWidth - collapsedWidth - borderSize}px` },
right: { marginRight: `-${expandedWidth - collapsedWidth - borderSize}px` },
2020-04-06 22:39:49 +02:00
},
};
const baseClassName =
2020-04-07 19:03:47 +02:00
'transition-all duration-300 ease-in-out h-100 bg-primary-dark border-black flex flex-col justify-start';
const classesMap = {
open: {
left: `border-r-${borderSize}`,
right: `border-l-${borderSize}`,
},
closed: {
left: `border-r-${borderSize} items-end`,
right: `border-l-${borderSize} items-start`,
},
};
2020-04-06 22:39:49 +02:00
const openIconName = {
left: 'panel-left',
right: 'panel-right',
};
2020-04-06 22:39:49 +02:00
const SidePanel = ({
side,
className,
children,
defaultIsOpen,
2020-04-07 19:03:47 +02:00
componentLabel,
iconLabel,
2020-04-06 22:39:49 +02:00
iconName,
}) => {
const [isOpen, setIsOpen] = useState(defaultIsOpen);
2020-04-07 00:29:37 +02:00
const openStatus = isOpen ? 'open' : 'closed';
2020-04-07 19:03:47 +02:00
const style = Object.assign({}, styleMap[openStatus][side], baseStyle);
const getSidePanelHeader = useCallback(() => {
2020-04-07 19:03:47 +02:00
return (
<React.Fragment>
{isOpen ? (
<Button
variant="text"
color="inherit"
rounded="none"
onClick={() => {
setIsOpen(false);
}}
2020-04-07 19:03:47 +02:00
className="flex flex-row items-center border-b w-100 border-secondary-main h-12"
>
<Icon
name={openIconName[side]}
className={classnames(
'text-primary-active',
side === 'left' && 'order-last'
)}
/>
<span className="flex-1 text-primary-active">{componentLabel}</span>
</Button>
) : (
<Button
variant="text"
color="inherit"
onClick={() => {
setIsOpen(true);
}}
2020-04-07 19:03:47 +02:00
style={{
minWidth: `${collapsedWidth}px`,
width: `${collapsedWidth}px`,
}}
className="flex flex-col text-xs px-1 py-1 text-white"
>
<Icon name={iconName} className="text-primary-active" />
<span className="mt-2 text-white text-xs">{iconLabel}</span>
</Button>
)}
</React.Fragment>
);
}, [componentLabel, iconLabel, iconName, isOpen, side]);
2020-04-06 22:39:49 +02:00
return (
<div
2020-04-07 19:03:47 +02:00
className={classnames(
className,
baseClassName,
classesMap[openStatus][side]
)}
2020-04-06 22:39:49 +02:00
style={style}
>
{getSidePanelHeader()}
2020-04-07 19:03:47 +02:00
{isOpen && children}
2020-04-06 22:39:49 +02:00
</div>
);
};
SidePanel.defaultProps = {
defaultIsOpen: false,
};
SidePanel.propTypes = {
side: PropTypes.oneOf(['left', 'right']).isRequired,
2020-04-07 19:03:47 +02:00
iconLabel: PropTypes.string.isRequired,
componentLabel: PropTypes.string.isRequired,
iconName: PropTypes.string.isRequired,
defaultIsOpen: PropTypes.bool,
2020-04-06 22:39:49 +02:00
className: PropTypes.string,
children: PropTypes.node,
};
export default SidePanel;