UNPKG

@wordpress/components

Version:
157 lines (156 loc) 5.01 kB
// packages/components/src/color-picker/component.tsx import { colord, extend, getFormat } from "colord"; import namesPlugin from "colord/plugins/names"; import { useCallback, useEffect, useRef, useState, useMemo } from "@wordpress/element"; import { useDebounce } from "@wordpress/compose"; import { __ } from "@wordpress/i18n"; import { useContextSystem, contextConnect } from "../context/index.mjs"; import { ColorfulWrapper, SelectControl, AuxiliaryColorArtefactWrapper, AuxiliaryColorArtefactHStackHeader, ColorInputWrapper } from "./styles.mjs"; import { ColorCopyButton } from "./color-copy-button.mjs"; import { ColorInput } from "./color-input.mjs"; import { Picker } from "./picker.mjs"; import { useControlledValue } from "../utils/hooks/index.mjs"; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; extend([namesPlugin]); function mergeHSLA(nextHSLA, prevHSLA) { if (nextHSLA.s === 0) { if (nextHSLA.l === 0 || nextHSLA.l === 100) { return { ...nextHSLA, h: prevHSLA.h, s: prevHSLA.s }; } return { ...nextHSLA, h: prevHSLA.h }; } return nextHSLA; } var options = [{ label: "RGB", value: "rgb" }, { label: "HSL", value: "hsl" }, { label: "Hex", value: "hex" }]; var UnconnectedColorPicker = (props, forwardedRef) => { const { enableAlpha = false, color: colorProp, onChange, defaultValue = "#fff", copyFormat, ...divProps } = useContextSystem(props, "ColorPicker"); const [color, setColor] = useControlledValue({ onChange, value: colorProp, defaultValue }); const safeColordColor = useMemo(() => { return colord(color || ""); }, [color]); const debouncedSetColor = useDebounce(setColor); const [internalHSLA, setInternalHSLA] = useState(() => ({ ...safeColordColor.toHsl() })); const lastProducedHexRef = useRef(safeColordColor.toHex()); useEffect(() => { const incomingHex = safeColordColor.toHex(); if (incomingHex === lastProducedHexRef.current) { return; } lastProducedHexRef.current = incomingHex; const externalHSLA = safeColordColor.toHsl(); setInternalHSLA((prev) => mergeHSLA(externalHSLA, prev)); }, [safeColordColor]); const handleHSLAChange = useCallback((nextHSLA) => { setInternalHSLA(nextHSLA); const previousHex = lastProducedHexRef.current; const nextHex = colord(nextHSLA).toHex(); if (nextHex !== previousHex) { lastProducedHexRef.current = nextHex; setColor(nextHex); } }, [setColor]); const handleChange = useCallback((nextValue) => { const nextHSLA = nextValue.toHsl(); setInternalHSLA((prev) => mergeHSLA(nextHSLA, prev)); const nextHex = nextValue.toHex(); lastProducedHexRef.current = nextHex; debouncedSetColor(nextHex); }, [debouncedSetColor]); const [colorType, setColorType] = useState(copyFormat || "hex"); const maybeHandlePaste = useCallback((event) => { const pastedText = event.clipboardData?.getData("text")?.trim(); if (!pastedText) { return; } const parsedColor = colord(pastedText); if (!parsedColor.isValid()) { return; } handleChange(parsedColor); const supportedFormats = { hex: "hex", rgb: "rgb", hsl: "hsl" }; const detectedFormat = String(getFormat(pastedText)); const newColorType = supportedFormats[detectedFormat]; if (newColorType) { setColorType(newColorType); } event.stopPropagation(); event.preventDefault(); }, [handleChange, setColorType]); return /* @__PURE__ */ _jsxs(ColorfulWrapper, { ref: forwardedRef, ...divProps, onPasteCapture: maybeHandlePaste, children: [/* @__PURE__ */ _jsx(Picker, { onChange: handleHSLAChange, hsla: internalHSLA, enableAlpha }), /* @__PURE__ */ _jsxs(AuxiliaryColorArtefactWrapper, { children: [/* @__PURE__ */ _jsxs(AuxiliaryColorArtefactHStackHeader, { justify: "space-between", children: [/* @__PURE__ */ _jsx(SelectControl, { size: "compact", options, value: colorType, onChange: (nextColorType) => setColorType(nextColorType), label: __("Color format"), hideLabelFromVision: true, variant: "minimal" }), /* @__PURE__ */ _jsx(ColorCopyButton, { color: safeColordColor, colorType: copyFormat || colorType })] }), /* @__PURE__ */ _jsx(ColorInputWrapper, { direction: "column", gap: 2, children: /* @__PURE__ */ _jsx(ColorInput, { colorType, color: safeColordColor, hsla: internalHSLA, onChange: handleChange, onHSLChange: handleHSLAChange, enableAlpha }) })] })] }); }; var ColorPicker = contextConnect(UnconnectedColorPicker, "ColorPicker"); var component_default = ColorPicker; export { ColorPicker, component_default as default }; //# sourceMappingURL=component.mjs.map