@sanity/color-input
Version:
872 lines (871 loc) • 38 kB
JavaScript
import { set, setIfMissing, unset } from "sanity";
import { c } from "react/compiler-runtime";
import { assignInlineVars } from "@vanilla-extract/dynamic";
import { startTransition, useEffect, useEffectEvent, useId, useLayoutEffect, useOptimistic, useRef, useState } from "react";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
import { AddIcon } from "@sanity/icons/Add";
import { TrashIcon } from "@sanity/icons/Trash";
import { Box, Button, Card, Flex, Inline, Stack, Text, useTheme_v2 } from "@sanity/ui";
import tinycolor from "tinycolor2";
import throttle from "lodash-es/throttle.js";
var colorBox$1 = "_58odtb3", colorBoxContainer = "_58odtb2", colorListWrap = "_58odtb1", swatchBackgroundVar = "var(--_58odtb0)";
function ColorListWrap(props) {
let $ = c(2), t0;
return $[0] === props ? t0 = $[1] : (t0 = /* @__PURE__ */ jsx(Flex, {
...props,
className: colorListWrap
}), $[0] = props, $[1] = t0), t0;
}
function ColorBoxContainer(props) {
let $ = c(2), t0;
return $[0] === props ? t0 = $[1] : (t0 = /* @__PURE__ */ jsx("div", {
...props,
className: colorBoxContainer
}), $[0] = props, $[1] = t0), t0;
}
function ColorBox$1(t0) {
let $ = c(4), { backgroundColor } = t0, t1;
$[0] === backgroundColor ? t1 = $[1] : (t1 = assignInlineVars({ [swatchBackgroundVar]: backgroundColor }), $[0] = backgroundColor, $[1] = t1);
let t2;
return $[2] === t1 ? t2 = $[3] : (t2 = /* @__PURE__ */ jsx("div", {
className: colorBox$1,
style: t1
}), $[2] = t1, $[3] = t2), t2;
}
const validateColors = (colors) => {
let seen = /* @__PURE__ */ new Set();
return colors.reduce((cls, c) => {
let color = c.hex ? tinycolor(c.hex) : tinycolor(c);
if (color.isValid()) {
let backgroundColor = color.toRgbString(), key = JSON.stringify({
color: c,
backgroundColor
});
seen.has(key) || (seen.add(key), cls.push({
key,
color: c,
backgroundColor
}));
}
return cls;
}, []);
};
function ColorList(t0) {
let $ = c(7), { colors, onChange } = t0;
if (!colors) return null;
let t1;
if ($[0] !== colors || $[1] !== onChange) {
let t2;
$[3] === onChange ? t2 = $[4] : (t2 = (t3) => {
let { key, color, backgroundColor } = t3;
return /* @__PURE__ */ jsx(ColorBoxContainer, {
onClick: () => {
onChange(color);
},
children: /* @__PURE__ */ jsx(ColorBox$1, { backgroundColor })
}, key);
}, $[3] = onChange, $[4] = t2), t1 = validateColors(colors).map(t2), $[0] = colors, $[1] = onChange, $[2] = t1;
} else t1 = $[2];
let t2;
return $[5] === t1 ? t2 = $[6] : (t2 = /* @__PURE__ */ jsx(ColorListWrap, {
wrap: "wrap",
children: t1
}), $[5] = t1, $[6] = t2), t2;
}
/**
* Renders a checkerboard pattern as a data URL, used as the transparency backdrop.
*
* Forked from
* {@link https://github.com/casesandberg/react-color/blob/v2.19.3/src/helpers/checkboard.js | react-color's checkboard helper}
* (MIT, Copyright (c) 2015 Case Sandberg). See the plugin LICENSE.
*/
const checkboardCache = {};
function render(c1, c2, size, serverCanvas) {
if (typeof document > "u" && !serverCanvas) return null;
let canvas = serverCanvas ? new serverCanvas() : document.createElement("canvas");
canvas.width = size * 2, canvas.height = size * 2;
let ctx = canvas.getContext("2d");
return ctx ? (ctx.fillStyle = c1, ctx.fillRect(0, 0, canvas.width, canvas.height), ctx.fillStyle = c2, ctx.fillRect(0, 0, size, size), ctx.translate(size, size), ctx.fillRect(0, 0, size, size), canvas.toDataURL()) : null;
}
function get(c1, c2, size, serverCanvas) {
let key = `${c1}-${c2}-${size}${serverCanvas ? "-server" : ""}`, cached = checkboardCache[key];
if (cached) return cached;
let checkboard = render(c1, c2, size, serverCanvas);
return checkboardCache[key] = checkboard, checkboard;
}
var backgroundImageVar = "var(--_1bq5keq2)", borderRadiusVar = "var(--_1bq5keq0)", boxShadowVar = "var(--_1bq5keq1)", checkboard = "_1bq5keq3";
/**
* Checkerboard transparency backdrop.
*
* Forked from
* {@link https://github.com/casesandberg/react-color/blob/v2.19.3/src/components/common/Checkboard.js | react-color's Checkboard}
* (MIT, Copyright (c) 2015 Case Sandberg). See the plugin LICENSE. The upstream
* `children` cloning branch is dropped as it is unused here.
*/
const EMPTY_RENDERERS = {};
function Checkboard(t0) {
let $ = c(11), { white: t1, grey: t2, size: t3, renderers: t4, borderRadius, boxShadow } = t0, white = t1 === void 0 ? "transparent" : t1, grey = t2 === void 0 ? "rgba(0,0,0,.08)" : t2, size = t3 === void 0 ? 8 : t3, renderers = t4 === void 0 ? EMPTY_RENDERERS : t4, t5;
$[0] !== grey || $[1] !== renderers.canvas || $[2] !== size || $[3] !== white ? (t5 = get(white, grey, size, renderers.canvas), $[0] = grey, $[1] = renderers.canvas, $[2] = size, $[3] = white, $[4] = t5) : t5 = $[4];
let background = t5, t6 = background ? `url(${background}) center left` : void 0, t7;
$[5] !== borderRadius || $[6] !== boxShadow || $[7] !== t6 ? (t7 = assignInlineVars({
[borderRadiusVar]: borderRadius,
[boxShadowVar]: boxShadow,
[backgroundImageVar]: t6
}), $[5] = borderRadius, $[6] = boxShadow, $[7] = t6, $[8] = t7) : t7 = $[8];
let t8;
return $[9] === t7 ? t8 = $[10] : (t8 = /* @__PURE__ */ jsx("div", {
className: checkboard,
style: t7
}), $[9] = t7, $[10] = t8), t8;
}
function calculateChange$2(e, hsl, direction, initialA, container) {
let containerWidth = container.clientWidth, containerHeight = container.clientHeight, x = "touches" in e ? e.touches[0]?.pageX ?? 0 : e.pageX, y = "touches" in e ? e.touches[0]?.pageY ?? 0 : e.pageY, left = x - (container.getBoundingClientRect().left + window.scrollX), top = y - (container.getBoundingClientRect().top + window.scrollY);
if (direction === "vertical") {
let a;
return a = top < 0 ? 0 : top > containerHeight ? 1 : Math.round(top * 100 / containerHeight) / 100, hsl.a === a ? null : {
h: hsl.h,
s: hsl.s,
l: hsl.l,
a,
source: "rgb"
};
}
let a;
return a = left < 0 ? 0 : left > containerWidth ? 1 : Math.round(left * 100 / containerWidth) / 100, initialA === a ? null : {
h: hsl.h,
s: hsl.s,
l: hsl.l,
a,
source: "rgb"
};
}
/**
* Drag plumbing shared by the picker surfaces (Saturation/Hue/Alpha) and the
* draggable `EditableInput` label.
*
* Attaches a native `mousedown` listener to the target element; each drag then
* tracks `mousemove`/`mouseup` on a window until the pointer is released or the
* component unmounts. The callbacks are Effect Events, so every event reads the
* latest render's props — mirroring how the original react-color class methods
* read `this.props` on each event.
*
* Note: this deliberately does not use a React 19 ref-callback with cleanup —
* the React Compiler memoizes ref callbacks against their captured deps, so a
* mid-drag prop update (every `mousemove` triggers `onChange`) would detach and
* re-attach the ref, aborting the in-flight drag.
*/
function useDrag(targetRef, options) {
let $ = c(9), onDragStart = useEffectEvent(options.onDragStart), onDrag = useEffectEvent(options.onDrag), getWindow = useEffectEvent(options.getWindow ?? _temp$1), enabled = options.enabled ?? !0, t0;
$[0] !== enabled || $[1] !== getWindow || $[2] !== onDrag || $[3] !== onDragStart || $[4] !== targetRef ? (t0 = () => {
let target = enabled ? targetRef.current : null;
if (!target) return _temp2;
let controller = new AbortController(), dragController = null;
return target.addEventListener("mousedown", (event) => {
if (!onDragStart(event)) return;
dragController?.abort(), dragController = new AbortController();
let { signal } = dragController, targetWindow = getWindow();
targetWindow.addEventListener("mousemove", (moveEvent) => onDrag(moveEvent), { signal }), targetWindow.addEventListener("mouseup", () => dragController?.abort(), { signal });
}, { signal: controller.signal }), () => {
controller.abort(), dragController?.abort();
};
}, $[0] = enabled, $[1] = getWindow, $[2] = onDrag, $[3] = onDragStart, $[4] = targetRef, $[5] = t0) : t0 = $[5];
let t1;
$[6] !== enabled || $[7] !== targetRef ? (t1 = [enabled, targetRef], $[6] = enabled, $[7] = targetRef, $[8] = t1) : t1 = $[8], useLayoutEffect(t0, t1);
}
function _temp2() {}
function _temp$1() {
return window;
}
var checkboardLayer = "_1jwt26w6", container = "_1jwt26w8", gradientLayer = "_1jwt26w7", gradientVar = "var(--_1jwt26w2)", pointer$2 = {
horizontal: "_1jwt26w9",
vertical: "_1jwt26wa"
}, pointerKnob$2 = "_1jwt26wb", pointerLeftVar$2 = "var(--_1jwt26w3)", pointerTopVar$2 = "var(--_1jwt26w4)", radiusVar$2 = "var(--_1jwt26w0)", root$3 = "_1jwt26w5", shadowVar$2 = "var(--_1jwt26w1)";
/**
* Alpha (transparency) slider.
*
* Forked from
* {@link https://github.com/casesandberg/react-color/blob/v2.19.3/src/components/common/Alpha.js | react-color's Alpha}
* (MIT, Copyright (c) 2015 Case Sandberg). See the plugin LICENSE.
*/
function Alpha(t0) {
let $ = c(29), { rgb, hsl, a, direction, radius, shadow, renderers, onChange } = t0, containerRef = useRef(null), t1;
$[0] !== a || $[1] !== direction || $[2] !== hsl || $[3] !== onChange ? (t1 = (event) => {
let containerEl = containerRef.current;
if (!containerEl) return;
let change = calculateChange$2(event, hsl, direction, a, containerEl);
change && typeof onChange == "function" && onChange(change);
}, $[0] = a, $[1] = direction, $[2] = hsl, $[3] = onChange, $[4] = t1) : t1 = $[4];
let handleChange = t1, t2;
$[5] === handleChange ? t2 = $[6] : (t2 = (event_0) => (handleChange(event_0), !0), $[5] = handleChange, $[6] = t2);
let t3;
$[7] !== handleChange || $[8] !== t2 ? (t3 = {
onDragStart: t2,
onDrag: handleChange
}, $[7] = handleChange, $[8] = t2, $[9] = t3) : t3 = $[9], useDrag(containerRef, t3);
let alphaValue = rgb.a ?? 1, gradient = direction === "vertical" ? `linear-gradient(to bottom, rgba(${rgb.r},${rgb.g},${rgb.b}, 0) 0%, rgba(${rgb.r},${rgb.g},${rgb.b}, 1) 100%)` : `linear-gradient(to right, rgba(${rgb.r},${rgb.g},${rgb.b}, 0) 0%, rgba(${rgb.r},${rgb.g},${rgb.b}, 1) 100%)`, pointerDirection = direction === "vertical" ? "vertical" : "horizontal", t4 = pointerDirection === "horizontal" ? `${alphaValue * 100}%` : void 0, t5 = pointerDirection === "vertical" ? `${alphaValue * 100}%` : void 0, t6;
$[10] !== gradient || $[11] !== radius || $[12] !== shadow || $[13] !== t4 || $[14] !== t5 ? (t6 = assignInlineVars({
[radiusVar$2]: radius,
[shadowVar$2]: shadow,
[gradientVar]: gradient,
[pointerLeftVar$2]: t4,
[pointerTopVar$2]: t5
}), $[10] = gradient, $[11] = radius, $[12] = shadow, $[13] = t4, $[14] = t5, $[15] = t6) : t6 = $[15];
let t7;
$[16] === renderers ? t7 = $[17] : (t7 = /* @__PURE__ */ jsx("div", {
className: checkboardLayer,
children: /* @__PURE__ */ jsx(Checkboard, { renderers })
}), $[16] = renderers, $[17] = t7);
let t8;
$[18] === Symbol.for("react.memo_cache_sentinel") ? (t8 = /* @__PURE__ */ jsx("div", { className: gradientLayer }), $[18] = t8) : t8 = $[18];
let t9 = pointer$2[pointerDirection], t10;
$[19] === Symbol.for("react.memo_cache_sentinel") ? (t10 = /* @__PURE__ */ jsx("div", { className: pointerKnob$2 }), $[19] = t10) : t10 = $[19];
let t11;
$[20] === t9 ? t11 = $[21] : (t11 = /* @__PURE__ */ jsx("div", {
className: t9,
children: t10
}), $[20] = t9, $[21] = t11);
let t12;
$[22] !== handleChange || $[23] !== t11 ? (t12 = /* @__PURE__ */ jsx("div", {
className: container,
ref: containerRef,
onTouchMove: handleChange,
onTouchStart: handleChange,
children: t11
}), $[22] = handleChange, $[23] = t11, $[24] = t12) : t12 = $[24];
let t13;
return $[25] !== t12 || $[26] !== t6 || $[27] !== t7 ? (t13 = /* @__PURE__ */ jsxs("div", {
className: root$3,
style: t6,
children: [
t7,
t8,
t12
]
}), $[25] = t12, $[26] = t6, $[27] = t7, $[28] = t13) : t13 = $[28], t13;
}
var input = "lba2g27", inputBgVar = "var(--lba2g22)", inputBorderVar = "var(--lba2g20)", inputFgVar = "var(--lba2g21)", inputFontSizeVar = "var(--lba2g23)", label = "lba2g28", labelDrag = "lba2g29", labelFgVar = "var(--lba2g25)", labelFontSizeVar = "var(--lba2g24)", wrap = "lba2g26";
/**
* Labeled text input with arrow-key stepping and drag-to-change support.
*
* Forked from
* {@link https://github.com/casesandberg/react-color/blob/v2.19.3/src/components/common/EditableInput.js | react-color's EditableInput}
* (MIT, Copyright (c) 2015 Case Sandberg). See the plugin LICENSE.
*
* @remarks
* Theme-driven colors are applied via vanilla-extract CSS variables set by the
* parent (`ColorPickerFields`).
*/
const getNumberValue = (value) => Number(String(value).replace(/%/g, "")), normalizeDisplayValue = (value) => String(value ?? "").toUpperCase();
function EditableInput(t0) {
let $ = c(44), { label: label$1, value: valueProp, arrowOffset, placeholder, hideLabel, dragLabel, dragMax, onChange } = t0, inputId = useId(), inputRef = useRef(null), labelRef = useRef(null), t1;
$[0] === valueProp ? t1 = $[1] : (t1 = normalizeDisplayValue(valueProp), $[0] = valueProp, $[1] = t1);
let initialValue = t1, [inputValue, setInputValue] = useState(initialValue), [blurValue, setBlurValue] = useState(initialValue), t2, t3;
$[2] !== inputValue || $[3] !== valueProp ? (t2 = () => {
let nextValue = normalizeDisplayValue(valueProp);
if (nextValue === inputValue) {
startTransition(() => {
setBlurValue("");
});
return;
}
if (inputRef.current === document.activeElement) {
setBlurValue(nextValue);
return;
}
setInputValue(nextValue), setBlurValue((currentBlurValue) => currentBlurValue ? "" : nextValue);
}, t3 = [inputValue, valueProp], $[2] = inputValue, $[3] = valueProp, $[4] = t2, $[5] = t3) : (t2 = $[4], t3 = $[5]), useEffect(t2, t3);
let t4;
$[6] !== blurValue || $[7] !== valueProp ? (t4 = () => {
blurValue && (setInputValue(normalizeDisplayValue(valueProp)), setBlurValue(""));
}, $[6] = blurValue, $[7] = valueProp, $[8] = t4) : t4 = $[8];
let handleBlur = t4, t5;
$[9] !== label$1 || $[10] !== onChange ? (t5 = (event) => {
let { value } = event.target;
onChange?.({ [label$1]: value }, event), setInputValue(value);
}, $[9] = label$1, $[10] = onChange, $[11] = t5) : t5 = $[11];
let handleChange = t5, t6;
$[12] !== arrowOffset || $[13] !== label$1 || $[14] !== onChange ? (t6 = (event_0) => {
let numericValue = getNumberValue(event_0.currentTarget.value), isUp = event_0.key === "ArrowUp", isDown = event_0.key === "ArrowDown";
if (!Number.isNaN(numericValue) && (isUp || isDown)) {
let offset = arrowOffset ?? 1, updatedValue = isUp ? numericValue + offset : numericValue - offset;
onChange?.({ [label$1]: String(updatedValue) }, event_0), setInputValue(String(updatedValue));
}
}, $[12] = arrowOffset, $[13] = label$1, $[14] = onChange, $[15] = t6) : t6 = $[15];
let handleKeyDown = t6, t7;
$[16] !== dragLabel || $[17] !== dragMax || $[18] !== label$1 || $[19] !== onChange || $[20] !== valueProp ? (t7 = (event_1) => {
if (!dragLabel) return;
let numericValue_0 = typeof valueProp == "number" ? valueProp : Number(valueProp), newValue = Math.round(numericValue_0 + event_1.movementX);
dragMax !== void 0 && newValue >= 0 && newValue <= dragMax && onChange?.({ [label$1]: String(newValue) }, event_1);
}, $[16] = dragLabel, $[17] = dragMax, $[18] = label$1, $[19] = onChange, $[20] = valueProp, $[21] = t7) : t7 = $[21];
let handleDrag = t7, showLabel = !!(label$1 && !hideLabel), t8;
$[22] !== dragLabel || $[23] !== handleDrag ? (t8 = (event_2) => dragLabel ? (event_2.preventDefault(), handleDrag(event_2), !0) : !1, $[22] = dragLabel, $[23] = handleDrag, $[24] = t8) : t8 = $[24];
let t9;
$[25] !== handleDrag || $[26] !== showLabel || $[27] !== t8 ? (t9 = {
enabled: showLabel,
onDragStart: t8,
onDrag: handleDrag
}, $[25] = handleDrag, $[26] = showLabel, $[27] = t8, $[28] = t9) : t9 = $[28], useDrag(labelRef, t9);
let t10;
$[29] !== handleBlur || $[30] !== handleChange || $[31] !== handleKeyDown || $[32] !== inputId || $[33] !== inputValue || $[34] !== placeholder ? (t10 = /* @__PURE__ */ jsx("input", {
id: inputId,
className: input,
ref: inputRef,
value: inputValue,
onKeyDown: handleKeyDown,
onChange: handleChange,
onBlur: handleBlur,
placeholder,
spellCheck: "false"
}), $[29] = handleBlur, $[30] = handleChange, $[31] = handleKeyDown, $[32] = inputId, $[33] = inputValue, $[34] = placeholder, $[35] = t10) : t10 = $[35];
let t11;
$[36] !== dragLabel || $[37] !== inputId || $[38] !== label$1 || $[39] !== showLabel ? (t11 = showLabel ? /* @__PURE__ */ jsx("label", {
htmlFor: inputId,
ref: labelRef,
className: dragLabel ? `${label} ${labelDrag}` : label,
children: label$1
}) : null, $[36] = dragLabel, $[37] = inputId, $[38] = label$1, $[39] = showLabel, $[40] = t11) : t11 = $[40];
let t12;
return $[41] !== t10 || $[42] !== t11 ? (t12 = /* @__PURE__ */ jsxs("div", {
className: wrap,
children: [t10, t11]
}), $[41] = t10, $[42] = t11, $[43] = t12) : t12 = $[43], t12;
}
/**
* Color conversion and validation helpers built on `tinycolor2`.
*
* Forked from
* {@link https://github.com/casesandberg/react-color/blob/v2.19.3/src/helpers/color.js | react-color's color helpers}
* (MIT, Copyright (c) 2015 Case Sandberg). See the plugin LICENSE.
*/
const VALIDATION_KEYS = /* @__PURE__ */ new Set([
"r",
"g",
"b",
"a",
"h",
"s",
"l",
"v"
]), PERCENT_PATTERN = /^\d+%$/;
function simpleCheckForValidColor(data) {
if (typeof data == "string") return data;
let checked = 0, passed = 0;
for (let [key, value] of Object.entries(data)) !VALIDATION_KEYS.has(key) || !value || (checked += 1, Number.isNaN(Number(value)) || (passed += 1), (key === "s" || key === "l") && PERCENT_PATTERN.test(String(value)) && (passed += 1));
return checked === passed && data;
}
function toState(data, oldHue) {
let instance = typeof data == "string" ? tinycolor(data) : "hex" in data ? tinycolor(data.hex) : tinycolor(data), hsl = instance.toHsl(), hsv = instance.toHsv(), rgb = instance.toRgb(), hex = instance.toHex();
hsl.s === 0 && (hsl.h = oldHue ?? 0, hsv.h = oldHue ?? 0);
let transparent = hex === "000000" && rgb.a === 0, incomingHue = typeof data == "string" ? void 0 : "h" in data ? data.h : void 0, source = typeof data == "string" ? void 0 : data.source;
return {
hsl,
hex: transparent ? "transparent" : `#${hex}`,
rgb,
hsv,
oldHue: incomingHue || oldHue || hsl.h,
source: source ?? ""
};
}
function isValidHex(hex) {
if (hex === "transparent") return !0;
let lh = +(hex.charAt(0) === "#");
return hex.length !== 4 + lh && hex.length < 7 + lh && tinycolor(hex).isValid();
}
function calculateChange$1(e, direction, hsl, container) {
let containerWidth = container.clientWidth, containerHeight = container.clientHeight, x = "touches" in e ? e.touches[0]?.pageX ?? 0 : e.pageX, y = "touches" in e ? e.touches[0]?.pageY ?? 0 : e.pageY, left = x - (container.getBoundingClientRect().left + window.scrollX), top = y - (container.getBoundingClientRect().top + window.scrollY);
if (direction === "vertical") {
let h;
return h = top < 0 ? 359 : top > containerHeight ? 0 : 360 * (-(top * 100 / containerHeight) + 100) / 100, hsl.h === h ? null : {
h,
s: hsl.s,
l: hsl.l,
a: hsl.a ?? 1,
source: "hsl"
};
}
let h;
return h = left < 0 ? 0 : left > containerWidth ? 359 : 360 * (left * 100 / containerWidth) / 100, hsl.h === h ? null : {
h,
s: hsl.s,
l: hsl.l,
a: hsl.a ?? 1,
source: "hsl"
};
}
var gradient = {
horizontal: "kz76125",
vertical: "kz76126"
}, pointer$1 = {
horizontal: "kz76127",
vertical: "kz76128"
}, pointerKnob$1 = "kz76129", pointerLeftVar$1 = "var(--kz76122)", pointerTopVar$1 = "var(--kz76123)", radiusVar$1 = "var(--kz76120)", root$2 = "kz76124", shadowVar$1 = "var(--kz76121)";
/**
* Hue slider.
*
* Forked from
* {@link https://github.com/casesandberg/react-color/blob/v2.19.3/src/components/common/Hue.js | react-color's Hue}
* (MIT, Copyright (c) 2015 Case Sandberg). See the plugin LICENSE.
*/
function Hue(t0) {
let $ = c(24), { hsl, direction: t1, radius, shadow, onChange } = t0, direction = t1 === void 0 ? "horizontal" : t1, containerRef = useRef(null), t2;
$[0] !== direction || $[1] !== hsl || $[2] !== onChange ? (t2 = (event) => {
let container = containerRef.current;
if (!container) return;
let change = calculateChange$1(event, direction, hsl, container);
change && typeof onChange == "function" && onChange(change);
}, $[0] = direction, $[1] = hsl, $[2] = onChange, $[3] = t2) : t2 = $[3];
let handleChange = t2, t3;
$[4] === handleChange ? t3 = $[5] : (t3 = (event_0) => (handleChange(event_0), !0), $[4] = handleChange, $[5] = t3);
let t4;
$[6] !== handleChange || $[7] !== t3 ? (t4 = {
onDragStart: t3,
onDrag: handleChange
}, $[6] = handleChange, $[7] = t3, $[8] = t4) : t4 = $[8], useDrag(containerRef, t4);
let pointerDirection = direction === "vertical" ? "vertical" : "horizontal", t5 = pointerDirection === "horizontal" ? `${hsl.h * 100 / 360}%` : void 0, t6 = pointerDirection === "vertical" ? `${-(hsl.h * 100 / 360) + 100}%` : void 0, t7;
$[9] !== radius || $[10] !== shadow || $[11] !== t5 || $[12] !== t6 ? (t7 = assignInlineVars({
[radiusVar$1]: radius,
[shadowVar$1]: shadow,
[pointerLeftVar$1]: t5,
[pointerTopVar$1]: t6
}), $[9] = radius, $[10] = shadow, $[11] = t5, $[12] = t6, $[13] = t7) : t7 = $[13];
let t8 = gradient[pointerDirection], t9 = pointer$1[pointerDirection], t10;
$[14] === Symbol.for("react.memo_cache_sentinel") ? (t10 = /* @__PURE__ */ jsx("div", { className: pointerKnob$1 }), $[14] = t10) : t10 = $[14];
let t11;
$[15] === t9 ? t11 = $[16] : (t11 = /* @__PURE__ */ jsx("div", {
className: t9,
children: t10
}), $[15] = t9, $[16] = t11);
let t12;
$[17] !== handleChange || $[18] !== t11 || $[19] !== t8 ? (t12 = /* @__PURE__ */ jsx("div", {
className: t8,
ref: containerRef,
onTouchMove: handleChange,
onTouchStart: handleChange,
children: t11
}), $[17] = handleChange, $[18] = t11, $[19] = t8, $[20] = t12) : t12 = $[20];
let t13;
return $[21] !== t12 || $[22] !== t7 ? (t13 = /* @__PURE__ */ jsx("div", {
className: root$2,
style: t7,
children: t12
}), $[21] = t12, $[22] = t7, $[23] = t13) : t13 = $[23], t13;
}
function calculateChange(e, hsl, container) {
let { width: containerWidth, height: containerHeight } = container.getBoundingClientRect(), x = "touches" in e ? e.touches[0]?.pageX ?? 0 : e.pageX, y = "touches" in e ? e.touches[0]?.pageY ?? 0 : e.pageY, left = x - (container.getBoundingClientRect().left + window.scrollX), top = y - (container.getBoundingClientRect().top + window.scrollY);
left < 0 ? left = 0 : left > containerWidth && (left = containerWidth), top < 0 ? top = 0 : top > containerHeight && (top = containerHeight);
let saturation = left / containerWidth, bright = 1 - top / containerHeight;
return {
h: hsl.h,
s: saturation,
v: bright,
a: hsl.a ?? 1,
source: "hsv"
};
}
var black = "_17f1xd57", hueBackgroundVar = "var(--_17f1xd52)", pointer = "_17f1xd58", pointerKnob = "_17f1xd59", pointerLeftVar = "var(--_17f1xd54)", pointerTopVar = "var(--_17f1xd53)", radiusVar = "var(--_17f1xd50)", root$1 = "_17f1xd55", shadowVar = "var(--_17f1xd51)", white = "_17f1xd56";
/**
* Saturation / value box.
*
* Forked from
* {@link https://github.com/casesandberg/react-color/blob/v2.19.3/src/components/common/Saturation.js | react-color's Saturation}
* (MIT, Copyright (c) 2015 Case Sandberg). See the plugin LICENSE.
*/
function Saturation(t0) {
let $ = c(23), { hsl, hsv, radius, shadow, onChange } = t0, containerRef = useRef(null), t1;
$[0] === Symbol.for("react.memo_cache_sentinel") ? (t1 = throttle(_temp, 50), $[0] = t1) : t1 = $[0];
let throttledChange = t1, t2, t3;
$[1] === Symbol.for("react.memo_cache_sentinel") ? (t2 = () => () => {
throttledChange.cancel();
}, t3 = [throttledChange], $[1] = t2, $[2] = t3) : (t2 = $[1], t3 = $[2]), useEffect(t2, t3);
let t4;
$[3] !== hsl || $[4] !== onChange ? (t4 = (event) => {
let container = containerRef.current;
!container || typeof onChange != "function" || throttledChange(onChange, calculateChange(event, hsl, container));
}, $[3] = hsl, $[4] = onChange, $[5] = t4) : t4 = $[5];
let handleChange = t4, t5;
$[6] === handleChange ? t5 = $[7] : (t5 = (event_0) => (handleChange(event_0), !0), $[6] = handleChange, $[7] = t5);
let t6;
$[8] === Symbol.for("react.memo_cache_sentinel") ? (t6 = () => {
let renderWindow = window;
for (; !renderWindow.document.contains(containerRef.current) && renderWindow.parent !== renderWindow;) renderWindow = renderWindow.parent;
return renderWindow;
}, $[8] = t6) : t6 = $[8];
let t7;
$[9] !== handleChange || $[10] !== t5 ? (t7 = {
onDragStart: t5,
onDrag: handleChange,
getWindow: t6
}, $[9] = handleChange, $[10] = t5, $[11] = t7) : t7 = $[11], useDrag(containerRef, t7);
let t8 = `hsl(${hsl.h},100%, 50%)`, t9 = `${-(hsv.v * 100) + 100}%`, t10 = `${hsv.s * 100}%`, t11;
$[12] !== radius || $[13] !== shadow || $[14] !== t10 || $[15] !== t8 || $[16] !== t9 ? (t11 = assignInlineVars({
[hueBackgroundVar]: t8,
[radiusVar]: radius,
[shadowVar]: shadow,
[pointerTopVar]: t9,
[pointerLeftVar]: t10
}), $[12] = radius, $[13] = shadow, $[14] = t10, $[15] = t8, $[16] = t9, $[17] = t11) : t11 = $[17];
let t12;
$[18] === Symbol.for("react.memo_cache_sentinel") ? (t12 = /* @__PURE__ */ jsx("div", { className: black }), $[18] = t12) : t12 = $[18];
let t13;
$[19] === Symbol.for("react.memo_cache_sentinel") ? (t13 = /* @__PURE__ */ jsxs("div", {
className: white,
children: [t12, /* @__PURE__ */ jsx("div", {
className: pointer,
children: /* @__PURE__ */ jsx("div", { className: pointerKnob })
})]
}), $[19] = t13) : t13 = $[19];
let t14;
return $[20] !== handleChange || $[21] !== t11 ? (t14 = /* @__PURE__ */ jsx("div", {
className: root$1,
style: t11,
ref: containerRef,
onTouchMove: handleChange,
onTouchStart: handleChange,
children: t13
}), $[20] = handleChange, $[21] = t11, $[22] = t14) : t14 = $[22], t14;
}
function _temp(handler, data) {
handler(data);
}
const ColorPickerFields = (t0) => {
let $ = c(36), { onChange, rgb, hsl, hex, disableAlpha } = t0, { color, font } = useTheme_v2(), inputEnabled = color.input.default.enabled, textFontSize = font.text.sizes[0]?.fontSize, labelFontSize = font.label.sizes[0]?.fontSize, t1;
$[0] !== hsl || $[1] !== onChange || $[2] !== rgb ? (t1 = (data) => {
if ("hex" in data && data.hex && isValidHex(data.hex)) onChange({
hex: data.hex,
source: "hex"
});
else if (rgb && ("r" in data && data.r || "g" in data && data.g || "b" in data && data.b)) onChange({
r: Number(data.r) || rgb.r,
g: Number(data.g) || rgb.g,
b: Number(data.b) || rgb.b,
a: rgb.a,
source: "rgb"
});
else if (hsl && "a" in data && data.a) {
let alpha = Number(data.a);
alpha < 0 ? alpha = 0 : alpha > 100 && (alpha = 100), alpha /= 100, onChange({
h: hsl.h,
s: hsl.s,
l: hsl.l,
a: alpha,
source: "hsl"
});
}
}, $[0] = hsl, $[1] = onChange, $[2] = rgb, $[3] = t1) : t1 = $[3];
let handleChange = t1, t2 = textFontSize === void 0 ? void 0 : `${textFontSize}px`, t3 = labelFontSize === void 0 ? void 0 : `${labelFontSize}px`, t4;
$[4] !== color.fg || $[5] !== inputEnabled.bg || $[6] !== inputEnabled.border || $[7] !== inputEnabled.fg || $[8] !== t2 || $[9] !== t3 ? (t4 = assignInlineVars({
[inputBorderVar]: inputEnabled.border,
[inputFgVar]: inputEnabled.fg,
[inputBgVar]: inputEnabled.bg,
[inputFontSizeVar]: t2,
[labelFontSizeVar]: t3,
[labelFgVar]: color.fg
}), $[4] = color.fg, $[5] = inputEnabled.bg, $[6] = inputEnabled.border, $[7] = inputEnabled.fg, $[8] = t2, $[9] = t3, $[10] = t4) : t4 = $[10];
let t5;
$[11] === hex ? t5 = $[12] : (t5 = hex?.replace("#", ""), $[11] = hex, $[12] = t5);
let t6;
$[13] !== handleChange || $[14] !== t5 ? (t6 = /* @__PURE__ */ jsx(Box, {
flex: 2,
marginRight: 1,
children: /* @__PURE__ */ jsx(EditableInput, {
label: "hex",
value: t5,
onChange: handleChange
})
}), $[13] = handleChange, $[14] = t5, $[15] = t6) : t6 = $[15];
let t7 = rgb?.r, t8;
$[16] !== handleChange || $[17] !== t7 ? (t8 = /* @__PURE__ */ jsx(Box, {
flex: 1,
marginRight: 1,
children: /* @__PURE__ */ jsx(EditableInput, {
label: "r",
value: t7,
onChange: handleChange,
dragLabel: !0,
dragMax: 255
})
}), $[16] = handleChange, $[17] = t7, $[18] = t8) : t8 = $[18];
let t9 = rgb?.g, t10;
$[19] !== handleChange || $[20] !== t9 ? (t10 = /* @__PURE__ */ jsx(Box, {
flex: 1,
marginRight: 1,
children: /* @__PURE__ */ jsx(EditableInput, {
label: "g",
value: t9,
onChange: handleChange,
dragLabel: !0,
dragMax: 255
})
}), $[19] = handleChange, $[20] = t9, $[21] = t10) : t10 = $[21];
let t11 = rgb?.b, t12;
$[22] !== handleChange || $[23] !== t11 ? (t12 = /* @__PURE__ */ jsx(Box, {
flex: 1,
marginRight: 1,
children: /* @__PURE__ */ jsx(EditableInput, {
label: "b",
value: t11,
onChange: handleChange,
dragLabel: !0,
dragMax: 255
})
}), $[22] = handleChange, $[23] = t11, $[24] = t12) : t12 = $[24];
let t13;
$[25] !== disableAlpha || $[26] !== handleChange || $[27] !== rgb?.a ? (t13 = !disableAlpha && /* @__PURE__ */ jsx(Box, {
flex: 1,
children: /* @__PURE__ */ jsx(EditableInput, {
label: "a",
value: Math.round((rgb?.a ?? 1) * 100),
onChange: handleChange,
dragLabel: !0,
dragMax: 100
})
}), $[25] = disableAlpha, $[26] = handleChange, $[27] = rgb?.a, $[28] = t13) : t13 = $[28];
let t14;
return $[29] !== t10 || $[30] !== t12 || $[31] !== t13 || $[32] !== t4 || $[33] !== t6 || $[34] !== t8 ? (t14 = /* @__PURE__ */ jsxs(Flex, {
style: t4,
children: [
t6,
t8,
t10,
t12,
t13
]
}), $[29] = t10, $[30] = t12, $[31] = t13, $[32] = t4, $[33] = t6, $[34] = t8, $[35] = t14) : t14 = $[35], t14;
};
var colorBox = "mdovfq7", fieldsBox = "mdovfq9", previewBackgroundVar = "var(--mdovfq1)", previewCard = "mdovfq6", readOnlyContainer = "mdovfq8", root = "mdovfq2", widthVar = "var(--mdovfq0)";
function ColorBox(t0) {
let $ = c(4), { backgroundColor } = t0, t1;
$[0] === backgroundColor ? t1 = $[1] : (t1 = assignInlineVars({ [previewBackgroundVar]: backgroundColor }), $[0] = backgroundColor, $[1] = t1);
let t2;
return $[2] === t1 ? t2 = $[3] : (t2 = /* @__PURE__ */ jsx(Box, {
className: colorBox,
style: t1
}), $[2] = t1, $[3] = t2), t2;
}
function ReadOnlyContainer(props) {
let $ = c(2), t0;
return $[0] === props ? t0 = $[1] : (t0 = /* @__PURE__ */ jsx(Flex, {
...props,
className: readOnlyContainer
}), $[0] = props, $[1] = t0), t0;
}
function FieldsBox(props) {
let $ = c(2), t0;
return $[0] === props ? t0 = $[1] : (t0 = /* @__PURE__ */ jsx(Box, {
...props,
className: fieldsBox
}), $[0] = props, $[1] = t0), t0;
}
const ColorPicker = (props) => {
let $ = c(48), { width, color: t0, onChange: onChangeProp, onUnset, disableAlpha, colorList, readOnly } = props, { rgb, hex, hsv, hsl } = t0, oldHueRef = useRef(hsl?.h ?? 0), t1;
$[0] !== hsl || $[1] !== onChangeProp ? (t1 = (data) => {
if (!simpleCheckForValidColor(data)) return;
let incomingHue = typeof data == "string" ? void 0 : "h" in data ? data.h : void 0, oldHue = hsl && hsl.s > 0 ? hsl.h : oldHueRef.current, nextColor = toState(data, incomingHue || oldHue);
oldHueRef.current = nextColor.oldHue, onChangeProp(nextColor);
}, $[0] = hsl, $[1] = onChangeProp, $[2] = t1) : t1 = $[2];
let onChange = t1;
if (!hsl || !hsv) return null;
let t2;
$[3] === width ? t2 = $[4] : (t2 = width ? assignInlineVars({ [widthVar]: width }) : void 0, $[3] = width, $[4] = t2);
let t3;
$[5] !== disableAlpha || $[6] !== hsl || $[7] !== hsv || $[8] !== onChange || $[9] !== readOnly || $[10] !== rgb ? (t3 = !readOnly && /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsx(Card, {
overflow: "hidden",
className: "mdovfq3",
children: /* @__PURE__ */ jsx(Saturation, {
onChange,
hsl,
hsv
})
}),
/* @__PURE__ */ jsx(Card, {
shadow: 1,
radius: 3,
overflow: "hidden",
className: "mdovfq4",
children: /* @__PURE__ */ jsx(Hue, {
hsl,
onChange: !readOnly && onChange
})
}),
!disableAlpha && /* @__PURE__ */ jsx(Card, {
shadow: 1,
radius: 3,
overflow: "hidden",
className: "mdovfq5",
children: /* @__PURE__ */ jsx(Alpha, {
rgb,
hsl,
onChange
})
})
] }), $[5] = disableAlpha, $[6] = hsl, $[7] = hsv, $[8] = onChange, $[9] = readOnly, $[10] = rgb, $[11] = t3) : t3 = $[11];
let t4;
$[12] === Symbol.for("react.memo_cache_sentinel") ? (t4 = /* @__PURE__ */ jsx(Checkboard, {
size: 8,
white: "transparent",
grey: "rgba(0,0,0,.08)"
}), $[12] = t4) : t4 = $[12];
let t5 = `rgba(${rgb?.r},${rgb?.g},${rgb?.b},${rgb?.a})`, t6;
$[13] === t5 ? t6 = $[14] : (t6 = /* @__PURE__ */ jsx(ColorBox, { backgroundColor: t5 }), $[13] = t5, $[14] = t6);
let t7;
$[15] !== hex || $[16] !== hsl?.h || $[17] !== hsl?.l || $[18] !== hsl?.s || $[19] !== readOnly || $[20] !== rgb?.b || $[21] !== rgb?.g || $[22] !== rgb?.r ? (t7 = readOnly && /* @__PURE__ */ jsx(ReadOnlyContainer, {
padding: 2,
paddingBottom: 1,
sizing: "border",
justify: "space-between",
children: /* @__PURE__ */ jsxs(Stack, {
gap: 3,
marginTop: 1,
children: [/* @__PURE__ */ jsx(Text, {
size: 3,
weight: "bold",
children: hex
}), /* @__PURE__ */ jsxs(Inline, {
gap: 3,
children: [/* @__PURE__ */ jsxs(Text, {
size: 1,
children: [
/* @__PURE__ */ jsx("strong", { children: "RGB: " }),
rgb?.r,
" ",
rgb?.g,
" ",
rgb?.b
]
}), /* @__PURE__ */ jsxs(Text, {
size: 1,
children: [
/* @__PURE__ */ jsx("strong", { children: "HSL: " }),
" ",
Math.round(hsl?.h ?? 0),
" ",
Math.round((hsl?.s ?? 0) * 100),
"% ",
Math.round((hsl?.l ?? 0) * 100),
"%"
]
})]
})]
})
}), $[15] = hex, $[16] = hsl?.h, $[17] = hsl?.l, $[18] = hsl?.s, $[19] = readOnly, $[20] = rgb?.b, $[21] = rgb?.g, $[22] = rgb?.r, $[23] = t7) : t7 = $[23];
let t8;
$[24] !== t6 || $[25] !== t7 ? (t8 = /* @__PURE__ */ jsxs(Card, {
flex: 1,
radius: 2,
overflow: "hidden",
className: previewCard,
children: [
t4,
t6,
t7
]
}), $[24] = t6, $[25] = t7, $[26] = t8) : t8 = $[26];
let t9;
$[27] !== disableAlpha || $[28] !== hex || $[29] !== hsl || $[30] !== onChange || $[31] !== onUnset || $[32] !== readOnly || $[33] !== rgb ? (t9 = !readOnly && /* @__PURE__ */ jsxs(Flex, {
align: "flex-start",
marginLeft: 2,
children: [/* @__PURE__ */ jsx(FieldsBox, { children: /* @__PURE__ */ jsx(ColorPickerFields, {
rgb,
hsl,
hex,
onChange,
disableAlpha
}) }), /* @__PURE__ */ jsx(Box, {
marginLeft: 2,
children: /* @__PURE__ */ jsx(Button, {
onClick: onUnset,
title: "Delete color",
icon: TrashIcon,
tone: "critical"
})
})]
}), $[27] = disableAlpha, $[28] = hex, $[29] = hsl, $[30] = onChange, $[31] = onUnset, $[32] = readOnly, $[33] = rgb, $[34] = t9) : t9 = $[34];
let t10;
$[35] !== t8 || $[36] !== t9 ? (t10 = /* @__PURE__ */ jsxs(Flex, { children: [t8, t9] }), $[35] = t8, $[36] = t9, $[37] = t10) : t10 = $[37];
let t11;
$[38] !== colorList || $[39] !== onChange ? (t11 = colorList && /* @__PURE__ */ jsx(ColorList, {
colors: colorList,
onChange
}), $[38] = colorList, $[39] = onChange, $[40] = t11) : t11 = $[40];
let t12;
$[41] !== t10 || $[42] !== t11 || $[43] !== t3 ? (t12 = /* @__PURE__ */ jsx(Card, {
padding: 1,
border: !0,
radius: 1,
children: /* @__PURE__ */ jsxs(Stack, {
gap: 2,
children: [
t3,
t10,
t11
]
})
}), $[41] = t10, $[42] = t11, $[43] = t3, $[44] = t12) : t12 = $[44];
let t13;
return $[45] !== t12 || $[46] !== t2 ? (t13 = /* @__PURE__ */ jsx("div", {
className: root,
style: t2,
children: t12
}), $[45] = t12, $[46] = t2, $[47] = t13) : t13 = $[47], t13;
}, DEFAULT_COLOR = {
hex: "#24a3e3",
hsl: {
h: 200,
s: .7732,
l: .5156,
a: 1
},
hsv: {
h: 200,
s: .8414,
v: .8901,
a: 1
},
rgb: {
r: 46,
g: 163,
b: 227,
a: 1
},
source: "hex"
};
function ColorInput(props) {
let $ = c(9), { onChange, readOnly } = props, _value = props.value, [value, setColorOptimistic] = useOptimistic(_value), type = props.schemaType, focusRef = useRef(null), t0;
$[0] !== onChange || $[1] !== type ? (t0 = function handleChange(nextColor) {
let fieldPatches = type.fields.filter((field) => field.name in nextColor).map((field_0) => {
let nextFieldValue = nextColor[field_0.name], isObject = field_0.type.jsonType === "object";
return set(isObject ? Object.assign({ _type: field_0.type.name }, nextFieldValue) : nextFieldValue, [field_0.name]);
});
onChange([
setIfMissing({ _type: type.name }),
set(type.name, ["_type"]),
set(nextColor.rgb?.a, ["alpha"]),
...fieldPatches
]);
}, $[0] = onChange, $[1] = type, $[2] = t0) : t0 = $[2];
let handleChange = t0, t1;
return $[3] !== handleChange || $[4] !== onChange || $[5] !== readOnly || $[6] !== type || $[7] !== value ? (t1 = /* @__PURE__ */ jsx(Fragment, { children: value && value.hex ? /* @__PURE__ */ jsx(ColorPicker, {
color: value,
onChange: (nextColor_0) => startTransition(() => {
setColorOptimistic(nextColor_0), handleChange(nextColor_0);
}),
readOnly: readOnly || typeof type.readOnly == "boolean" && type.readOnly,
disableAlpha: !!type.options?.disableAlpha,
colorList: type.options?.colorList,
onUnset: () => startTransition(() => {
setColorOptimistic(void 0), onChange(unset());
})
}) : /* @__PURE__ */ jsx(Button, {
icon: AddIcon,
mode: "ghost",
text: "Create color",
ref: focusRef,
disabled: !!readOnly,
onClick: () => startTransition(() => {
setColorOptimistic(DEFAULT_COLOR), handleChange(DEFAULT_COLOR);
})
}) }), $[3] = handleChange, $[4] = onChange, $[5] = readOnly, $[6] = type, $[7] = value, $[8] = t1) : t1 = $[8], t1;
}
export { ColorInput as default };
//# sourceMappingURL=ColorInput-CMhbbfkK.js.map