All files / src/components/LegendBox index.tsx

100% Statements 87/87
100% Branches 11/11
100% Functions 1/1
100% Lines 87/87

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134  1x           1x 1x                                       1x 41x 41x 41x 41x 41x 41x 41x 41x 41x 41x 41x 41x 41x 41x 41x 41x 41x 41x 41x   41x 41x 41x 41x 41x 41x 41x 41x 41x 41x   41x 5x 5x 5x 1x 5x   5x 5x     41x 27x 27x 27x 27x 27x 27x 27x 27x   27x 27x     41x 41x 41x 41x 41x 41x 41x 41x 41x   41x 41x     41x   41x 11x 11x 11x 11x   11x   11x   11x 11x 11x   11x 11x   30x 16x 16x 16x 16x 16x 16x   16x 16x     41x   41x  
import { ReactNode } from 'react';
import {
  legendBoxBorderVariants,
  legendBoxColorVariants,
  legendBoxSizeVariants,
} from '@/constants/legendBoxVariants';
 
import { combineClasses } from '@shared/utils';
import { Divider } from '../Divider';
 
interface LegendBoxProps {
  icon?: ReactNode;
  title?: string;
  result: string;
  extra?: ReactNode;
  onExtraClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
  colorVariant?: keyof typeof legendBoxColorVariants;
  sizeVariant?: keyof typeof legendBoxSizeVariants;
  borderVariant?: keyof typeof legendBoxBorderVariants;
  line?: boolean;
  containerClassName?: string;
  titleClassName?: string;
  resultClassName?: string;
  extraClassName?: string;
  enableHoverExtra?: boolean;
  id?: string;
}
 
export const LegendBox = ({
  icon,
  title,
  result,
  extra,
  onExtraClick,
  colorVariant = 'default',
  sizeVariant = 'sm',
  borderVariant = 'sm',
  line = false,
  containerClassName,
  titleClassName,
  resultClassName,
  extraClassName,
  enableHoverExtra = false,
  id,
}: LegendBoxProps) => {
  const colors = legendBoxColorVariants[colorVariant];
  const sizes = legendBoxSizeVariants[sizeVariant];
  const border = legendBoxBorderVariants[borderVariant];
 
  return (
    <div
      className={combineClasses(
        'flex items-center border gap-2 relative h-7.5 overflow-hidden',
        enableHoverExtra && 'group px-5 hover:px-2.75 cursor-pointer',
        colors.border,
        border,
        containerClassName,
      )}
      data-testid={id}
    >
      {icon && (
        <span
          className={combineClasses(
            enableHoverExtra &&
              'transition-opacity duration-200 hover:opacity-0',
          )}
        >
          {icon}
        </span>
      )}
 
      {title && (
        <span
          className={combineClasses(
            colors.title[borderVariant],
            sizes.title,
            'leading-none transition-all duration-200',
            enableHoverExtra && 'group-hover:pr-4',
            titleClassName,
          )}
        >
          {title}
        </span>
      )}
 
      {result && (
        <div
          data-testid="legend-box-result"
          className={combineClasses(
            colors.result,
            sizes.result,
            'inline-flex items-center transition-all duration-200 leading-none dark:text-background',
            resultClassName,
          )}
        >
          {result}
        </div>
      )}
 
      {line && <Divider orientation="vertical" />}
 
      {extra && onExtraClick ? (
        <button
          type="button"
          onClick={onExtraClick}
          className={combineClasses(
            // base
            'ml-auto flex items-center justify-center overflow-hidden transition-all duration-300 ease-in-out',
            // initial: hidden
            'max-w-0 opacity-0',
            // hover: reveal smoothly without breaking width
            'group-hover:max-w-[20px] group-hover:opacity-100 group-hover:pl-2 mb-0.5',
            extraClassName,
          )}
        >
          {extra}
        </button>
      ) : (
        extra && (
          <div
            className={combineClasses(
              colors.extra,
              'ml-auto text-4xs leading-none font-semibold dark:text-background',
              extraClassName,
            )}
          >
            {extra}
          </div>
        )
      )}
    </div>
  );
};