From 6be20422494e3806fba3d1c5ad5c3e98bd6e67e5 Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Wed, 1 Jun 2022 19:34:43 +0200 Subject: chore: replace the Ackee select by a toggle component --- src/components/molecules/forms/fieldset.tsx | 118 ++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 src/components/molecules/forms/fieldset.tsx (limited to 'src/components/molecules/forms/fieldset.tsx') diff --git a/src/components/molecules/forms/fieldset.tsx b/src/components/molecules/forms/fieldset.tsx new file mode 100644 index 0000000..9f46247 --- /dev/null +++ b/src/components/molecules/forms/fieldset.tsx @@ -0,0 +1,118 @@ +import useClickOutside from '@utils/hooks/use-click-outside'; +import { + cloneElement, + FC, + ReactComponentElement, + ReactNode, + useRef, + useState, +} from 'react'; +import HelpButton from '../buttons/help-button'; +import Tooltip from '../modals/tooltip'; +import styles from './fieldset.module.scss'; + +export type FieldsetProps = { + /** + * Set additional classnames to the body wrapper. + */ + bodyClassName?: string; + /** + * The fieldset body. + */ + children: ReactNode | ReactNode[]; + /** + * Set additional classnames to the fieldset wrapper. + */ + className?: string; + /** + * The fieldset legend. + */ + legend: string; + /** + * Set additional classnames to the legend. + */ + legendClassName?: string; + /** + * The legend position. Default: stacked. + */ + legendPosition?: 'inline' | 'stacked'; + /** + * An accessible role. Default: group. + */ + role?: 'group' | 'radiogroup' | 'presentation' | 'none'; + /** + * An optional tooltip component. + */ + Tooltip?: ReactComponentElement; +}; + +/** + * Fieldset component + * + * Render a fieldset with a legend. + */ +const Fieldset: FC = ({ + bodyClassName = '', + children, + className = '', + legend, + legendClassName = '', + legendPosition = 'stacked', + Tooltip: TooltipComponent, + ...props +}) => { + const [isTooltipOpened, setIsTooltipOpened] = useState(false); + const buttonRef = useRef(null); + const tooltipRef = useRef(null); + const wrapperModifier = `wrapper--${legendPosition}`; + const buttonModifier = isTooltipOpened ? styles['btn--activated'] : ''; + const legendModifier = + TooltipComponent === undefined ? '' : 'legend--has-tooltip'; + const tooltipModifier = isTooltipOpened + ? 'tooltip--visible' + : 'tooltip--hidden'; + + /** + * Close the tooltip if the event target is outside. + * + * @param {EventTarget} target - The event target. + */ + const closeTooltip = (target: EventTarget) => { + if (buttonRef.current && !buttonRef.current.contains(target as Node)) + setIsTooltipOpened(false); + }; + + useClickOutside( + tooltipRef, + (target) => isTooltipOpened && closeTooltip(target) + ); + + return ( +
+ + {legend} + + {TooltipComponent && ( + <> + setIsTooltipOpened(!isTooltipOpened)} + ref={buttonRef} + /> + {cloneElement(TooltipComponent, { + cloneClassName: `${styles.tooltip} ${styles[tooltipModifier]}`, + ref: tooltipRef, + })} + + )} +
{children}
+
+ ); +}; + +export default Fieldset; -- cgit v1.2.3