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 | 1x 7x 7x 7x 2x 7x 20x 20x 20x 12x 12x 20x 8x 8x 20x 20x 1x 20x 4x 16x 16x 1x 1x | import React, { Fragment } from 'react';
import { type HsvaColor, hexToHsva, color as handleColor, type ColorResult } from '@uiw/color-convert';
import type * as CSS from 'csstype';
export type SwatchPresetColor = { color: string; title?: string } | string;
export interface SwatchRectRenderProps extends React.HTMLAttributes<HTMLDivElement> {
title: string;
color: string;
checked: boolean;
style: CSS.Properties<string | number>;
onClick: (evn: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
}
export interface SwatchProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'color'> {
prefixCls?: string;
color?: string;
colors?: SwatchPresetColor[];
rectProps?: React.HTMLAttributes<HTMLDivElement>;
rectRender?: (props: SwatchRectRenderProps) => JSX.Element | undefined;
onChange?: (hsva: HsvaColor, color: ColorResult, evn: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
addonAfter?: React.ReactNode;
addonBefore?: React.ReactNode;
}
const Swatch = React.forwardRef<HTMLDivElement, SwatchProps>((props, ref) => {
const {
prefixCls = 'w-color-swatch',
className,
color,
colors = [],
style,
rectProps = {},
onChange,
addonAfter,
addonBefore,
rectRender,
...other
} = props;
const rectStyle: CSS.Properties<string | number> = {
'--swatch-background-color': 'rgb(144, 19, 254)',
background: 'var(--swatch-background-color)',
height: 15,
width: 15,
marginRight: 5,
marginBottom: 5,
cursor: 'pointer',
position: 'relative',
outline: 'none',
borderRadius: 2,
...rectProps.style,
} as CSS.Properties<string | number>;
const handleClick = (hex: string, evn: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
onChange && onChange(hexToHsva(hex), handleColor(hexToHsva(hex)), evn);
};
return (
<div
ref={ref}
{...other}
className={[prefixCls, className || ''].filter(Boolean).join(' ')}
style={{
display: 'flex',
flexWrap: 'wrap',
position: 'relative',
...style,
}}
>
{addonBefore && React.isValidElement(addonBefore) && addonBefore}
{colors &&
Array.isArray(colors) &&
colors.map((item, idx) => {
let title = '';
let background = '';
if (typeof item === 'string') {
title = item;
background = item;
}
if (typeof item === 'object' && item.color) {
title = item.title || item.color;
background = item.color;
}
const checked = color && color.toLocaleLowerCase() === background.toLocaleLowerCase();
const render =
rectRender &&
rectRender({
title,
color: background,
checked: !!checked,
style: { ...rectStyle, background },
onClick: (evn) => handleClick(background, evn),
});
if (render) {
return <Fragment key={idx}>{render}</Fragment>;
}
const child =
rectProps.children && React.isValidElement(rectProps.children)
? React.cloneElement<any>(rectProps.children, {
color: background,
checked,
})
: null;
return (
<div
tabIndex={0}
key={idx}
title={title}
onClick={(evn) => handleClick(background, evn)}
{...rectProps}
children={child}
style={{ ...rectStyle, background }}
/>
);
})}
{addonAfter && React.isValidElement(addonAfter) && addonAfter}
</div>
);
});
Swatch.displayName = 'Swatch';
export default Swatch;
|