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

184 lines
4.7 KiB
React
Raw Normal View History

import React, { useState } from 'react';
2020-04-06 22:39:49 +02:00
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { Button, Icon } from '../';
2020-04-06 22:39:49 +02:00
2020-04-07 19:03:47 +02:00
const borderSize = 4;
2020-04-14 00:35:32 +02:00
const expandedWidth = 248;
const collapsedWidth = 56;
2020-04-07 19:03:47 +02:00
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-08 17:00:08 +02:00
const collapsedHideWidth = expandedWidth - collapsedWidth - borderSize;
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-08 17:00:08 +02:00
left: { marginLeft: `-${collapsedHideWidth}px` },
right: { marginRight: `-${collapsedHideWidth}px` },
2020-04-06 22:39:49 +02:00
},
};
2020-04-08 17:00:08 +02:00
const baseClasses =
2020-04-14 00:35:32 +02:00
'transition-all duration-300 ease-in-out h-100 bg-primary-dark border-black flex flex-col justify-start box-content';
2020-04-07 19:03:47 +02:00
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 = {
2020-04-08 18:00:07 +02:00
left: 'push-left',
right: 'push-right',
};
2020-04-10 01:31:21 +02:00
const position = {
left: {
right: 5,
},
right: {
left: 5,
},
};
const getChildComponent = (childComponents, componentOpen) => {
if (Array.isArray(childComponents)) {
return childComponents.find(
_childComponent => _childComponent.name === componentOpen
);
} else {
return childComponents;
}
};
2020-04-06 22:39:49 +02:00
const SidePanel = ({
side,
className,
defaultComponentOpen,
childComponents,
2020-04-06 22:39:49 +02:00
}) => {
const [componentOpen, setComponentOpen] = useState(defaultComponentOpen);
const openStatus = componentOpen ? 'open' : 'closed';
2020-04-07 19:03:47 +02:00
const style = Object.assign({}, styleMap[openStatus][side], baseStyle);
const childComponent = getChildComponent(childComponents, componentOpen);
const getPanelButtons = () => {
const _childComponents = Array.isArray(childComponents)
? childComponents
: [childComponents];
return _childComponents.map((childComponent, i) => {
return (
<Button
key={i}
variant="text"
color="inherit"
onClick={() => {
setComponentOpen(childComponent.name);
}}
style={{
minWidth: `${collapsedWidth}px`,
width: `${collapsedWidth}px`,
}}
name={childComponent.name}
className="flex flex-col text-xs px-1 py-1 text-white border-transparent border-b"
>
<Icon
name={childComponent.iconName}
className="text-primary-active"
/>
<span className="mt-2 text-white text-xs">
{childComponent.iconLabel}
</span>
</Button>
);
});
};
return (
<div
className={classnames(
className,
baseClasses,
classesMap[openStatus][side]
)}
style={style}
>
{componentOpen ? (
<React.Fragment>
2020-04-13 19:53:36 +02:00
<div className="px-3 border-b border-secondary-light">
<Button
variant="text"
color="inherit"
rounded="none"
onClick={() => {
setComponentOpen(null);
2020-04-13 19:53:36 +02:00
}}
name={childComponent.name}
2020-04-13 19:53:36 +02:00
className="flex flex-row items-center px-3 h-12 relative w-full"
>
<Icon
name={openIconName[side]}
className={classnames(
'text-primary-active absolute',
side === 'left' && 'order-last'
)}
style={{ ...position[side] }}
/>
<span className="flex-1 text-primary-active">
{childComponent.label}
2020-04-13 19:53:36 +02:00
</span>
</Button>
</div>
<childComponent.content />
</React.Fragment>
) : (
<React.Fragment>{getPanelButtons()}</React.Fragment>
2020-04-07 19:03:47 +02:00
)}
2020-04-06 22:39:49 +02:00
</div>
);
};
SidePanel.defaultProps = {
defaultComponentOpen: null,
2020-04-06 22:39:49 +02:00
};
SidePanel.propTypes = {
side: PropTypes.oneOf(['left', 'right']).isRequired,
className: PropTypes.string,
defaultComponentOpen: PropTypes.string,
childComponents: PropTypes.oneOfType([
PropTypes.shape({
iconName: PropTypes.string.isRequired,
iconLabel: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
content: PropTypes.func, // TODO: Should be node, but it keeps complaining?
}),
PropTypes.arrayOf(
PropTypes.shape({
iconName: PropTypes.string.isRequired,
iconLabel: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
content: PropTypes.func, // TODO: Should be node, but it keeps complaining?
})
),
]),
2020-04-06 22:39:49 +02:00
};
export default SidePanel;