UNPKG

storybook

Version:

Storybook: Develop, document, and test UI components in isolation

539 lines (531 loc) • 27.1 kB
import { getControlId } from "./chunk-2FRVAXCZ.js"; import { require_color_convert } from "./chunk-VIJ7SQRO.js"; import "./chunk-NZMVUW5T.js"; import { __toESM } from "./chunk-A242L54C.js"; // ../addons/docs/src/blocks/controls/Color.tsx var import_color_convert = __toESM(require_color_convert(), 1); import React, { useCallback, useEffect, useMemo, useState } from "react"; import { Button, Form, PopoverProvider } from "storybook/internal/components"; import { MarkupIcon } from "@storybook/icons"; // ../../node_modules/es-toolkit/dist/function/debounce.mjs function debounce(func, debounceMs, { signal, edges } = {}) { let pendingThis, pendingArgs = null, leading = edges != null && edges.includes("leading"), trailing = edges == null || edges.includes("trailing"), invoke = () => { pendingArgs !== null && (func.apply(pendingThis, pendingArgs), pendingThis = void 0, pendingArgs = null); }, onTimerEnd = () => { trailing && invoke(), cancel(); }, timeoutId = null, schedule = () => { timeoutId != null && clearTimeout(timeoutId), timeoutId = setTimeout(() => { timeoutId = null, onTimerEnd(); }, debounceMs); }, cancelTimer = () => { timeoutId !== null && (clearTimeout(timeoutId), timeoutId = null); }, cancel = () => { cancelTimer(), pendingThis = void 0, pendingArgs = null; }, flush = () => { invoke(); }, debounced = function(...args) { if (signal?.aborted) return; pendingThis = this, pendingArgs = args; let isFirstCall = timeoutId == null; schedule(), leading && isFirstCall && invoke(); }; return debounced.schedule = schedule, debounced.cancel = cancel, debounced.flush = flush, signal?.addEventListener("abort", cancel, { once: !0 }), debounced; } // ../../node_modules/es-toolkit/dist/function/partial.mjs function partial(func, ...partialArgs) { return partialImpl(func, placeholderSymbol, ...partialArgs); } function partialImpl(func, placeholder, ...partialArgs) { let partialed = function(...providedArgs) { let providedArgsIndex = 0, substitutedArgs = partialArgs.slice().map((arg) => arg === placeholder ? providedArgs[providedArgsIndex++] : arg), remainingArgs = providedArgs.slice(providedArgsIndex); return func.apply(this, substitutedArgs.concat(remainingArgs)); }; return func.prototype && (partialed.prototype = Object.create(func.prototype)), partialed; } var placeholderSymbol = Symbol("partial.placeholder"); partial.placeholder = placeholderSymbol; // ../../node_modules/es-toolkit/dist/function/partialRight.mjs function partialRight(func, ...partialArgs) { return partialRightImpl(func, placeholderSymbol2, ...partialArgs); } function partialRightImpl(func, placeholder, ...partialArgs) { let partialedRight = function(...providedArgs) { let placeholderLength = partialArgs.filter((arg) => arg === placeholder).length, rangeLength = Math.max(providedArgs.length - placeholderLength, 0), remainingArgs = providedArgs.slice(0, rangeLength), providedArgsIndex = rangeLength, substitutedArgs = partialArgs.slice().map((arg) => arg === placeholder ? providedArgs[providedArgsIndex++] : arg); return func.apply(this, remainingArgs.concat(substitutedArgs)); }; return func.prototype && (partialedRight.prototype = Object.create(func.prototype)), partialedRight; } var placeholderSymbol2 = Symbol("partialRight.placeholder"); partialRight.placeholder = placeholderSymbol2; // ../../node_modules/es-toolkit/dist/function/retry.mjs var DEFAULT_RETRIES = Number.POSITIVE_INFINITY; // ../../node_modules/react-colorful/dist/index.mjs import e, { useRef as r, useMemo as t, useEffect as n, useState as o, useCallback as a, useLayoutEffect as l } from "react"; function u() { return (u = Object.assign || function(e2) { for (var r2 = 1; r2 < arguments.length; r2++) { var t2 = arguments[r2]; for (var n2 in t2) Object.prototype.hasOwnProperty.call(t2, n2) && (e2[n2] = t2[n2]); } return e2; }).apply(this, arguments); } function c(e2, r2) { if (e2 == null) return {}; var t2, n2, o2 = {}, a2 = Object.keys(e2); for (n2 = 0; n2 < a2.length; n2++) r2.indexOf(t2 = a2[n2]) >= 0 || (o2[t2] = e2[t2]); return o2; } function i(e2) { var t2 = r(e2), n2 = r(function(e3) { t2.current && t2.current(e3); }); return t2.current = e2, n2.current; } var s = function(e2, r2, t2) { return r2 === void 0 && (r2 = 0), t2 === void 0 && (t2 = 1), e2 > t2 ? t2 : e2 < r2 ? r2 : e2; }, f = function(e2) { return "touches" in e2; }, v = function(e2) { return e2 && e2.ownerDocument.defaultView || self; }, d = function(e2, r2, t2) { var n2 = e2.getBoundingClientRect(), o2 = f(r2) ? (function(e3, r3) { for (var t3 = 0; t3 < e3.length; t3++) if (e3[t3].identifier === r3) return e3[t3]; return e3[0]; })(r2.touches, t2) : r2; return { left: s((o2.pageX - (n2.left + v(e2).pageXOffset)) / n2.width), top: s((o2.pageY - (n2.top + v(e2).pageYOffset)) / n2.height) }; }, h = function(e2) { !f(e2) && e2.preventDefault(); }, m = e.memo(function(o2) { var a2 = o2.onMove, l2 = o2.onKey, s2 = c(o2, ["onMove", "onKey"]), m2 = r(null), g2 = i(a2), p2 = i(l2), b2 = r(null), _2 = r(!1), x2 = t(function() { var e2 = function(e3) { h(e3), (f(e3) ? e3.touches.length > 0 : e3.buttons > 0) && m2.current ? g2(d(m2.current, e3, b2.current)) : t2(!1); }, r2 = function() { return t2(!1); }; function t2(t3) { var n2 = _2.current, o3 = v(m2.current), a3 = t3 ? o3.addEventListener : o3.removeEventListener; a3(n2 ? "touchmove" : "mousemove", e2), a3(n2 ? "touchend" : "mouseup", r2); } return [function(e3) { var r3 = e3.nativeEvent, n2 = m2.current; if (n2 && (h(r3), !(function(e4, r4) { return r4 && !f(e4); })(r3, _2.current) && n2)) { if (f(r3)) { _2.current = !0; var o3 = r3.changedTouches || []; o3.length && (b2.current = o3[0].identifier); } n2.focus(), g2(d(n2, r3, b2.current)), t2(!0); } }, function(e3) { var r3 = e3.which || e3.keyCode; r3 < 37 || r3 > 40 || (e3.preventDefault(), p2({ left: r3 === 39 ? 0.05 : r3 === 37 ? -0.05 : 0, top: r3 === 40 ? 0.05 : r3 === 38 ? -0.05 : 0 })); }, t2]; }, [p2, g2]), C2 = x2[0], E2 = x2[1], H2 = x2[2]; return n(function() { return H2; }, [H2]), e.createElement("div", u({}, s2, { onTouchStart: C2, onMouseDown: C2, className: "react-colorful__interactive", ref: m2, onKeyDown: E2, tabIndex: 0, role: "slider" })); }), g = function(e2) { return e2.filter(Boolean).join(" "); }, p = function(r2) { var t2 = r2.color, n2 = r2.left, o2 = r2.top, a2 = o2 === void 0 ? 0.5 : o2, l2 = g(["react-colorful__pointer", r2.className]); return e.createElement("div", { className: l2, style: { top: 100 * a2 + "%", left: 100 * n2 + "%" } }, e.createElement("div", { className: "react-colorful__pointer-fill", style: { backgroundColor: t2 } })); }, b = function(e2, r2, t2) { return r2 === void 0 && (r2 = 0), t2 === void 0 && (t2 = Math.pow(10, r2)), Math.round(t2 * e2) / t2; }, _ = { grad: 0.9, turn: 360, rad: 360 / (2 * Math.PI) }, x = function(e2) { return L(C(e2)); }, C = function(e2) { return e2[0] === "#" && (e2 = e2.substring(1)), e2.length < 6 ? { r: parseInt(e2[0] + e2[0], 16), g: parseInt(e2[1] + e2[1], 16), b: parseInt(e2[2] + e2[2], 16), a: e2.length === 4 ? b(parseInt(e2[3] + e2[3], 16) / 255, 2) : 1 } : { r: parseInt(e2.substring(0, 2), 16), g: parseInt(e2.substring(2, 4), 16), b: parseInt(e2.substring(4, 6), 16), a: e2.length === 8 ? b(parseInt(e2.substring(6, 8), 16) / 255, 2) : 1 }; }, E = function(e2, r2) { return r2 === void 0 && (r2 = "deg"), Number(e2) * (_[r2] || 1); }, H = function(e2) { var r2 = /hsla?\(?\s*(-?\d*\.?\d+)(deg|rad|grad|turn)?[,\s]+(-?\d*\.?\d+)%?[,\s]+(-?\d*\.?\d+)%?,?\s*[/\s]*(-?\d*\.?\d+)?(%)?\s*\)?/i.exec(e2); return r2 ? N({ h: E(r2[1], r2[2]), s: Number(r2[3]), l: Number(r2[4]), a: r2[5] === void 0 ? 1 : Number(r2[5]) / (r2[6] ? 100 : 1) }) : { h: 0, s: 0, v: 0, a: 1 }; }; var N = function(e2) { var r2 = e2.s, t2 = e2.l; return { h: e2.h, s: (r2 *= (t2 < 50 ? t2 : 100 - t2) / 100) > 0 ? 2 * r2 / (t2 + r2) * 100 : 0, v: t2 + r2, a: e2.a }; }, w = function(e2) { return K(I(e2)); }, y = function(e2) { var r2 = e2.s, t2 = e2.v, n2 = e2.a, o2 = (200 - r2) * t2 / 100; return { h: b(e2.h), s: b(o2 > 0 && o2 < 200 ? r2 * t2 / 100 / (o2 <= 100 ? o2 : 200 - o2) * 100 : 0), l: b(o2 / 2), a: b(n2, 2) }; }, q = function(e2) { var r2 = y(e2); return "hsl(" + r2.h + ", " + r2.s + "%, " + r2.l + "%)"; }, k = function(e2) { var r2 = y(e2); return "hsla(" + r2.h + ", " + r2.s + "%, " + r2.l + "%, " + r2.a + ")"; }, I = function(e2) { var r2 = e2.h, t2 = e2.s, n2 = e2.v, o2 = e2.a; r2 = r2 / 360 * 6, t2 /= 100, n2 /= 100; var a2 = Math.floor(r2), l2 = n2 * (1 - t2), u2 = n2 * (1 - (r2 - a2) * t2), c2 = n2 * (1 - (1 - r2 + a2) * t2), i2 = a2 % 6; return { r: b(255 * [n2, u2, l2, l2, c2, n2][i2]), g: b(255 * [c2, n2, n2, u2, l2, l2][i2]), b: b(255 * [l2, l2, c2, n2, n2, u2][i2]), a: b(o2, 2) }; }; var z = function(e2) { var r2 = /rgba?\(?\s*(-?\d*\.?\d+)(%)?[,\s]+(-?\d*\.?\d+)(%)?[,\s]+(-?\d*\.?\d+)(%)?,?\s*[/\s]*(-?\d*\.?\d+)?(%)?\s*\)?/i.exec(e2); return r2 ? L({ r: Number(r2[1]) / (r2[2] ? 100 / 255 : 1), g: Number(r2[3]) / (r2[4] ? 100 / 255 : 1), b: Number(r2[5]) / (r2[6] ? 100 / 255 : 1), a: r2[7] === void 0 ? 1 : Number(r2[7]) / (r2[8] ? 100 : 1) }) : { h: 0, s: 0, v: 0, a: 1 }; }; var D = function(e2) { var r2 = e2.toString(16); return r2.length < 2 ? "0" + r2 : r2; }, K = function(e2) { var r2 = e2.r, t2 = e2.g, n2 = e2.b, o2 = e2.a, a2 = o2 < 1 ? D(b(255 * o2)) : ""; return "#" + D(r2) + D(t2) + D(n2) + a2; }, L = function(e2) { var r2 = e2.r, t2 = e2.g, n2 = e2.b, o2 = e2.a, a2 = Math.max(r2, t2, n2), l2 = a2 - Math.min(r2, t2, n2), u2 = l2 ? a2 === r2 ? (t2 - n2) / l2 : a2 === t2 ? 2 + (n2 - r2) / l2 : 4 + (r2 - t2) / l2 : 0; return { h: b(60 * (u2 < 0 ? u2 + 6 : u2)), s: b(a2 ? l2 / a2 * 100 : 0), v: b(a2 / 255 * 100), a: o2 }; }; var S = e.memo(function(r2) { var t2 = r2.hue, n2 = r2.onChange, o2 = g(["react-colorful__hue", r2.className]); return e.createElement("div", { className: o2 }, e.createElement(m, { onMove: function(e2) { n2({ h: 360 * e2.left }); }, onKey: function(e2) { n2({ h: s(t2 + 360 * e2.left, 0, 360) }); }, "aria-label": "Hue", "aria-valuenow": b(t2), "aria-valuemax": "360", "aria-valuemin": "0" }, e.createElement(p, { className: "react-colorful__hue-pointer", left: t2 / 360, color: q({ h: t2, s: 100, v: 100, a: 1 }) }))); }), T = e.memo(function(r2) { var t2 = r2.hsva, n2 = r2.onChange, o2 = { backgroundColor: q({ h: t2.h, s: 100, v: 100, a: 1 }) }; return e.createElement("div", { className: "react-colorful__saturation", style: o2 }, e.createElement(m, { onMove: function(e2) { n2({ s: 100 * e2.left, v: 100 - 100 * e2.top }); }, onKey: function(e2) { n2({ s: s(t2.s + 100 * e2.left, 0, 100), v: s(t2.v - 100 * e2.top, 0, 100) }); }, "aria-label": "Color", "aria-valuetext": "Saturation " + b(t2.s) + "%, Brightness " + b(t2.v) + "%" }, e.createElement(p, { className: "react-colorful__saturation-pointer", top: 1 - t2.v / 100, left: t2.s / 100, color: q(t2) }))); }), F = function(e2, r2) { if (e2 === r2) return !0; for (var t2 in e2) if (e2[t2] !== r2[t2]) return !1; return !0; }, P = function(e2, r2) { return e2.replace(/\s/g, "") === r2.replace(/\s/g, ""); }, X = function(e2, r2) { return e2.toLowerCase() === r2.toLowerCase() || F(C(e2), C(r2)); }; function Y(e2, t2, l2) { var u2 = i(l2), c2 = o(function() { return e2.toHsva(t2); }), s2 = c2[0], f2 = c2[1], v2 = r({ color: t2, hsva: s2 }); n(function() { if (!e2.equal(t2, v2.current.color)) { var r2 = e2.toHsva(t2); v2.current = { hsva: r2, color: t2 }, f2(r2); } }, [t2, e2]), n(function() { var r2; F(s2, v2.current.hsva) || e2.equal(r2 = e2.fromHsva(s2), v2.current.color) || (v2.current = { hsva: s2, color: r2 }, u2(r2)); }, [s2, e2, u2]); var d2 = a(function(e3) { f2(function(r2) { return Object.assign({}, r2, e3); }); }, []); return [s2, d2]; } var R, V = typeof window < "u" ? l : n, $ = function() { return R || (typeof __webpack_nonce__ < "u" ? __webpack_nonce__ : void 0); }; var J = /* @__PURE__ */ new Map(), Q = function(e2) { V(function() { var r2 = e2.current ? e2.current.ownerDocument : document; if (r2 !== void 0 && !J.has(r2)) { var t2 = r2.createElement("style"); t2.innerHTML = `.react-colorful{position:relative;display:flex;flex-direction:column;width:200px;height:200px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.react-colorful__saturation{position:relative;flex-grow:1;border-color:transparent;border-bottom:12px solid #000;border-radius:8px 8px 0 0;background-image:linear-gradient(0deg,#000,transparent),linear-gradient(90deg,#fff,hsla(0,0%,100%,0))}.react-colorful__alpha-gradient,.react-colorful__pointer-fill{content:"";position:absolute;left:0;top:0;right:0;bottom:0;pointer-events:none;border-radius:inherit}.react-colorful__alpha-gradient,.react-colorful__saturation{box-shadow:inset 0 0 0 1px rgba(0,0,0,.05)}.react-colorful__alpha,.react-colorful__hue{position:relative;height:24px}.react-colorful__hue{background:linear-gradient(90deg,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red)}.react-colorful__last-control{border-radius:0 0 8px 8px}.react-colorful__interactive{position:absolute;left:0;top:0;right:0;bottom:0;border-radius:inherit;outline:none;touch-action:none}.react-colorful__pointer{position:absolute;z-index:1;box-sizing:border-box;width:28px;height:28px;transform:translate(-50%,-50%);background-color:#fff;border:2px solid #fff;border-radius:50%;box-shadow:0 2px 4px rgba(0,0,0,.2)}.react-colorful__interactive:focus .react-colorful__pointer{transform:translate(-50%,-50%) scale(1.1)}.react-colorful__alpha,.react-colorful__alpha-pointer{background-color:#fff;background-image:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill-opacity=".05"><path d="M8 0h8v8H8zM0 8h8v8H0z"/></svg>')}.react-colorful__saturation-pointer{z-index:3}.react-colorful__hue-pointer{z-index:2}`, J.set(r2, t2); var n2 = $(); n2 && t2.setAttribute("nonce", n2), r2.head.appendChild(t2); } }, []); }, U = function(t2) { var n2 = t2.className, o2 = t2.colorModel, a2 = t2.color, l2 = a2 === void 0 ? o2.defaultColor : a2, i2 = t2.onChange, s2 = c(t2, ["className", "colorModel", "color", "onChange"]), f2 = r(null); Q(f2); var v2 = Y(o2, l2, i2), d2 = v2[0], h2 = v2[1], m2 = g(["react-colorful", n2]); return e.createElement("div", u({}, s2, { ref: f2, className: m2 }), e.createElement(T, { hsva: d2, onChange: h2 }), e.createElement(S, { hue: d2.h, onChange: h2, className: "react-colorful__last-control" })); }, W = { defaultColor: "000", toHsva: x, fromHsva: function(e2) { return w({ h: e2.h, s: e2.s, v: e2.v, a: 1 }); }, equal: X }, Z = function(r2) { return e.createElement(U, u({}, r2, { colorModel: W })); }, ee = function(r2) { var t2 = r2.className, n2 = r2.hsva, o2 = r2.onChange, a2 = { backgroundImage: "linear-gradient(90deg, " + k(Object.assign({}, n2, { a: 0 })) + ", " + k(Object.assign({}, n2, { a: 1 })) + ")" }, l2 = g(["react-colorful__alpha", t2]), u2 = b(100 * n2.a); return e.createElement("div", { className: l2 }, e.createElement("div", { className: "react-colorful__alpha-gradient", style: a2 }), e.createElement(m, { onMove: function(e2) { o2({ a: e2.left }); }, onKey: function(e2) { o2({ a: s(n2.a + e2.left) }); }, "aria-label": "Alpha", "aria-valuetext": u2 + "%", "aria-valuenow": u2, "aria-valuemin": "0", "aria-valuemax": "100" }, e.createElement(p, { className: "react-colorful__alpha-pointer", left: n2.a, color: k(n2) }))); }, re = function(t2) { var n2 = t2.className, o2 = t2.colorModel, a2 = t2.color, l2 = a2 === void 0 ? o2.defaultColor : a2, i2 = t2.onChange, s2 = c(t2, ["className", "colorModel", "color", "onChange"]), f2 = r(null); Q(f2); var v2 = Y(o2, l2, i2), d2 = v2[0], h2 = v2[1], m2 = g(["react-colorful", n2]); return e.createElement("div", u({}, s2, { ref: f2, className: m2 }), e.createElement(T, { hsva: d2, onChange: h2 }), e.createElement(S, { hue: d2.h, onChange: h2 }), e.createElement(ee, { hsva: d2, onChange: h2, className: "react-colorful__last-control" })); }; var le = { defaultColor: "hsla(0, 0%, 0%, 1)", toHsva: H, fromHsva: k, equal: P }, ue = function(r2) { return e.createElement(re, u({}, r2, { colorModel: le })); }; var Ee = { defaultColor: "rgba(0, 0, 0, 1)", toHsva: z, fromHsva: function(e2) { var r2 = I(e2); return "rgba(" + r2.r + ", " + r2.g + ", " + r2.b + ", " + r2.a + ")"; }, equal: P }, He = function(r2) { return e.createElement(re, u({}, r2, { colorModel: Ee })); }; // ../addons/docs/src/blocks/controls/Color.tsx import { styled } from "storybook/theming"; var Wrapper = styled.div({ position: "relative", maxWidth: 250 }), TooltipContent = styled.div({ width: 200, margin: 5, ".react-colorful__saturation": { borderRadius: "4px 4px 0 0" }, ".react-colorful__hue": { boxShadow: "inset 0 0 0 1px rgb(0 0 0 / 5%)" }, ".react-colorful__last-control": { borderRadius: "0 0 4px 4px" } }), Swatches = styled.div({ display: "grid", gridTemplateColumns: "repeat(9, 16px)", gap: 6, padding: 3, marginTop: 5, width: 200 }), swatchBackground = (isDark) => `url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill-opacity="0.05" fill="${isDark ? "white" : "black"}"><path d="M8 0h8v8H8zM0 8h8v8H0z"/></svg>')`, SwatchColor = styled(Button)( ({ value, selected, theme }) => ({ width: 16, height: 16, boxShadow: selected ? `${theme.appBorderColor} 0 0 0 1px inset, ${theme.textMutedColor}50 0 0 0 4px` : `${theme.appBorderColor} 0 0 0 1px inset`, border: "none", borderRadius: theme.appBorderRadius, "&, &:hover": { background: "unset", backgroundColor: "unset", backgroundImage: `linear-gradient(${value}, ${value}), ${swatchBackground(theme.base === "dark")}` } }) ), Input = styled(Form.Input)(({ theme }) => ({ width: "100%", paddingLeft: 30, paddingRight: 30, boxSizing: "border-box", fontFamily: theme.typography.fonts.base, '[aria-readonly="true"] > &': { background: theme.base === "light" ? theme.color.lighter : "transparent" } })), PopoverTrigger = styled(SwatchColor)(({ disabled }) => ({ position: "absolute", top: 4, left: 4, zIndex: 1, cursor: disabled ? "not-allowed" : "pointer" })), CycleColorSpaceButton = styled(Button)(({ theme }) => ({ position: "absolute", zIndex: 1, top: 6, right: 7, width: 20, height: 20, padding: 4, boxSizing: "border-box", cursor: "pointer", color: theme.input.color })), ColorSpace = /* @__PURE__ */ ((ColorSpace2) => (ColorSpace2.RGB = "rgb", ColorSpace2.HSL = "hsl", ColorSpace2.HEX = "hex", ColorSpace2))(ColorSpace || {}), COLOR_SPACES = Object.values(ColorSpace), COLOR_REGEXP = /\(([0-9]+),\s*([0-9]+)%?,\s*([0-9]+)%?,?\s*([0-9.]+)?\)/, RGB_REGEXP = /^\s*rgba?\(([0-9]+),\s*([0-9]+),\s*([0-9]+),?\s*([0-9.]+)?\)\s*$/i, HSL_REGEXP = /^\s*hsla?\(([0-9]+),\s*([0-9]+)%,\s*([0-9]+)%,?\s*([0-9.]+)?\)\s*$/i, HEX_REGEXP = /^\s*#?([0-9a-f]{3}|[0-9a-f]{6})\s*$/i, SHORTHEX_REGEXP = /^\s*#?([0-9a-f]{3})\s*$/i, ColorPicker = { hex: Z, rgb: He, hsl: ue }, fallbackColor = { hex: "transparent", rgb: "rgba(0, 0, 0, 0)", hsl: "hsla(0, 0%, 0%, 0)" }, stringToArgs = (value) => { let match = value?.match(COLOR_REGEXP); if (!match) return [0, 0, 0, 1]; let [, x2, y2, z2, a2 = 1] = match; return [x2, y2, z2, a2].map(Number); }, parseRgb = (value) => { let [r2, g2, b2, a2] = stringToArgs(value), [h2, s2, l2] = import_color_convert.default.rgb.hsl([r2, g2, b2]) || [0, 0, 0]; return { valid: !0, value, keyword: import_color_convert.default.rgb.keyword([r2, g2, b2]), colorSpace: "rgb" /* RGB */, rgb: value, hsl: `hsla(${h2}, ${s2}%, ${l2}%, ${a2})`, hex: `#${import_color_convert.default.rgb.hex([r2, g2, b2]).toLowerCase()}` }; }, parseHsl = (value) => { let [h2, s2, l2, a2] = stringToArgs(value), [r2, g2, b2] = import_color_convert.default.hsl.rgb([h2, s2, l2]) || [0, 0, 0]; return { valid: !0, value, keyword: import_color_convert.default.hsl.keyword([h2, s2, l2]), colorSpace: "hsl" /* HSL */, rgb: `rgba(${r2}, ${g2}, ${b2}, ${a2})`, hsl: value, hex: `#${import_color_convert.default.hsl.hex([h2, s2, l2]).toLowerCase()}` }; }, parseHexOrKeyword = (value) => { let plain = value.replace("#", ""), rgb = import_color_convert.default.keyword.rgb(plain) || import_color_convert.default.hex.rgb(plain), hsl = import_color_convert.default.rgb.hsl(rgb), mapped = value; /[^#a-f0-9]/i.test(value) ? mapped = plain : HEX_REGEXP.test(value) && (mapped = `#${plain}`); let valid = !0; if (mapped.startsWith("#")) valid = HEX_REGEXP.test(mapped); else try { import_color_convert.default.keyword.hex(mapped); } catch { valid = !1; } return { valid, value: mapped, keyword: import_color_convert.default.rgb.keyword(rgb), colorSpace: "hex" /* HEX */, rgb: `rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]}, 1)`, hsl: `hsla(${hsl[0]}, ${hsl[1]}%, ${hsl[2]}%, 1)`, hex: mapped }; }, parseValue = (value) => { if (value) return RGB_REGEXP.test(value) ? parseRgb(value) : HSL_REGEXP.test(value) ? parseHsl(value) : parseHexOrKeyword(value); }, getRealValue = (value, color, colorSpace) => { if (!value || !color?.valid) return fallbackColor[colorSpace]; if (colorSpace !== "hex" /* HEX */) return color?.[colorSpace] || fallbackColor[colorSpace]; if (!color.hex.startsWith("#")) try { return `#${import_color_convert.default.keyword.hex(color.hex)}`; } catch { return fallbackColor.hex; } let short = color.hex.match(SHORTHEX_REGEXP); if (!short) return HEX_REGEXP.test(color.hex) ? color.hex : fallbackColor.hex; let [r2, g2, b2] = short[1].split(""); return `#${r2}${r2}${g2}${g2}${b2}${b2}`; }, useColorInput = (initialValue, onChange) => { let [value, setValue] = useState(initialValue || ""), [color, setColor] = useState(() => parseValue(value)), [colorSpace, setColorSpace] = useState(color?.colorSpace || "hex" /* HEX */); useEffect(() => { let nextValue = initialValue || "", nextColor = parseValue(nextValue); setValue(nextValue), setColor(nextColor), setColorSpace(nextColor?.colorSpace || "hex" /* HEX */); }, [initialValue]); let realValue = useMemo( () => getRealValue(value, color, colorSpace).toLowerCase(), [value, color, colorSpace] ), updateValue = useCallback( (update) => { let parsed = parseValue(update), v2 = parsed?.value || update || ""; setValue(v2), v2 === "" && (setColor(void 0), onChange(void 0)), parsed && (setColor(parsed), setColorSpace(parsed.colorSpace), onChange(parsed.value)); }, [onChange] ), cycleColorSpace = useCallback(() => { let nextIndex = (COLOR_SPACES.indexOf(colorSpace) + 1) % COLOR_SPACES.length, nextSpace = COLOR_SPACES[nextIndex]; setColorSpace(nextSpace); let updatedValue = color?.[nextSpace] || ""; setValue(updatedValue), onChange(updatedValue); }, [color, colorSpace, onChange]); return { value, realValue, updateValue, color, colorSpace, cycleColorSpace }; }, id = (value) => value.replace(/\s*/, "").toLowerCase(), usePresets = (presetColors, currentColor, colorSpace) => { let [selectedColors, setSelectedColors] = useState(currentColor?.valid ? [currentColor] : []); useEffect(() => { currentColor === void 0 && setSelectedColors([]); }, [currentColor]); let presets = useMemo(() => (presetColors || []).map((preset) => typeof preset == "string" ? parseValue(preset) : preset.title ? { ...parseValue(preset.color), keyword: preset.title } : parseValue(preset.color)).concat(selectedColors).filter(Boolean).slice(-27), [presetColors, selectedColors]), addPreset = useCallback( (color) => { color?.valid && (presets.some( (preset) => preset && preset[colorSpace] && id(preset[colorSpace] || "") === id(color[colorSpace] || "") ) || setSelectedColors((arr) => arr.concat(color))); }, [colorSpace, presets] ); return { presets, addPreset }; }, ColorControl = ({ name, value: initialValue, onChange, onFocus, onBlur, presetColors, startOpen = !1, argType }) => { let debouncedOnChange = useCallback(debounce(onChange, 200), [onChange]), { value, realValue, updateValue, color, colorSpace, cycleColorSpace } = useColorInput( initialValue, debouncedOnChange ), { presets, addPreset } = usePresets(presetColors ?? [], color, colorSpace), Picker = ColorPicker[colorSpace], readOnly = !!argType?.table?.readonly, controlId = getControlId(name); return React.createElement(Wrapper, null, React.createElement("label", { htmlFor: controlId, className: "sb-sr-only" }, name), React.createElement( Input, { id: controlId, value, onChange: (e2) => updateValue(e2.target.value), onFocus: (e2) => e2.target.select(), readOnly, placeholder: "Choose color..." } ), React.createElement( PopoverProvider, { defaultVisible: startOpen, visible: readOnly ? !1 : void 0, onVisibleChange: () => color && addPreset(color), popover: React.createElement(TooltipContent, null, React.createElement( Picker, { color: realValue === "transparent" ? "#000000" : realValue, onChange: updateValue, onFocus, onBlur } ), presets.length > 0 && React.createElement(Swatches, null, presets.map((preset, index) => React.createElement( SwatchColor, { key: `${preset?.value || index}-${index}`, variant: "ghost", padding: "small", size: "small", ariaLabel: "Pick this color", tooltip: preset?.keyword || preset?.value || "", value: preset?.value || "", selected: !!(color && preset && preset[colorSpace] && id(preset[colorSpace] || "") === id(color[colorSpace])), onClick: () => preset && updateValue(preset.value || "") } )))) }, React.createElement( PopoverTrigger, { variant: "ghost", padding: "small", size: "small", ariaLabel: "Open color picker", value: realValue, style: { margin: 4 }, disabled: readOnly } ) ), value ? React.createElement( CycleColorSpaceButton, { variant: "ghost", padding: "small", size: "small", ariaLabel: "Cycle through color spaces", disabled: readOnly, onClick: readOnly ? void 0 : cycleColorSpace }, React.createElement(MarkupIcon, null) ) : null); }, Color_default = ColorControl; export { ColorControl, Color_default as default };