aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/molecules/forms/select-with-tooltip.tsx
blob: cf7b041be4a11d2ce3aaea3c0b6dde10d398512c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import { FC, 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 buttonModifier = isTooltipOpened ? styles['btn--activated'] : '';
  const tooltipModifier = isTooltipOpened
    ? styles['tooltip--visible']
    : styles['tooltip--hidden'];

  return (
    <div className={styles.wrapper}>
      <LabelledSelect
        labelPosition="left"
        id={id}
        labelClassName={styles.label}
        {...props}
      />
      <HelpButton
        onClick={() => setIsTooltipOpened(!isTooltipOpened)}
        className={`${styles.btn} ${buttonModifier}`}
      />
      <Tooltip
        title={title}
        content={content}
        icon="?"
        className={`${styles.tooltip} ${tooltipModifier} ${tooltipClassName}`}
      />
    </div>
  );
};

export default SelectWithTooltip;
lass="nc">.convert-px(150); position: relative; } .info { display: grid; grid-template-columns: repeat(auto-fill, minmax(20ch, 1fr)); align-items: start; justify-content: left; column-gap: var(--spacing-md); margin: var(--spacing-md) 0 0; } .inline-data { display: inline-block; margin-top: fun.convert-px(3); &:not(:last-of-type) { margin-right: var(--spacing-xs); } } .techno { padding: 0 var(--spacing-2xs); border: fun.convert-px(1) solid var(--color-primary-darker); } .repo { display: block; width: 3em; height: 3em; background: none; box-shadow: fun.convert-px(1) fun.convert-px(1) fun.convert-px(1) var(--color-shadow), fun.convert-px(1) fun.convert-px(2) fun.convert-px(2) fun.convert-px(-1) var(--color-shadow), fun.convert-px(3) fun.convert-px(4) fun.convert-px(4) fun.convert-px(-3) var(--color-shadow), 0 0 0 0 var(--color-shadow); transition: all 0.3s linear 0s; &:hover, &:focus { box-shadow: fun.convert-px(1) fun.convert-px(1) fun.convert-px(1) var(--color-shadow), fun.convert-px(1) fun.convert-px(1) fun.convert-px(2) fun.convert-px(-1) var(--color-shadow-light), fun.convert-px(3) fun.convert-px(3) fun.convert-px(4) fun.convert-px(-4) var(--color-shadow-light), fun.convert-px(6) fun.convert-px(6) fun.convert-px(10) fun.convert-px(-3) var(--color-shadow); transform: scale(1.15); } &:focus { outline: var(--color-primary) dashed fun.convert-px(2); } &:active { box-shadow: 0 0 0 0 var(--color-shadow); outline: none; transform: scale(0.9); } }