Update sidePanel to support multiple components
This commit is contained in:
parent
802a8d5f1b
commit
08ebfd5865
@ -1,4 +1,4 @@
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classnames from 'classnames';
|
||||
|
||||
@ -53,30 +53,78 @@ const position = {
|
||||
},
|
||||
};
|
||||
|
||||
const getChildComponent = (childComponents, componentOpen) => {
|
||||
if (Array.isArray(childComponents)) {
|
||||
return childComponents.find(
|
||||
(_childComponent) => _childComponent.name === componentOpen
|
||||
);
|
||||
} else {
|
||||
return childComponents;
|
||||
}
|
||||
};
|
||||
|
||||
const SidePanel = ({
|
||||
side,
|
||||
className,
|
||||
children,
|
||||
defaultIsOpen,
|
||||
componentLabel,
|
||||
iconLabel,
|
||||
iconName,
|
||||
defaultComponentOpen,
|
||||
childComponents,
|
||||
}) => {
|
||||
const [isOpen, setIsOpen] = useState(defaultIsOpen);
|
||||
const openStatus = isOpen ? 'open' : 'closed';
|
||||
const [componentOpen, setComponentOpen] = useState(defaultComponentOpen);
|
||||
|
||||
const openStatus = componentOpen ? 'open' : 'closed';
|
||||
const style = Object.assign({}, styleMap[openStatus][side], baseStyle);
|
||||
|
||||
const getSidePanelHeader = useCallback(() => {
|
||||
return (
|
||||
<React.Fragment>
|
||||
{isOpen ? (
|
||||
const childComponent = getChildComponent(childComponents, componentOpen);
|
||||
|
||||
const getPanelButtons = () => {
|
||||
const _childComponents = Array.isArray(childComponents)
|
||||
? childComponents
|
||||
: [childComponents];
|
||||
return _childComponents.map((childComponent) => {
|
||||
return (
|
||||
<Button
|
||||
key={childComponent.name}
|
||||
variant="text"
|
||||
color="inherit"
|
||||
onClick={() => {
|
||||
setComponentOpen(childComponent.name);
|
||||
}}
|
||||
style={{
|
||||
minWidth: `${collapsedWidth}px`,
|
||||
width: `${collapsedWidth}px`,
|
||||
}}
|
||||
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>
|
||||
<div className="px-3 border-b border-secondary-light">
|
||||
<Button
|
||||
variant="text"
|
||||
color="inherit"
|
||||
rounded="none"
|
||||
onClick={() => {
|
||||
setIsOpen(false);
|
||||
setComponentOpen(null);
|
||||
}}
|
||||
className="flex flex-row items-center px-3 h-12 relative w-full"
|
||||
>
|
||||
@ -89,58 +137,45 @@ const SidePanel = ({
|
||||
style={{ ...position[side] }}
|
||||
/>
|
||||
<span className="flex-1 text-primary-active">
|
||||
{componentLabel}
|
||||
{childComponent.label}
|
||||
</span>
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
<Button
|
||||
variant="text"
|
||||
color="inherit"
|
||||
onClick={() => {
|
||||
setIsOpen(true);
|
||||
}}
|
||||
style={{
|
||||
minWidth: `${collapsedWidth}px`,
|
||||
width: `${collapsedWidth}px`,
|
||||
}}
|
||||
className="flex flex-col text-xs px-1 py-1 text-white border-transparent border-b"
|
||||
>
|
||||
<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]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classnames(
|
||||
className,
|
||||
baseClasses,
|
||||
classesMap[openStatus][side]
|
||||
{childComponent.content}
|
||||
</React.Fragment>
|
||||
) : (
|
||||
<React.Fragment>{getPanelButtons()}</React.Fragment>
|
||||
)}
|
||||
style={style}
|
||||
>
|
||||
{getSidePanelHeader()}
|
||||
{isOpen && children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
SidePanel.defaultProps = {
|
||||
defaultIsOpen: false,
|
||||
defaultComponentOpen: null,
|
||||
};
|
||||
|
||||
SidePanel.propTypes = {
|
||||
side: PropTypes.oneOf(['left', 'right']).isRequired,
|
||||
iconLabel: PropTypes.string.isRequired,
|
||||
componentLabel: PropTypes.string.isRequired,
|
||||
iconName: PropTypes.string.isRequired,
|
||||
defaultIsOpen: PropTypes.bool,
|
||||
className: PropTypes.string,
|
||||
children: PropTypes.node,
|
||||
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.node,
|
||||
}),
|
||||
PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
iconName: PropTypes.string.isRequired,
|
||||
iconLabel: PropTypes.string.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
label: PropTypes.string.isRequired,
|
||||
content: PropTypes.node,
|
||||
})
|
||||
),
|
||||
]),
|
||||
};
|
||||
|
||||
export default SidePanel;
|
||||
|
||||
@ -24,19 +24,52 @@ import { SidePanel } from '@ohif/ui';
|
||||
>
|
||||
<SidePanel
|
||||
side="left"
|
||||
iconName="group-layers"
|
||||
iconLabel="Studies"
|
||||
componentLabel="Studies"
|
||||
defaultIsOpen={false}
|
||||
>
|
||||
<div className="flex justify-center text-white p-2">panel content</div>
|
||||
</SidePanel>
|
||||
childComponents={{
|
||||
iconName: "group-layers",
|
||||
iconLabel: "Studies",
|
||||
name: "studies",
|
||||
label: "Studies",
|
||||
content: <div className="flex justify-center text-white p-2">panel content</div>,
|
||||
}}
|
||||
/>
|
||||
<div className="flex flex-1 h-100 overflow-hidden bg-primary-main items-center justify-center text-white">
|
||||
CONTENT
|
||||
</div>
|
||||
</div>
|
||||
</Playground>
|
||||
|
||||
|
||||
## Multiple panels
|
||||
|
||||
<Playground>
|
||||
<div
|
||||
className="flex flex-row flex-no-wrap flex-1 items-stretch overflow-hidden w-full"
|
||||
style={{ height: '500px' }}
|
||||
>
|
||||
<SidePanel
|
||||
side="left"
|
||||
childComponents={[{
|
||||
iconName: "group-layers",
|
||||
iconLabel: "Studies",
|
||||
name: "studies",
|
||||
label: "Studies",
|
||||
content: <div className="flex justify-center text-white p-2">studies panel content</div>,
|
||||
},
|
||||
{
|
||||
iconName: "list-bullets",
|
||||
iconLabel: "Measure",
|
||||
name: "measurements",
|
||||
label: "Measurements",
|
||||
content: <div className="flex justify-center text-white p-2">measure panel content</div>,
|
||||
}]}
|
||||
/>
|
||||
<div className="flex flex-1 h-100 overflow-hidden bg-primary-main items-center justify-center text-white">
|
||||
CONTENT
|
||||
</div>
|
||||
</div>
|
||||
</Playground>
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={SidePanel} />
|
||||
|
||||
@ -57,14 +57,18 @@ import { tabs } from './studyBrowserMockData';
|
||||
>
|
||||
<SidePanel
|
||||
side="left"
|
||||
iconName="group-layers"
|
||||
iconLabel="Studies"
|
||||
componentLabel="Studies"
|
||||
defaultIsOpen={true}
|
||||
>
|
||||
<StudyBrowser tabs={tabs} />
|
||||
</SidePanel>
|
||||
<div className="flex flex-col flex-1 h-100">
|
||||
defaultComponentOpen='studies'
|
||||
childComponents={{
|
||||
iconName: 'group-layers',
|
||||
iconLabel: 'Studies',
|
||||
label: 'Studies',
|
||||
name: 'studies',
|
||||
content: (
|
||||
<StudyBrowser tabs={tabs} />
|
||||
)
|
||||
}}
|
||||
/>
|
||||
<div className="flex flex-col flex-1 h-full pb-2">
|
||||
<div className="flex flex-2 w-100 border-b border-transparent h-12">
|
||||
<ViewportToolbar />
|
||||
</div>
|
||||
@ -100,45 +104,49 @@ import { tabs } from './studyBrowserMockData';
|
||||
</div>
|
||||
<SidePanel
|
||||
side="right"
|
||||
iconName="list-bullets"
|
||||
iconLabel="Measure"
|
||||
componentLabel="Measurements"
|
||||
defaultIsOpen={true}
|
||||
>
|
||||
<MeasurementsPanel
|
||||
descriptionData={descriptionData}
|
||||
measurementTableData={measurementTableData}
|
||||
actionButtons={
|
||||
<>
|
||||
<ButtonGroup onClick={() => alert('Export')}>
|
||||
<Button
|
||||
className="text-white border-primary-main bg-black text-base py-2 px-2"
|
||||
size="initial"
|
||||
color="inherit"
|
||||
>
|
||||
Export
|
||||
</Button>
|
||||
<IconButton
|
||||
className="bg-black border-primary-main px-2 text-white px-2"
|
||||
color="inherit"
|
||||
size="initial"
|
||||
>
|
||||
<Icon name="arrow-down" />
|
||||
</IconButton>
|
||||
</ButtonGroup>
|
||||
<Button
|
||||
className="text-white border border-primary-main bg-black text-base py-2 px-2 ml-2"
|
||||
variant="outlined"
|
||||
size="initial"
|
||||
color="inherit"
|
||||
onClick={() => alert('Create Report')}
|
||||
>
|
||||
Create Report
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</SidePanel>
|
||||
defaultComponentOpen="measurements"
|
||||
childComponents={{
|
||||
iconName: 'list-bullets',
|
||||
iconLabel: 'Measure',
|
||||
label: 'Measurements',
|
||||
name: 'measurements',
|
||||
content: (
|
||||
<MeasurementsPanel
|
||||
descriptionData={descriptionData}
|
||||
measurementTableData={measurementTableData}
|
||||
actionButtons={
|
||||
<React.Fragment>
|
||||
<ButtonGroup onClick={() => alert('Export')}>
|
||||
<Button
|
||||
className="text-white border-primary-main bg-black text-base py-2 px-2"
|
||||
size="initial"
|
||||
color="inherit"
|
||||
>
|
||||
Export
|
||||
</Button>
|
||||
<IconButton
|
||||
className="bg-black border-primary-main px-2 text-white px-2"
|
||||
color="inherit"
|
||||
size="initial"
|
||||
>
|
||||
<Icon name="arrow-down" />
|
||||
</IconButton>
|
||||
</ButtonGroup>
|
||||
<Button
|
||||
className="text-white border border-primary-main bg-black text-base py-2 px-2 ml-2"
|
||||
variant="outlined"
|
||||
size="initial"
|
||||
color="inherit"
|
||||
onClick={() => alert('Create Report')}
|
||||
>
|
||||
Create Report
|
||||
</Button>
|
||||
</React.Fragment>
|
||||
}
|
||||
/>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user