nitro-react/src/common/card/accordion/NitroCardAccordionSetView.tsx

85 lines
2.4 KiB
TypeScript

import { FC, useCallback, useEffect, useMemo, useState } from 'react';
import { FaCaretDown, FaCaretUp } from 'react-icons/fa';
import { Column, ColumnProps, Flex, Text } from '../..';
import { useNitroCardAccordionContext } from './NitroCardAccordionContext';
export interface NitroCardAccordionSetViewProps extends ColumnProps
{
headerText: string;
isExpanded?: boolean;
}
export const NitroCardAccordionSetView: FC<NitroCardAccordionSetViewProps> = props =>
{
const { headerText = '', isExpanded = false, gap = 0, classNames = [], children = null, ...rest } = props;
const [ isOpen, setIsOpen ] = useState(false);
const { setClosers = null, closeAll = null } = useNitroCardAccordionContext();
const onClick = () =>
{
closeAll();
setIsOpen(prevValue => !prevValue);
}
const onClose = useCallback(() => setIsOpen(false), []);
const getClassNames = useMemo(() =>
{
const newClassNames = [ 'nitro-card-accordion-set' ];
if(isOpen) newClassNames.push('active');
if(classNames && classNames.length) newClassNames.push(...classNames);
return newClassNames;
}, [ isOpen, classNames ]);
useEffect(() =>
{
setIsOpen(isExpanded);
}, [ isExpanded ]);
useEffect(() =>
{
const closeFunction = onClose;
setClosers(prevValue =>
{
const newClosers = [ ...prevValue ];
newClosers.push(closeFunction);
return newClosers;
});
return () =>
{
setClosers(prevValue =>
{
const newClosers = [ ...prevValue ];
const index = newClosers.indexOf(closeFunction);
if(index >= 0) newClosers.splice(index, 1);
return newClosers;
});
}
}, [ onClose, setClosers ]);
return (
<Column classNames={ getClassNames } gap={ gap } { ...rest }>
<Flex pointer justifyContent="between" className="nitro-card-accordion-set-header px-2 py-1" onClick={ onClick }>
<Text>{ headerText }</Text>
{ isOpen && <FaCaretUp className="fa-icon" /> }
{ !isOpen && <FaCaretDown className="fa-icon" /> }
</Flex>
{ isOpen &&
<Column fullHeight overflow="auto" gap={ 0 } className="nitro-card-accordion-set-content">
{ children }
</Column> }
</Column>
);
}