All files / color-material/src index.tsx

100% Statements 18/18
100% Branches 20/20
100% Functions 6/6
100% Lines 18/18

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                      1x                     1x 10x 10x 10x 10x 5x   10x 7x 5x       10x                   10x         5x   2x 2x 2x                                                                               5x           1x      
import React, { CSSProperties } from 'react';
import { HsvaColor, ColorResult, color as handleColor, validHex, hexToHsva, hsvaToHex } from '@uiw/color-convert';
import EditableInput from '@uiw/react-color-editable-input';
import RGBA from '@uiw/react-color-editable-input-rgba';
 
export interface MaterialProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'color'> {
  prefixCls?: string;
  color?: string | HsvaColor;
  onChange?: (color: ColorResult) => void;
}
 
const styleRBG = {
  boxShadow: 'initial',
  borderWidth: '0 0 1px 0',
  borderBottomColor: 'var(--material-border-bottom-color)',
  borderBottomStyle: 'solid',
  height: 30,
  outline: 0,
  fontSize: 15,
  padding: 0,
} as CSSProperties;
 
const Material = React.forwardRef<HTMLDivElement, MaterialProps>((props, ref) => {
  const { prefixCls = 'w-color-material', className, style, color, onChange, ...other } = props;
  const hsva = (typeof color === 'string' && validHex(color) ? hexToHsva(color) : color) as HsvaColor;
  const hex = color ? hsvaToHex(hsva).replace(/^#/, '') : '';
  const handleChange = (hsv: HsvaColor) => {
    onChange && onChange(handleColor(hsv));
  };
  const handleHex = (value: string | number, evn: React.ChangeEvent<HTMLInputElement>) => {
    if (typeof value === 'string' && validHex(value) && /(3|6)/.test(String(value.length))) {
      onChange && onChange(handleColor(hexToHsva(value)));
    }
  };
 
  const styleWrapper = {
    '--material-border-bottom-color': '#eee',
    '--material-background-color': '#fff',
    padding: 16,
    width: 98,
    fontFamily: 'Roboto',
    backgroundColor: 'var(--material-background-color)',
    ...style,
  } as CSSProperties;
 
  return (
    <div ref={ref} className={[prefixCls, className || ''].filter(Boolean).join(' ')} style={styleWrapper} {...other}>
      <EditableInput
        label="Hex"
        value={hex.toLocaleUpperCase()}
        onChange={(evn, val) => handleHex(val, evn)}
        onBlur={(evn) => {
          const value = evn.target.value;
          evn.target.value = value.slice(0, 6);
          handleHex(value.slice(0, 6), evn);
        }}
        inputStyle={{
          outline: 0,
          border: 0,
          height: 30,
          fontSize: 15,
          padding: 0,
          boxShadow: 'initial',
          borderWidth: '0 0 2px 0',
          borderBottomColor: hex ? `#${hex}` : 'var(--material-border-bottom-color)',
          borderBottomStyle: 'solid',
          background: 'transparent',
        }}
        style={{ flexDirection: 'column-reverse', alignItems: 'flex-start' }}
      />
 
      <RGBA
        hsva={hsva}
        placement="top"
        style={{ marginTop: 11 }}
        rProps={{
          style: {
            alignItems: 'flex-start',
          },
          inputStyle: { ...styleRBG },
        }}
        gProps={{
          style: {
            alignItems: 'flex-start',
          },
          inputStyle: { ...styleRBG },
        }}
        bProps={{
          style: {
            alignItems: 'flex-start',
          },
          inputStyle: { ...styleRBG },
        }}
        aProps={false}
        onChange={(result) => handleChange(result.hsva)}
      />
    </div>
  );
});
 
Material.displayName = 'Material';
 
export default Material;