diff --git a/packages/color-picker/src/components/Previewer/index.tsx b/packages/color-picker/src/components/Previewer/index.tsx new file mode 100644 index 00000000..ca3998e0 --- /dev/null +++ b/packages/color-picker/src/components/Previewer/index.tsx @@ -0,0 +1,42 @@ +import type { FC } from 'react'; +import React, { memo } from 'react'; +import reactCSS from 'reactcss'; +import isEqual from 'lodash/isEqual'; + +import { Checkboard } from '../common'; + +import { useStore } from '../../store'; +import type { ColorPickerProps } from '../../types'; + +export const Previewer: FC = memo(() => { + const rgba = useStore((s) => s.colorModel.rgba(), isEqual); + + const styles: any = reactCSS({ + default: { + color: { + width: '24px', + height: '24px', + position: 'relative', + marginTop: '4px', + marginLeft: '4px', + borderRadius: 12, + overflow: 'hidden', + }, + activeColor: { + borderRadius: 12, + absolute: '0px 0px 0px 0px', + background: `rgba(${rgba.join(',')})`, + boxShadow: 'inset 0 0 0 1px rgba(0,0,0,.15), inset 0 0 4px rgba(0,0,0,.25)', + }, + }, + }); + + return ( +
+ +
+
+ ); +}); + +export default Previewer; diff --git a/packages/color-picker/src/components/Saturation/index.tsx b/packages/color-picker/src/components/Saturation/index.tsx index 6f285a78..e0336b76 100644 --- a/packages/color-picker/src/components/Saturation/index.tsx +++ b/packages/color-picker/src/components/Saturation/index.tsx @@ -1,12 +1,12 @@ import type { FC } from 'react'; -import React, { useEffect, useMemo, useRef } from 'react'; +import React, { memo, useEffect, useMemo, useRef } from 'react'; import reactCSS from 'reactcss'; import { fromEvent, Subject } from 'rxjs'; import { concatMap, map, takeUntil, throttleTime } from 'rxjs/operators'; import { useStore } from '../../store'; -export const Saturation: FC = () => { +export const Saturation: FC = memo(() => { const hue = useStore((s) => s.hue); const saturation = useStore((s) => s.saturation); const brightness = useStore((s) => s.brightness); @@ -127,6 +127,6 @@ export const Saturation: FC = () => {
); -}; +}); export default Saturation; diff --git a/packages/color-picker/src/components/SketchFields/index.tsx b/packages/color-picker/src/components/SketchFields/index.tsx index 9b3842f6..f40e5875 100644 --- a/packages/color-picker/src/components/SketchFields/index.tsx +++ b/packages/color-picker/src/components/SketchFields/index.tsx @@ -1,12 +1,12 @@ import type { FC } from 'react'; -import React, { memo } from 'react'; +import React, { memo, useMemo } from 'react'; import isEqual from 'lodash/isEqual'; import { Flexbox } from '@arvinxu/layout-kit'; import cls from 'classnames'; import copy from 'copy-to-clipboard'; import shallow from 'zustand/shallow'; -import type { ColorMode, ColorObj, ColorPickerStore } from '../../store'; +import type { ColorMode, ColorPickerStore, SpaceColor } from '../../store'; import { colorSpaceSelector, useStore } from '../../store'; import { isValidHex } from '../../helpers/color'; import DraggableLabel from '../DraggableLabel'; @@ -27,7 +27,7 @@ export const SketchFields: FC = memo(() => { const hex = useStore((s) => s.colorModel.hex('rgb')); const alpha = useStore((s) => Math.round(s.colorModel.alpha() * 100)); - const modeValue = useStore(colorSpaceSelector, isEqual) as ColorObj; + const modeValue = useStore(colorSpaceSelector, isEqual) as SpaceColor; const { updateAlpha, updateByHex, updateColorMode, updateByColorSpace } = useStore( selector, @@ -36,6 +36,38 @@ export const SketchFields: FC = memo(() => { const prefixCls = 'avx-color-fields'; + const inputGroup = useMemo( + () => + mode.split('').map((dim) => { + return ( +
+ { + updateByColorSpace(dim, value); + }} + /> +
+ ); + }), + [mode, modeValue, updateByColorSpace], + ); + + const labelGroup = useMemo( + () => + mode.split('').map((dim, index) => ( + { + updateByColorSpace(dim, value); + }} + /> + )), + [mode, modeValue, updateByColorSpace], + ); + return ( @@ -50,19 +82,7 @@ export const SketchFields: FC = memo(() => { style={{ width: 56, fontFamily: 'monospace' }} /> - {mode.split('').map((dim) => { - return ( -
- { - updateByColorSpace(dim, value); - }} - /> -
- ); - })} - + {inputGroup}
@@ -94,20 +114,11 @@ export const SketchFields: FC = memo(() => { value={mode} > - + {/**/} - {mode.split('').map((dim, index) => ( - { - updateByColorSpace(dim, value); - }} - /> - ))} + {labelGroup}
= memo(({ className }) => { - const rgba = useStore((s) => s.colorModel.rgba(), isEqual); - const styles: any = reactCSS({ default: { picker: { @@ -41,20 +37,7 @@ export const Sketch: FC = memo(({ className }) => { padding: '4px 0', flex: '1', }, - color: { - width: '24px', - height: '24px', - position: 'relative', - marginTop: '4px', - marginLeft: '4px', - borderRadius: '50%', - overflow: 'hidden', - }, - activeColor: { - absolute: '0px 0px 0px 0px', - background: `rgba(${rgba.join(',')})`, - boxShadow: 'inset 0 0 0 1px rgba(0,0,0,.15), inset 0 0 4px rgba(0,0,0,.25)', - }, + hue: { position: 'relative', height: '10px', @@ -84,10 +67,7 @@ export const Sketch: FC = memo(({ className }) => { -
- -
-
+
diff --git a/packages/color-picker/src/store.ts b/packages/color-picker/src/store.ts index b1dc1cfe..5f6854e1 100644 --- a/packages/color-picker/src/store.ts +++ b/packages/color-picker/src/store.ts @@ -9,16 +9,22 @@ import type { HSLColor, HSVColor, RGBColor } from './types'; export type ColorMode = 'rgb' | 'hsl' | 'hsv'; +type OnColorChange = ({ hex, color }: { hex: string; color: Color }) => void; interface ColorPickerState { - colorMode: ColorMode; + // 外部预设值 presetColors: string[]; - onSwatchHover?: any; - onChange?: ({ hex, color }: { hex: string; color: Color }) => void; + // 回调方法 + onSwatchHover?: OnColorChange; + onChange?: OnColorChange; + colorModel: Color; + colorMode: ColorMode; + hue: number; saturation: number; brightness: number; } + interface ColorPickerAction { internalUpdateColor: (color: Color) => void; updateAlpha: (a: number) => void; @@ -183,10 +189,10 @@ const createStore = () => { }, updateByRgb: (rgb) => { - const { r, g, b, a } = rgb; - const { internalUpdateColor } = get(); + const { r, g, b } = rgb; + const { internalUpdateColor, colorModel } = get(); - internalUpdateColor(chroma([r, g, b, a], 'rgb')); + internalUpdateColor(chroma([r, g, b, colorModel.alpha()], 'rgb')); }, }), { name: 'ColorPicker' }, @@ -208,28 +214,23 @@ const { Provider, useStore } = createContext(); export { Provider, useStore, createStore }; -export interface ColorObj { - rgb: RGBColor; - hsl: HSLColor; - hsv: HSVColor; - hex: string; -} +// ============ Selector =========== // export type SpaceColor = RGBColor | HSLColor | HSVColor; export const colorSpaceSelector = (s: ColorPickerState): SpaceColor => { - const [r, g, b, a] = s.colorModel.rgba(); + const [r, g, b] = s.colorModel.rgba(); const hsl = s.colorModel.hsl(); switch (s.colorMode) { case 'rgb': { - return { r, g, b, a }; + return { r, g, b }; } case 'hsv': { - return { h: s.hue, s: s.saturation, v: s.brightness, a }; + return { h: s.hue, s: s.saturation, v: s.brightness }; } case 'hsl': { - return { h: s.hue, s: hsl[1] * 100, l: hsl[2] * 100, a }; + return { h: s.hue, s: hsl[1] * 100, l: hsl[2] * 100 }; } } }; diff --git a/packages/color-picker/src/types.ts b/packages/color-picker/src/types.ts index d516ee43..48c6069c 100644 --- a/packages/color-picker/src/types.ts +++ b/packages/color-picker/src/types.ts @@ -2,21 +2,18 @@ import type { CSSProperties } from 'react'; import type React from 'react'; export interface HSLColor { - a?: number | undefined; h: number; l: number; s: number; } export interface HSVColor { - a?: number | undefined; h: number; s: number; v: number; } export interface RGBColor { - a?: number | undefined; b: number; g: number; r: number;