Local modifications to ClusterLabs/Anvil by Alteeve
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

83 lines
2.3 KiB

import {
ExpandLess as ExpandLessIcon,
ExpandMore as ExpandMoreIcon,
} from '@mui/icons-material';
import { Box, IconButton } from '@mui/material';
import { FC, useMemo, useState } from 'react';
import { GREY } from '../../lib/consts/DEFAULT_THEME';
import FlexBox from '../FlexBox';
import InnerPanel from './InnerPanel';
import InnerPanelBody from './InnerPanelBody';
import InnerPanelHeader from './InnerPanelHeader';
import Spinner from '../Spinner';
import { BodyText } from '../Text';
const HEADER_SPINNER_LENGTH = '1.2em';
const ExpandablePanel: FC<ExpandablePanelProps> = ({
children,
expandInitially: isExpandInitially = false,
header,
loading: isLoading = false,
panelProps,
showHeaderSpinner: isShowHeaderSpinner = false,
}) => {
const [isExpand, setIsExpand] = useState<boolean>(isExpandInitially);
const expandButtonIcon = useMemo(
() => (isExpand ? <ExpandLessIcon /> : <ExpandMoreIcon />),
[isExpand],
);
const contentHeight = useMemo(() => (isExpand ? 'auto' : '.2em'), [isExpand]);
const headerElement = useMemo(
() => (typeof header === 'string' ? <BodyText>{header}</BodyText> : header),
[header],
);
const headerSpinner = useMemo(
() =>
isShowHeaderSpinner && !isExpand && isLoading ? (
<Spinner
progressProps={{
style: {
height: HEADER_SPINNER_LENGTH,
width: HEADER_SPINNER_LENGTH,
},
}}
/>
) : undefined,
[isExpand, isLoading, isShowHeaderSpinner],
);
const content = useMemo(
() =>
isExpand && isLoading ? (
<Spinner sx={{ margin: '1em 0' }} />
) : (
<InnerPanelBody>{children}</InnerPanelBody>
),
[children, isExpand, isLoading],
);
return (
<InnerPanel {...panelProps}>
<InnerPanelHeader>
<FlexBox row>
{headerElement}
{headerSpinner}
</FlexBox>
<IconButton
onClick={() => {
setIsExpand((previous) => !previous);
}}
sx={{ color: GREY, padding: '.2em' }}
>
{expandButtonIcon}
</IconButton>
</InnerPanelHeader>
<Box sx={{ height: contentHeight, overflowY: 'hidden' }}>{content}</Box>
</InnerPanel>
);
};
export default ExpandablePanel;