parent
a7b80b2e36
commit
767288aa96
3 changed files with 89 additions and 1 deletions
@ -0,0 +1,61 @@ |
||||
import { |
||||
ExpandLess as ExpandLessIcon, |
||||
ExpandMore as ExpandMoreIcon, |
||||
} from '@mui/icons-material'; |
||||
import { Box, IconButton } from '@mui/material'; |
||||
import { FC, ReactNode, useMemo, useState } from 'react'; |
||||
|
||||
import { GREY } from '../../lib/consts/DEFAULT_THEME'; |
||||
|
||||
import InnerPanel from './InnerPanel'; |
||||
import InnerPanelBody from './InnerPanelBody'; |
||||
import InnerPanelHeader from './InnerPanelHeader'; |
||||
|
||||
type ExpandablePanelOptionalProps = { |
||||
isExpandInitially?: boolean; |
||||
}; |
||||
|
||||
type ExpandablePanelProps = ExpandablePanelOptionalProps & { |
||||
header: ReactNode; |
||||
}; |
||||
|
||||
const EXPANDABLE_PANEL_DEFAULT_PROPS: Required<ExpandablePanelOptionalProps> = { |
||||
isExpandInitially: false, |
||||
}; |
||||
|
||||
const ExpandablePanel: FC<ExpandablePanelProps> = ({ |
||||
children, |
||||
header, |
||||
isExpandInitially = EXPANDABLE_PANEL_DEFAULT_PROPS.isExpandInitially, |
||||
}) => { |
||||
const [isExpand, setIsExpand] = useState<boolean>(isExpandInitially); |
||||
|
||||
const expandButtonIcon = useMemo( |
||||
() => (isExpand ? <ExpandLessIcon /> : <ExpandMoreIcon />), |
||||
[isExpand], |
||||
); |
||||
const contentHeight = useMemo(() => (isExpand ? 'auto' : '.2em'), [isExpand]); |
||||
|
||||
return ( |
||||
<InnerPanel> |
||||
<InnerPanelHeader> |
||||
{header} |
||||
<IconButton |
||||
onClick={() => { |
||||
setIsExpand((previous) => !previous); |
||||
}} |
||||
sx={{ color: GREY, padding: '.2em' }} |
||||
> |
||||
{expandButtonIcon} |
||||
</IconButton> |
||||
</InnerPanelHeader> |
||||
<Box sx={{ height: contentHeight, overflowY: 'hidden' }}> |
||||
<InnerPanelBody>{children}</InnerPanelBody> |
||||
</Box> |
||||
</InnerPanel> |
||||
); |
||||
}; |
||||
|
||||
ExpandablePanel.defaultProps = EXPANDABLE_PANEL_DEFAULT_PROPS; |
||||
|
||||
export default ExpandablePanel; |
@ -0,0 +1,18 @@ |
||||
import { Box, BoxProps } from '@mui/material'; |
||||
import { FC } from 'react'; |
||||
|
||||
const InnerPanelBody: FC<BoxProps> = ({ sx, ...innerPanelBodyRestProps }) => ( |
||||
<Box |
||||
{...{ |
||||
...innerPanelBodyRestProps, |
||||
sx: { |
||||
paddingLeft: '.7em', |
||||
paddingRight: '.7em', |
||||
paddingTop: '.3em', |
||||
...sx, |
||||
}, |
||||
}} |
||||
/> |
||||
); |
||||
|
||||
export default InnerPanelBody; |
@ -1,6 +1,15 @@ |
||||
import ExpandablePanel from './ExpandablePanel'; |
||||
import InnerPanel from './InnerPanel'; |
||||
import InnerPanelBody from './InnerPanelBody'; |
||||
import InnerPanelHeader from './InnerPanelHeader'; |
||||
import Panel from './Panel'; |
||||
import PanelHeader from './PanelHeader'; |
||||
|
||||
export { InnerPanel, InnerPanelHeader, Panel, PanelHeader }; |
||||
export { |
||||
ExpandablePanel, |
||||
InnerPanel, |
||||
InnerPanelBody, |
||||
InnerPanelHeader, |
||||
Panel, |
||||
PanelHeader, |
||||
}; |
||||
|
Loading…
Reference in new issue