From 12a03a9a72f7895d571dbaeeb245d92aa277a610 Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Fri, 6 Oct 2023 17:48:03 +0200 Subject: refactor(components): merge HeadingButton and Widget components The HeadingButton component was only used inside Widget component and it is not very useful on its own so I merge the two components in a new Collapsible component. --- .../molecules/collapsible/collapsible.tsx | 108 +++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 src/components/molecules/collapsible/collapsible.tsx (limited to 'src/components/molecules/collapsible/collapsible.tsx') diff --git a/src/components/molecules/collapsible/collapsible.tsx b/src/components/molecules/collapsible/collapsible.tsx new file mode 100644 index 0000000..e61ccba --- /dev/null +++ b/src/components/molecules/collapsible/collapsible.tsx @@ -0,0 +1,108 @@ +import { + useCallback, + type ForwardRefRenderFunction, + type HTMLAttributes, + type ReactNode, + forwardRef, + useId, + useState, +} from 'react'; +import { Button, Icon } from '../../atoms'; +import styles from './collapsible.module.scss'; + +export type CollapsibleProps = Omit< + HTMLAttributes, + 'children' +> & { + /** + * The collapsible body. + */ + children: ReactNode; + /** + * Should we disable padding around body? + * + * @default false + */ + disablePadding?: boolean; + /** + * Should the body be bordered? + * + * @default false + */ + hasBorders?: boolean; + /** + * The collapsible heading. + */ + heading: ReactNode; + /** + * Should the component be collapsed or expanded by default? + * + * @default false + */ + isCollapsed?: boolean; +}; + +const CollapsibleWithRef: ForwardRefRenderFunction< + HTMLDivElement, + CollapsibleProps +> = ( + { + children, + className = '', + disablePadding = false, + hasBorders = false, + heading, + isCollapsed = false, + ...props + }, + ref +) => { + const bodyId = useId(); + const [isExpanded, setIsExpanded] = useState(!isCollapsed); + const bodyClassNames = [ + styles.body, + hasBorders ? styles['body--has-borders'] : '', + styles[disablePadding ? 'body--no-padding' : 'body--has-padding'], + ]; + const wrapperClassNames = [ + styles.wrapper, + styles[isExpanded ? 'wrapper--expanded' : 'wrapper--collapsed'], + className, + ]; + + const handleState = useCallback(() => { + setIsExpanded((prevState) => !prevState); + }, []); + + return ( +
+ +
+ {children} +
+
+ ); +}; + +/** + * Collapsible component. + * + * Render a heading associated to a collapsible body. + */ +export const Collapsible = forwardRef(CollapsibleWithRef); -- cgit v1.2.3