aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/molecules/forms/select-with-tooltip.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/molecules/forms/select-with-tooltip.tsx')
-rw-r--r--src/components/molecules/forms/select-with-tooltip.tsx73
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;