All files / color-slider/src index.tsx

100% Statements 12/12
100% Branches 14/14
100% Functions 4/4
100% Lines 12/12

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                                      1x 5x 5x 5x 3x   5x               25x 25x 25x 25x                   3x                                       1x      
import React from 'react';
import {
  ColorResult,
  color as handleColor,
  hexToHsva,
  hsvaToHsla,
  hsvaToHslString,
  validHex,
  HsvaColor,
  hslStringToHsva,
} from '@uiw/color-convert';
 
export interface SliderProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'color'> {
  prefixCls?: string;
  color?: string | HsvaColor;
  lightness?: number[];
  onChange?: (color: ColorResult, evn: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
}
 
const Slider = React.forwardRef<HTMLDivElement, SliderProps>((props, ref) => {
  const { prefixCls = 'w-color-slider', className, style, onChange, color, lightness = [80, 65, 50, 35, 20], ...other } = props;
  const hsva = (typeof color === 'string' && validHex(color) ? hexToHsva(color) : color || {}) as HsvaColor;
  const handleClick = (hslStr: string, evn: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
    onChange && onChange(handleColor(hslStringToHsva(hslStr)), evn);
  };
  return (
    <div
      ref={ref}
      style={{ display: 'flex', ...style }}
      className={[prefixCls, className || ''].filter(Boolean).join(' ')}
      {...other}
    >
      {lightness.map((num, idx) => {
        const hsl = hsvaToHsla(hsva);
        const hslStr = `hsl(${hsl.h}, 50%, ${num}%)`;
        const checked = hslStr === hsvaToHslString(hsva);
        return (
          <div
            key={idx}
            style={{
              paddingLeft: 1,
              width: `${100 / lightness.length}%`,
              boxSizing: 'border-box',
            }}
          >
            <div
              onClick={(evn) => handleClick(hslStr, evn)}
              style={{
                backgroundColor: hslStr,
                height: 12,
                cursor: 'pointer',
                ...(checked
                  ? {
                      borderRadius: 2,
                      transform: 'scale(1, 1.5)',
                    }
                  : {}),
              }}
            />
          </div>
        );
      })}
    </div>
  );
});
 
Slider.displayName = 'Slider';
 
export default Slider;