diff options
| author | Armand Philippot <git@armandphilippot.com> | 2022-05-24 19:35:12 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-05-24 19:35:12 +0200 |
| commit | c85ab5ad43ccf52881ee224672c41ec30021cf48 (patch) | |
| tree | 8058808d9bfca19383f120c46b34d99ff2f89f63 /src/components/molecules/forms/select-with-tooltip.tsx | |
| parent | 52404177c07a2aab7fc894362fb3060dff2431a0 (diff) | |
| parent | 11b9de44a4b2f305a6a484187805e429b2767118 (diff) | |
refactor: use storybook and atomic design (#16)
BREAKING CHANGE: rewrite most of the Typescript types, so the content format (the meta in particular) needs to be updated.
Diffstat (limited to 'src/components/molecules/forms/select-with-tooltip.tsx')
| -rw-r--r-- | src/components/molecules/forms/select-with-tooltip.tsx | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/src/components/molecules/forms/select-with-tooltip.tsx b/src/components/molecules/forms/select-with-tooltip.tsx new file mode 100644 index 0000000..29e2563 --- /dev/null +++ b/src/components/molecules/forms/select-with-tooltip.tsx @@ -0,0 +1,73 @@ +import useClickOutside from '@utils/hooks/use-click-outside'; +import { FC, useRef, useState } from 'react'; +import HelpButton from '../buttons/help-button'; +import Tooltip, { type TooltipProps } from '../modals/tooltip'; +import LabelledSelect, { type LabelledSelectProps } from './labelled-select'; +import styles from './select-with-tooltip.module.scss'; + +export type SelectWithTooltipProps = Omit< + LabelledSelectProps, + 'labelPosition' +> & + Pick<TooltipProps, 'title' | 'content'> & { + /** + * Set additional classnames to the tooltip wrapper. + */ + tooltipClassName?: TooltipProps['className']; + }; + +/** + * SelectWithTooltip component + * + * Render a select with a button to display a tooltip about options. + */ +const SelectWithTooltip: FC<SelectWithTooltipProps> = ({ + title, + content, + id, + tooltipClassName = '', + ...props +}) => { + const [isTooltipOpened, setIsTooltipOpened] = useState<boolean>(false); + const buttonRef = useRef<HTMLButtonElement>(null); + const tooltipRef = useRef<HTMLDivElement>(null); + const buttonModifier = isTooltipOpened ? styles['btn--activated'] : ''; + const tooltipModifier = isTooltipOpened + ? styles['tooltip--visible'] + : styles['tooltip--hidden']; + + const closeTooltip = (target: EventTarget) => { + if (buttonRef.current && !buttonRef.current.contains(target as Node)) + setIsTooltipOpened(false); + }; + + useClickOutside( + tooltipRef, + (target) => isTooltipOpened && closeTooltip(target) + ); + + return ( + <div className={styles.wrapper}> + <LabelledSelect + labelPosition="left" + id={id} + labelClassName={styles.label} + {...props} + /> + <HelpButton + className={`${styles.btn} ${buttonModifier}`} + onClick={() => setIsTooltipOpened(!isTooltipOpened)} + ref={buttonRef} + /> + <Tooltip + title={title} + content={content} + icon="?" + className={`${styles.tooltip} ${tooltipModifier} ${tooltipClassName}`} + ref={tooltipRef} + /> + </div> + ); +}; + +export default SelectWithTooltip; |
