All files / color-colorful/src index.tsx

100% Statements 16/16
94.11% Branches 16/17
100% Functions 9/9
100% Lines 15/15

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                                          1x 27x                             27x                           1x 9x 9x 9x 9x                                 9x   1x             1x 9x               9x 2x             1x      
import React, { CSSProperties } from 'react';
import {
  validHex,
  color as handleColor,
  hexToHsva,
  HsvaColor,
  ColorResult,
  hsvaToHex,
  hsvaToRgbaString,
} from '@uiw/color-convert';
import Alpha, { BACKGROUND_IMG } from '@uiw/react-color-alpha';
import Saturation from '@uiw/react-color-saturation';
import Hue from '@uiw/react-color-hue';
 
export interface ColorfulProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'color'> {
  prefixCls?: string;
  onChange?: (color: ColorResult) => void;
  color?: string | HsvaColor;
  disableAlpha?: boolean;
}
 
const Pointer = ({ style, color, ...props }: React.HTMLAttributes<HTMLDivElement> & { color: string }) => {
  const stylePointer = {
    '--colorful-pointer-background-color': '#fff',
    '--colorful-pointer-border': '2px solid #fff',
    height: 28,
    width: 28,
    position: 'absolute',
    transform: 'translate(-14px, -4px)',
    boxShadow: '0 2px 4px rgb(0 0 0 / 20%)',
    borderRadius: '50%',
    background: `url(${BACKGROUND_IMG})`,
    backgroundColor: 'var(--colorful-pointer-background-color)',
    border: 'var(--colorful-pointer-border)',
    zIndex: 1,
    ...style,
  } as CSSProperties;
  return (
    <div {...props} style={stylePointer}>
      <div
        style={{
          backgroundColor: color,
          borderRadius: '50%',
          height: ' 100%',
          width: '100%',
        }}
      />
    </div>
  );
};
 
const Colorful = React.forwardRef<HTMLDivElement, ColorfulProps>((props, ref) => {
  const { prefixCls = 'w-color-colorful', className, onChange, color, style, disableAlpha, ...other } = props;
  const hsva = (typeof color === 'string' && validHex(color) ? hexToHsva(color) : color || {}) as HsvaColor;
  const handleChange = (value: HsvaColor) => onChange && onChange(handleColor(value));
  return (
    <div
      ref={ref}
      style={{
        width: 200,
        position: 'relative',
        ...style,
      }}
      {...other}
      className={`${prefixCls} ${className || ''}`}
    >
      <Saturation
        hsva={hsva}
        className={prefixCls}
        radius="8px 8px 0 0"
        style={{ width: 'auto', height: 150, minWidth: 120, borderBottom: '12px solid #000' }}
        pointer={({ left, top, color }) => (
          <Pointer style={{ left, top, transform: 'translate(-16px, -16px)' }} color={hsvaToHex(hsva)} />
        )}
        onChange={(newColor) => handleChange({ ...hsva, ...newColor })}
      />
      <Hue
        hue={hsva.h}
        height={24}
        radius={disableAlpha ? '0 0 8px 8px' : 0}
        className={prefixCls}
        onChange={(newHue) => handleChange({ ...hsva, ...newHue })}
        pointer={({ left }) => <Pointer style={{ left }} color={`hsl(${hsva.h || 0}deg 100% 50%)`} />}
      />
      {!disableAlpha && (
        <Alpha
          hsva={hsva}
          height={24}
          className={prefixCls}
          radius="0 0 8px 8px"
          pointer={({ left }) => <Pointer style={{ left }} color={hsvaToRgbaString(hsva)} />}
          onChange={(newAlpha) => handleChange({ ...hsva, ...newAlpha })}
        />
      )}
    </div>
  );
});
 
Colorful.displayName = 'Colorful';
 
export default Colorful;