chroma-panel 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +44 -0
- package/README.md +119 -0
- package/dist/_virtual/_rolldown/runtime.cjs +23 -0
- package/dist/a11y/contrast.cjs +107 -0
- package/dist/a11y/contrast.d.cts +34 -0
- package/dist/a11y/contrast.d.ts +34 -0
- package/dist/a11y/contrast.js +101 -0
- package/dist/color/convert.cjs +162 -0
- package/dist/color/convert.d.cts +16 -0
- package/dist/color/convert.d.ts +16 -0
- package/dist/color/convert.js +153 -0
- package/dist/color/parse.cjs +153 -0
- package/dist/color/parse.d.cts +7 -0
- package/dist/color/parse.d.ts +7 -0
- package/dist/color/parse.js +151 -0
- package/dist/color/serialize.cjs +79 -0
- package/dist/color/serialize.d.cts +11 -0
- package/dist/color/serialize.d.ts +11 -0
- package/dist/color/serialize.js +73 -0
- package/dist/color/sticky.cjs +20 -0
- package/dist/color/sticky.d.cts +6 -0
- package/dist/color/sticky.d.ts +6 -0
- package/dist/color/sticky.js +19 -0
- package/dist/color/types.d.cts +43 -0
- package/dist/color/types.d.ts +43 -0
- package/dist/components/ChromaPanel.cjs +254 -0
- package/dist/components/ChromaPanel.d.cts +47 -0
- package/dist/components/ChromaPanel.d.ts +47 -0
- package/dist/components/ChromaPanel.js +251 -0
- package/dist/components/ColorInput.cjs +128 -0
- package/dist/components/ColorInput.d.cts +19 -0
- package/dist/components/ColorInput.d.ts +19 -0
- package/dist/components/ColorInput.js +127 -0
- package/dist/components/ModeToolbar.cjs +33 -0
- package/dist/components/ModeToolbar.d.cts +10 -0
- package/dist/components/ModeToolbar.d.ts +10 -0
- package/dist/components/ModeToolbar.js +32 -0
- package/dist/components/PanelFooter.cjs +82 -0
- package/dist/components/PanelFooter.d.cts +5 -0
- package/dist/components/PanelFooter.d.ts +5 -0
- package/dist/components/PanelFooter.js +80 -0
- package/dist/components/Popover.cjs +154 -0
- package/dist/components/Popover.d.cts +13 -0
- package/dist/components/Popover.d.ts +13 -0
- package/dist/components/Popover.js +153 -0
- package/dist/contrast.cjs +10 -0
- package/dist/contrast.d.cts +2 -0
- package/dist/contrast.d.ts +2 -0
- package/dist/contrast.js +2 -0
- package/dist/core/context.cjs +30 -0
- package/dist/core/context.d.cts +43 -0
- package/dist/core/context.d.ts +43 -0
- package/dist/core/context.js +26 -0
- package/dist/core/dev.cjs +11 -0
- package/dist/core/dev.js +11 -0
- package/dist/core/store.cjs +43 -0
- package/dist/core/store.d.cts +17 -0
- package/dist/core/store.d.ts +17 -0
- package/dist/core/store.js +44 -0
- package/dist/core/styleInjector.cjs +38 -0
- package/dist/core/styleInjector.d.cts +4 -0
- package/dist/core/styleInjector.d.ts +4 -0
- package/dist/core/styleInjector.js +38 -0
- package/dist/core/useColorStore.cjs +43 -0
- package/dist/core/useColorStore.d.cts +6 -0
- package/dist/core/useColorStore.d.ts +6 -0
- package/dist/core/useColorStore.js +41 -0
- package/dist/core/useFormControl.cjs +87 -0
- package/dist/core/useFormControl.js +82 -0
- package/dist/core/useMediaQuery.cjs +48 -0
- package/dist/core/useMediaQuery.js +46 -0
- package/dist/core/usePointerDrag.cjs +177 -0
- package/dist/core/usePointerDrag.d.cts +35 -0
- package/dist/core/usePointerDrag.d.ts +35 -0
- package/dist/core/usePointerDrag.js +175 -0
- package/dist/core/useScrollFade.cjs +44 -0
- package/dist/core/useScrollFade.js +43 -0
- package/dist/core.cjs +33 -0
- package/dist/core.d.cts +7 -0
- package/dist/core.d.ts +7 -0
- package/dist/core.js +6 -0
- package/dist/data/defaults.cjs +123 -0
- package/dist/data/defaults.d.cts +6 -0
- package/dist/data/defaults.d.ts +6 -0
- package/dist/data/defaults.js +122 -0
- package/dist/data/namedColors.cjs +11 -0
- package/dist/data/namedColors.d.cts +3 -0
- package/dist/data/namedColors.d.ts +3 -0
- package/dist/data/namedColors.js +12 -0
- package/dist/image/extract.cjs +98 -0
- package/dist/image/extract.d.cts +16 -0
- package/dist/image/extract.d.ts +16 -0
- package/dist/image/extract.js +99 -0
- package/dist/image/mmcq.cjs +182 -0
- package/dist/image/mmcq.d.cts +8 -0
- package/dist/image/mmcq.d.ts +8 -0
- package/dist/image/mmcq.js +183 -0
- package/dist/image-worker.js +202 -0
- package/dist/image.cjs +12 -0
- package/dist/image.d.cts +4 -0
- package/dist/image.d.ts +4 -0
- package/dist/image.js +9 -0
- package/dist/index.cjs +119 -0
- package/dist/index.d.cts +36 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.js +44 -0
- package/dist/modes/gradients.cjs +48 -0
- package/dist/modes/gradients.js +43 -0
- package/dist/modes/image/index.cjs +193 -0
- package/dist/modes/image/index.d.cts +10 -0
- package/dist/modes/image/index.d.ts +10 -0
- package/dist/modes/image/index.js +191 -0
- package/dist/modes/palettes/index.cjs +76 -0
- package/dist/modes/palettes/index.d.cts +6 -0
- package/dist/modes/palettes/index.d.ts +6 -0
- package/dist/modes/palettes/index.js +74 -0
- package/dist/modes/pencils/index.cjs +36 -0
- package/dist/modes/pencils/index.d.cts +6 -0
- package/dist/modes/pencils/index.d.ts +6 -0
- package/dist/modes/pencils/index.js +34 -0
- package/dist/modes/registry.cjs +26 -0
- package/dist/modes/registry.d.cts +13 -0
- package/dist/modes/registry.d.ts +13 -0
- package/dist/modes/registry.js +25 -0
- package/dist/modes/sliders/index.cjs +300 -0
- package/dist/modes/sliders/index.d.cts +6 -0
- package/dist/modes/sliders/index.d.ts +6 -0
- package/dist/modes/sliders/index.js +298 -0
- package/dist/modes/wheel/index.cjs +62 -0
- package/dist/modes/wheel/index.d.cts +6 -0
- package/dist/modes/wheel/index.d.ts +6 -0
- package/dist/modes/wheel/index.js +60 -0
- package/dist/named-colors.cjs +3 -0
- package/dist/named-colors.d.cts +2 -0
- package/dist/named-colors.d.ts +2 -0
- package/dist/named-colors.js +2 -0
- package/dist/palettes.cjs +8 -0
- package/dist/palettes.d.cts +2 -0
- package/dist/palettes.d.ts +2 -0
- package/dist/palettes.js +7 -0
- package/dist/panel.cjs +80 -0
- package/dist/panel.d.cts +27 -0
- package/dist/panel.d.ts +27 -0
- package/dist/panel.js +27 -0
- package/dist/pencils.cjs +8 -0
- package/dist/pencils.d.cts +2 -0
- package/dist/pencils.d.ts +2 -0
- package/dist/pencils.js +7 -0
- package/dist/primitives/AxisInput.cjs +26 -0
- package/dist/primitives/AxisInput.js +25 -0
- package/dist/primitives/ChannelSlider.cjs +94 -0
- package/dist/primitives/ChannelSlider.d.cts +18 -0
- package/dist/primitives/ChannelSlider.d.ts +18 -0
- package/dist/primitives/ChannelSlider.js +93 -0
- package/dist/primitives/ColorArea.cjs +85 -0
- package/dist/primitives/ColorArea.d.cts +8 -0
- package/dist/primitives/ColorArea.d.ts +8 -0
- package/dist/primitives/ColorArea.js +84 -0
- package/dist/primitives/ColorDisc.cjs +95 -0
- package/dist/primitives/ColorDisc.d.cts +8 -0
- package/dist/primitives/ColorDisc.d.ts +8 -0
- package/dist/primitives/ColorDisc.js +94 -0
- package/dist/primitives/ColorField.cjs +68 -0
- package/dist/primitives/ColorField.d.cts +9 -0
- package/dist/primitives/ColorField.d.ts +9 -0
- package/dist/primitives/ColorField.js +67 -0
- package/dist/primitives/NumberField.cjs +65 -0
- package/dist/primitives/NumberField.d.cts +14 -0
- package/dist/primitives/NumberField.d.ts +14 -0
- package/dist/primitives/NumberField.js +64 -0
- package/dist/primitives/SegmentedControl.cjs +66 -0
- package/dist/primitives/SegmentedControl.d.cts +21 -0
- package/dist/primitives/SegmentedControl.d.ts +21 -0
- package/dist/primitives/SegmentedControl.js +65 -0
- package/dist/primitives/Swatch.cjs +22 -0
- package/dist/primitives/Swatch.d.cts +13 -0
- package/dist/primitives/Swatch.d.ts +13 -0
- package/dist/primitives/Swatch.js +21 -0
- package/dist/primitives/SwatchGrid.cjs +63 -0
- package/dist/primitives/SwatchGrid.d.cts +17 -0
- package/dist/primitives/SwatchGrid.d.ts +17 -0
- package/dist/primitives/SwatchGrid.js +62 -0
- package/dist/primitives/icons.cjs +149 -0
- package/dist/primitives/icons.d.cts +9 -0
- package/dist/primitives/icons.d.ts +9 -0
- package/dist/primitives/icons.js +141 -0
- package/dist/primitives/useEyedropper.cjs +30 -0
- package/dist/primitives/useEyedropper.d.cts +7 -0
- package/dist/primitives/useEyedropper.d.ts +7 -0
- package/dist/primitives/useEyedropper.js +29 -0
- package/dist/sliders.cjs +8 -0
- package/dist/sliders.d.cts +2 -0
- package/dist/sliders.d.ts +2 -0
- package/dist/sliders.js +7 -0
- package/dist/style.css +2 -0
- package/dist/styles/css.cjs +4 -0
- package/dist/styles/css.js +5 -0
- package/dist/wheel.cjs +8 -0
- package/dist/wheel.d.cts +2 -0
- package/dist/wheel.d.ts +2 -0
- package/dist/wheel.js +7 -0
- package/package.json +222 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cx, usePanel } from "../core/context.js";
|
|
3
|
+
import { clamp } from "../color/convert.js";
|
|
4
|
+
import { useTransientColor } from "../core/useColorStore.js";
|
|
5
|
+
import { usePointerDrag } from "../core/usePointerDrag.js";
|
|
6
|
+
import { AxisInput } from "./AxisInput.js";
|
|
7
|
+
import * as React from "react";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
//#region src/primitives/ChannelSlider.tsx
|
|
10
|
+
function ChannelSlider(props) {
|
|
11
|
+
const { label, shortLabel, min, max, step, read, write, gradient, channel, formatValue, className } = props;
|
|
12
|
+
const { store, disabled, classNames } = usePanel();
|
|
13
|
+
const trackRef = React.useRef(null);
|
|
14
|
+
const fillRef = React.useRef(null);
|
|
15
|
+
const inputRef = React.useRef(null);
|
|
16
|
+
const fns = React.useRef({
|
|
17
|
+
read,
|
|
18
|
+
gradient,
|
|
19
|
+
formatValue
|
|
20
|
+
});
|
|
21
|
+
React.useEffect(() => {
|
|
22
|
+
fns.current = {
|
|
23
|
+
read,
|
|
24
|
+
gradient,
|
|
25
|
+
formatValue
|
|
26
|
+
};
|
|
27
|
+
});
|
|
28
|
+
useTransientColor(store, (c) => {
|
|
29
|
+
const value = fns.current.read(c);
|
|
30
|
+
const ratio = max === min ? 0 : clamp((value - min) / (max - min), 0, 1);
|
|
31
|
+
const track = trackRef.current;
|
|
32
|
+
if (track !== null) track.style.setProperty("--cp-thumb-x", `${ratio * 100}%`);
|
|
33
|
+
const fill = fillRef.current;
|
|
34
|
+
const g = fns.current.gradient;
|
|
35
|
+
if (fill !== null && g !== void 0) fill.style.background = g(c);
|
|
36
|
+
const input = inputRef.current;
|
|
37
|
+
if (input !== null) {
|
|
38
|
+
input.value = String(value);
|
|
39
|
+
const text = fns.current.formatValue?.(value) ?? String(Math.round(value));
|
|
40
|
+
input.setAttribute("aria-valuetext", `${label} ${text}`);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
const drag = usePointerDrag({
|
|
44
|
+
disabled,
|
|
45
|
+
onMove: ({ x }) => store.set(write(min + x * (max - min), store.get())),
|
|
46
|
+
onEnd: () => store.commit()
|
|
47
|
+
});
|
|
48
|
+
const initial = read(store.get());
|
|
49
|
+
const track = /* @__PURE__ */ jsxs("div", {
|
|
50
|
+
ref: trackRef,
|
|
51
|
+
className: cx("cp-slider", classNames.slider, className),
|
|
52
|
+
"data-cp-channel": channel,
|
|
53
|
+
style: drag.style,
|
|
54
|
+
onPointerDown: drag.onPointerDown,
|
|
55
|
+
onPointerMove: drag.onPointerMove,
|
|
56
|
+
onPointerUp: drag.onPointerUp,
|
|
57
|
+
onLostPointerCapture: drag.onLostPointerCapture,
|
|
58
|
+
children: [
|
|
59
|
+
/* @__PURE__ */ jsx("div", {
|
|
60
|
+
ref: fillRef,
|
|
61
|
+
className: "cp-slider-fill",
|
|
62
|
+
"aria-hidden": "true"
|
|
63
|
+
}),
|
|
64
|
+
/* @__PURE__ */ jsx(AxisInput, {
|
|
65
|
+
ref: inputRef,
|
|
66
|
+
label,
|
|
67
|
+
min,
|
|
68
|
+
max,
|
|
69
|
+
step: step ?? 1,
|
|
70
|
+
defaultValue: initial,
|
|
71
|
+
disabled,
|
|
72
|
+
onInput: (v) => store.set(write(v, store.get())),
|
|
73
|
+
onCommit: () => store.commit()
|
|
74
|
+
}),
|
|
75
|
+
/* @__PURE__ */ jsx("div", {
|
|
76
|
+
className: cx("cp-thumb", classNames.thumb),
|
|
77
|
+
"aria-hidden": "true"
|
|
78
|
+
})
|
|
79
|
+
]
|
|
80
|
+
});
|
|
81
|
+
if (shortLabel === void 0) return track;
|
|
82
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
83
|
+
className: "cp-slider-row",
|
|
84
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
85
|
+
className: "cp-slider-label",
|
|
86
|
+
"aria-hidden": "true",
|
|
87
|
+
children: shortLabel
|
|
88
|
+
}), track]
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
//#endregion
|
|
92
|
+
export { ChannelSlider };
|
|
93
|
+
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
const require_context = require("../core/context.cjs");
|
|
4
|
+
const require_useColorStore = require("../core/useColorStore.cjs");
|
|
5
|
+
const require_usePointerDrag = require("../core/usePointerDrag.cjs");
|
|
6
|
+
const require_AxisInput = require("./AxisInput.cjs");
|
|
7
|
+
let react = require("react");
|
|
8
|
+
react = require_runtime.__toESM(react, 1);
|
|
9
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
10
|
+
//#region src/primitives/ColorArea.tsx
|
|
11
|
+
function ColorArea(props) {
|
|
12
|
+
const { height = 150, className } = props;
|
|
13
|
+
const { store, disabled, classNames } = require_context.usePanel();
|
|
14
|
+
const areaRef = react.useRef(null);
|
|
15
|
+
const satRef = react.useRef(null);
|
|
16
|
+
const valRef = react.useRef(null);
|
|
17
|
+
require_useColorStore.useTransientColor(store, (c) => {
|
|
18
|
+
const el = areaRef.current;
|
|
19
|
+
if (el === null) return;
|
|
20
|
+
el.style.setProperty("--cp-thumb-x", `${c.s}%`);
|
|
21
|
+
el.style.setProperty("--cp-thumb-y", `${100 - c.v}%`);
|
|
22
|
+
const sat = satRef.current;
|
|
23
|
+
if (sat !== null) {
|
|
24
|
+
sat.value = String(Math.round(c.s));
|
|
25
|
+
sat.setAttribute("aria-valuetext", `Saturation ${Math.round(c.s)} percent`);
|
|
26
|
+
}
|
|
27
|
+
const val = valRef.current;
|
|
28
|
+
if (val !== null) {
|
|
29
|
+
val.value = String(Math.round(c.v));
|
|
30
|
+
val.setAttribute("aria-valuetext", `Brightness ${Math.round(c.v)} percent`);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
const drag = require_usePointerDrag.usePointerDrag({
|
|
34
|
+
disabled,
|
|
35
|
+
onMove: ({ x, y }) => store.patch({
|
|
36
|
+
s: x * 100,
|
|
37
|
+
v: (1 - y) * 100
|
|
38
|
+
}),
|
|
39
|
+
onEnd: () => store.commit()
|
|
40
|
+
});
|
|
41
|
+
const initial = store.get();
|
|
42
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
43
|
+
ref: areaRef,
|
|
44
|
+
className: require_context.cx("cp-area", className),
|
|
45
|
+
style: {
|
|
46
|
+
...drag.style,
|
|
47
|
+
height
|
|
48
|
+
},
|
|
49
|
+
onPointerDown: drag.onPointerDown,
|
|
50
|
+
onPointerMove: drag.onPointerMove,
|
|
51
|
+
onPointerUp: drag.onPointerUp,
|
|
52
|
+
onLostPointerCapture: drag.onLostPointerCapture,
|
|
53
|
+
role: "group",
|
|
54
|
+
"aria-label": "Saturation and brightness",
|
|
55
|
+
"aria-disabled": disabled || void 0,
|
|
56
|
+
children: [
|
|
57
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_AxisInput.AxisInput, {
|
|
58
|
+
ref: satRef,
|
|
59
|
+
label: "Saturation",
|
|
60
|
+
min: 0,
|
|
61
|
+
max: 100,
|
|
62
|
+
defaultValue: Math.round(initial.s),
|
|
63
|
+
disabled,
|
|
64
|
+
onInput: (s) => store.patch({ s }),
|
|
65
|
+
onCommit: () => store.commit()
|
|
66
|
+
}),
|
|
67
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_AxisInput.AxisInput, {
|
|
68
|
+
ref: valRef,
|
|
69
|
+
label: "Brightness",
|
|
70
|
+
min: 0,
|
|
71
|
+
max: 100,
|
|
72
|
+
defaultValue: Math.round(initial.v),
|
|
73
|
+
disabled,
|
|
74
|
+
onInput: (v) => store.patch({ v }),
|
|
75
|
+
onCommit: () => store.commit()
|
|
76
|
+
}),
|
|
77
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
78
|
+
className: require_context.cx("cp-thumb", classNames.thumb),
|
|
79
|
+
"aria-hidden": "true"
|
|
80
|
+
})
|
|
81
|
+
]
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
//#endregion
|
|
85
|
+
exports.ColorArea = ColorArea;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cx, usePanel } from "../core/context.js";
|
|
3
|
+
import { useTransientColor } from "../core/useColorStore.js";
|
|
4
|
+
import { usePointerDrag } from "../core/usePointerDrag.js";
|
|
5
|
+
import { AxisInput } from "./AxisInput.js";
|
|
6
|
+
import * as React from "react";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
//#region src/primitives/ColorArea.tsx
|
|
9
|
+
function ColorArea(props) {
|
|
10
|
+
const { height = 150, className } = props;
|
|
11
|
+
const { store, disabled, classNames } = usePanel();
|
|
12
|
+
const areaRef = React.useRef(null);
|
|
13
|
+
const satRef = React.useRef(null);
|
|
14
|
+
const valRef = React.useRef(null);
|
|
15
|
+
useTransientColor(store, (c) => {
|
|
16
|
+
const el = areaRef.current;
|
|
17
|
+
if (el === null) return;
|
|
18
|
+
el.style.setProperty("--cp-thumb-x", `${c.s}%`);
|
|
19
|
+
el.style.setProperty("--cp-thumb-y", `${100 - c.v}%`);
|
|
20
|
+
const sat = satRef.current;
|
|
21
|
+
if (sat !== null) {
|
|
22
|
+
sat.value = String(Math.round(c.s));
|
|
23
|
+
sat.setAttribute("aria-valuetext", `Saturation ${Math.round(c.s)} percent`);
|
|
24
|
+
}
|
|
25
|
+
const val = valRef.current;
|
|
26
|
+
if (val !== null) {
|
|
27
|
+
val.value = String(Math.round(c.v));
|
|
28
|
+
val.setAttribute("aria-valuetext", `Brightness ${Math.round(c.v)} percent`);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
const drag = usePointerDrag({
|
|
32
|
+
disabled,
|
|
33
|
+
onMove: ({ x, y }) => store.patch({
|
|
34
|
+
s: x * 100,
|
|
35
|
+
v: (1 - y) * 100
|
|
36
|
+
}),
|
|
37
|
+
onEnd: () => store.commit()
|
|
38
|
+
});
|
|
39
|
+
const initial = store.get();
|
|
40
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
41
|
+
ref: areaRef,
|
|
42
|
+
className: cx("cp-area", className),
|
|
43
|
+
style: {
|
|
44
|
+
...drag.style,
|
|
45
|
+
height
|
|
46
|
+
},
|
|
47
|
+
onPointerDown: drag.onPointerDown,
|
|
48
|
+
onPointerMove: drag.onPointerMove,
|
|
49
|
+
onPointerUp: drag.onPointerUp,
|
|
50
|
+
onLostPointerCapture: drag.onLostPointerCapture,
|
|
51
|
+
role: "group",
|
|
52
|
+
"aria-label": "Saturation and brightness",
|
|
53
|
+
"aria-disabled": disabled || void 0,
|
|
54
|
+
children: [
|
|
55
|
+
/* @__PURE__ */ jsx(AxisInput, {
|
|
56
|
+
ref: satRef,
|
|
57
|
+
label: "Saturation",
|
|
58
|
+
min: 0,
|
|
59
|
+
max: 100,
|
|
60
|
+
defaultValue: Math.round(initial.s),
|
|
61
|
+
disabled,
|
|
62
|
+
onInput: (s) => store.patch({ s }),
|
|
63
|
+
onCommit: () => store.commit()
|
|
64
|
+
}),
|
|
65
|
+
/* @__PURE__ */ jsx(AxisInput, {
|
|
66
|
+
ref: valRef,
|
|
67
|
+
label: "Brightness",
|
|
68
|
+
min: 0,
|
|
69
|
+
max: 100,
|
|
70
|
+
defaultValue: Math.round(initial.v),
|
|
71
|
+
disabled,
|
|
72
|
+
onInput: (v) => store.patch({ v }),
|
|
73
|
+
onCommit: () => store.commit()
|
|
74
|
+
}),
|
|
75
|
+
/* @__PURE__ */ jsx("div", {
|
|
76
|
+
className: cx("cp-thumb", classNames.thumb),
|
|
77
|
+
"aria-hidden": "true"
|
|
78
|
+
})
|
|
79
|
+
]
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
//#endregion
|
|
83
|
+
export { ColorArea };
|
|
84
|
+
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
const require_context = require("../core/context.cjs");
|
|
4
|
+
const require_convert = require("../color/convert.cjs");
|
|
5
|
+
const require_useColorStore = require("../core/useColorStore.cjs");
|
|
6
|
+
const require_usePointerDrag = require("../core/usePointerDrag.cjs");
|
|
7
|
+
const require_AxisInput = require("./AxisInput.cjs");
|
|
8
|
+
let react = require("react");
|
|
9
|
+
react = require_runtime.__toESM(react, 1);
|
|
10
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
11
|
+
//#region src/primitives/ColorDisc.tsx
|
|
12
|
+
function ColorDisc(props) {
|
|
13
|
+
const { size = 200, className } = props;
|
|
14
|
+
const { store, disabled, classNames } = require_context.usePanel();
|
|
15
|
+
const discRef = react.useRef(null);
|
|
16
|
+
const hueRef = react.useRef(null);
|
|
17
|
+
const satRef = react.useRef(null);
|
|
18
|
+
require_useColorStore.useTransientColor(store, (c) => {
|
|
19
|
+
const el = discRef.current;
|
|
20
|
+
if (el === null) return;
|
|
21
|
+
const radians = require_convert.normalizeHue(c.h) * Math.PI / 180;
|
|
22
|
+
const radiusPct = c.s / 2;
|
|
23
|
+
el.style.setProperty("--cp-thumb-x", `${50 + Math.sin(radians) * radiusPct}%`);
|
|
24
|
+
el.style.setProperty("--cp-thumb-y", `${50 - Math.cos(radians) * radiusPct}%`);
|
|
25
|
+
const hue = hueRef.current;
|
|
26
|
+
if (hue !== null) {
|
|
27
|
+
hue.value = String(Math.round(require_convert.normalizeHue(c.h)));
|
|
28
|
+
hue.setAttribute("aria-valuetext", `Hue ${Math.round(require_convert.normalizeHue(c.h))} degrees`);
|
|
29
|
+
}
|
|
30
|
+
const sat = satRef.current;
|
|
31
|
+
if (sat !== null) {
|
|
32
|
+
sat.value = String(Math.round(c.s));
|
|
33
|
+
sat.setAttribute("aria-valuetext", `Saturation ${Math.round(c.s)} percent`);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
const drag = require_usePointerDrag.usePointerDrag({
|
|
37
|
+
disabled,
|
|
38
|
+
onMove: ({ x, y }) => {
|
|
39
|
+
const dx = x - .5;
|
|
40
|
+
const dy = y - .5;
|
|
41
|
+
const distance = Math.min(Math.hypot(dx, dy), .5);
|
|
42
|
+
const patch = { s: distance / .5 * 100 };
|
|
43
|
+
if (distance > 1e-6) patch.h = require_convert.normalizeHue(Math.atan2(dx, -dy) * 180 / Math.PI);
|
|
44
|
+
store.patch(patch);
|
|
45
|
+
},
|
|
46
|
+
onEnd: () => store.commit()
|
|
47
|
+
});
|
|
48
|
+
const initial = store.get();
|
|
49
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
50
|
+
className: "cp-disc-wrap",
|
|
51
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
52
|
+
ref: discRef,
|
|
53
|
+
className: require_context.cx("cp-disc", classNames.panel, className),
|
|
54
|
+
style: {
|
|
55
|
+
...drag.style,
|
|
56
|
+
width: size
|
|
57
|
+
},
|
|
58
|
+
onPointerDown: drag.onPointerDown,
|
|
59
|
+
onPointerMove: drag.onPointerMove,
|
|
60
|
+
onPointerUp: drag.onPointerUp,
|
|
61
|
+
onLostPointerCapture: drag.onLostPointerCapture,
|
|
62
|
+
role: "group",
|
|
63
|
+
"aria-label": "Colour wheel",
|
|
64
|
+
"aria-disabled": disabled || void 0,
|
|
65
|
+
children: [
|
|
66
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_AxisInput.AxisInput, {
|
|
67
|
+
ref: hueRef,
|
|
68
|
+
label: "Hue",
|
|
69
|
+
min: 0,
|
|
70
|
+
max: 360,
|
|
71
|
+
defaultValue: Math.round(require_convert.normalizeHue(initial.h)),
|
|
72
|
+
disabled,
|
|
73
|
+
onInput: (h) => store.patch({ h }),
|
|
74
|
+
onCommit: () => store.commit()
|
|
75
|
+
}),
|
|
76
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_AxisInput.AxisInput, {
|
|
77
|
+
ref: satRef,
|
|
78
|
+
label: "Saturation",
|
|
79
|
+
min: 0,
|
|
80
|
+
max: 100,
|
|
81
|
+
defaultValue: Math.round(initial.s),
|
|
82
|
+
disabled,
|
|
83
|
+
onInput: (s) => store.patch({ s }),
|
|
84
|
+
onCommit: () => store.commit()
|
|
85
|
+
}),
|
|
86
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
87
|
+
className: require_context.cx("cp-thumb", classNames.thumb),
|
|
88
|
+
"aria-hidden": "true"
|
|
89
|
+
})
|
|
90
|
+
]
|
|
91
|
+
})
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
//#endregion
|
|
95
|
+
exports.ColorDisc = ColorDisc;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cx, usePanel } from "../core/context.js";
|
|
3
|
+
import { normalizeHue } from "../color/convert.js";
|
|
4
|
+
import { useTransientColor } from "../core/useColorStore.js";
|
|
5
|
+
import { usePointerDrag } from "../core/usePointerDrag.js";
|
|
6
|
+
import { AxisInput } from "./AxisInput.js";
|
|
7
|
+
import * as React from "react";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
//#region src/primitives/ColorDisc.tsx
|
|
10
|
+
function ColorDisc(props) {
|
|
11
|
+
const { size = 200, className } = props;
|
|
12
|
+
const { store, disabled, classNames } = usePanel();
|
|
13
|
+
const discRef = React.useRef(null);
|
|
14
|
+
const hueRef = React.useRef(null);
|
|
15
|
+
const satRef = React.useRef(null);
|
|
16
|
+
useTransientColor(store, (c) => {
|
|
17
|
+
const el = discRef.current;
|
|
18
|
+
if (el === null) return;
|
|
19
|
+
const radians = normalizeHue(c.h) * Math.PI / 180;
|
|
20
|
+
const radiusPct = c.s / 2;
|
|
21
|
+
el.style.setProperty("--cp-thumb-x", `${50 + Math.sin(radians) * radiusPct}%`);
|
|
22
|
+
el.style.setProperty("--cp-thumb-y", `${50 - Math.cos(radians) * radiusPct}%`);
|
|
23
|
+
const hue = hueRef.current;
|
|
24
|
+
if (hue !== null) {
|
|
25
|
+
hue.value = String(Math.round(normalizeHue(c.h)));
|
|
26
|
+
hue.setAttribute("aria-valuetext", `Hue ${Math.round(normalizeHue(c.h))} degrees`);
|
|
27
|
+
}
|
|
28
|
+
const sat = satRef.current;
|
|
29
|
+
if (sat !== null) {
|
|
30
|
+
sat.value = String(Math.round(c.s));
|
|
31
|
+
sat.setAttribute("aria-valuetext", `Saturation ${Math.round(c.s)} percent`);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
const drag = usePointerDrag({
|
|
35
|
+
disabled,
|
|
36
|
+
onMove: ({ x, y }) => {
|
|
37
|
+
const dx = x - .5;
|
|
38
|
+
const dy = y - .5;
|
|
39
|
+
const distance = Math.min(Math.hypot(dx, dy), .5);
|
|
40
|
+
const patch = { s: distance / .5 * 100 };
|
|
41
|
+
if (distance > 1e-6) patch.h = normalizeHue(Math.atan2(dx, -dy) * 180 / Math.PI);
|
|
42
|
+
store.patch(patch);
|
|
43
|
+
},
|
|
44
|
+
onEnd: () => store.commit()
|
|
45
|
+
});
|
|
46
|
+
const initial = store.get();
|
|
47
|
+
return /* @__PURE__ */ jsx("div", {
|
|
48
|
+
className: "cp-disc-wrap",
|
|
49
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
50
|
+
ref: discRef,
|
|
51
|
+
className: cx("cp-disc", classNames.panel, className),
|
|
52
|
+
style: {
|
|
53
|
+
...drag.style,
|
|
54
|
+
width: size
|
|
55
|
+
},
|
|
56
|
+
onPointerDown: drag.onPointerDown,
|
|
57
|
+
onPointerMove: drag.onPointerMove,
|
|
58
|
+
onPointerUp: drag.onPointerUp,
|
|
59
|
+
onLostPointerCapture: drag.onLostPointerCapture,
|
|
60
|
+
role: "group",
|
|
61
|
+
"aria-label": "Colour wheel",
|
|
62
|
+
"aria-disabled": disabled || void 0,
|
|
63
|
+
children: [
|
|
64
|
+
/* @__PURE__ */ jsx(AxisInput, {
|
|
65
|
+
ref: hueRef,
|
|
66
|
+
label: "Hue",
|
|
67
|
+
min: 0,
|
|
68
|
+
max: 360,
|
|
69
|
+
defaultValue: Math.round(normalizeHue(initial.h)),
|
|
70
|
+
disabled,
|
|
71
|
+
onInput: (h) => store.patch({ h }),
|
|
72
|
+
onCommit: () => store.commit()
|
|
73
|
+
}),
|
|
74
|
+
/* @__PURE__ */ jsx(AxisInput, {
|
|
75
|
+
ref: satRef,
|
|
76
|
+
label: "Saturation",
|
|
77
|
+
min: 0,
|
|
78
|
+
max: 100,
|
|
79
|
+
defaultValue: Math.round(initial.s),
|
|
80
|
+
disabled,
|
|
81
|
+
onInput: (s) => store.patch({ s }),
|
|
82
|
+
onCommit: () => store.commit()
|
|
83
|
+
}),
|
|
84
|
+
/* @__PURE__ */ jsx("div", {
|
|
85
|
+
className: cx("cp-thumb", classNames.thumb),
|
|
86
|
+
"aria-hidden": "true"
|
|
87
|
+
})
|
|
88
|
+
]
|
|
89
|
+
})
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
//#endregion
|
|
93
|
+
export { ColorDisc };
|
|
94
|
+
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
const require_context = require("../core/context.cjs");
|
|
4
|
+
const require_useColorStore = require("../core/useColorStore.cjs");
|
|
5
|
+
const require_parse = require("../color/parse.cjs");
|
|
6
|
+
const require_serialize = require("../color/serialize.cjs");
|
|
7
|
+
let react = require("react");
|
|
8
|
+
react = require_runtime.__toESM(react, 1);
|
|
9
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
10
|
+
//#region src/primitives/ColorField.tsx
|
|
11
|
+
function ColorField(props) {
|
|
12
|
+
const { label = "Hex", withAlpha = false, className } = props;
|
|
13
|
+
const { store, disabled, classNames } = require_context.usePanel();
|
|
14
|
+
const id = require_context.useStableId("cp-hex-");
|
|
15
|
+
const inputRef = react.useRef(null);
|
|
16
|
+
const focused = react.useRef(false);
|
|
17
|
+
const format = react.useRef(withAlpha);
|
|
18
|
+
react.useEffect(() => {
|
|
19
|
+
format.current = withAlpha;
|
|
20
|
+
});
|
|
21
|
+
const render = (c) => format.current ? require_serialize.toHexa(c) : require_serialize.toHex(c);
|
|
22
|
+
require_useColorStore.useTransientColor(store, (c) => {
|
|
23
|
+
if (focused.current) return;
|
|
24
|
+
const el = inputRef.current;
|
|
25
|
+
if (el !== null) {
|
|
26
|
+
el.value = render(c);
|
|
27
|
+
el.setAttribute("aria-invalid", "false");
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
const handleChange = (event) => {
|
|
31
|
+
const parsed = require_parse.parse(event.currentTarget.value);
|
|
32
|
+
event.currentTarget.setAttribute("aria-invalid", parsed === null ? "true" : "false");
|
|
33
|
+
if (parsed !== null) store.ingest(parsed);
|
|
34
|
+
};
|
|
35
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36
|
+
className: require_context.cx("cp-field", classNames.field, className),
|
|
37
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
38
|
+
className: "cp-field-label",
|
|
39
|
+
htmlFor: id,
|
|
40
|
+
children: label
|
|
41
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
42
|
+
ref: inputRef,
|
|
43
|
+
id,
|
|
44
|
+
className: "cp-input",
|
|
45
|
+
type: "text",
|
|
46
|
+
spellCheck: false,
|
|
47
|
+
autoComplete: "off",
|
|
48
|
+
autoCapitalize: "off",
|
|
49
|
+
defaultValue: render(store.get()),
|
|
50
|
+
disabled,
|
|
51
|
+
onFocus: () => {
|
|
52
|
+
focused.current = true;
|
|
53
|
+
},
|
|
54
|
+
onChange: handleChange,
|
|
55
|
+
onBlur: (e) => {
|
|
56
|
+
focused.current = false;
|
|
57
|
+
e.currentTarget.value = render(store.get());
|
|
58
|
+
e.currentTarget.setAttribute("aria-invalid", "false");
|
|
59
|
+
store.commit();
|
|
60
|
+
},
|
|
61
|
+
onKeyDown: (e) => {
|
|
62
|
+
if (e.key === "Enter") e.currentTarget.blur();
|
|
63
|
+
}
|
|
64
|
+
})]
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
//#endregion
|
|
68
|
+
exports.ColorField = ColorField;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
//#region src/primitives/ColorField.d.ts
|
|
3
|
+
export interface ColorFieldProps {
|
|
4
|
+
label?: string;
|
|
5
|
+
withAlpha?: boolean;
|
|
6
|
+
className?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function ColorField(props: ColorFieldProps): React.ReactElement;
|
|
9
|
+
//#endregion
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
//#region src/primitives/ColorField.d.ts
|
|
3
|
+
export interface ColorFieldProps {
|
|
4
|
+
label?: string;
|
|
5
|
+
withAlpha?: boolean;
|
|
6
|
+
className?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function ColorField(props: ColorFieldProps): React.ReactElement;
|
|
9
|
+
//#endregion
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cx, usePanel, useStableId } from "../core/context.js";
|
|
3
|
+
import { useTransientColor } from "../core/useColorStore.js";
|
|
4
|
+
import { parse } from "../color/parse.js";
|
|
5
|
+
import { toHex, toHexa } from "../color/serialize.js";
|
|
6
|
+
import * as React from "react";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
//#region src/primitives/ColorField.tsx
|
|
9
|
+
function ColorField(props) {
|
|
10
|
+
const { label = "Hex", withAlpha = false, className } = props;
|
|
11
|
+
const { store, disabled, classNames } = usePanel();
|
|
12
|
+
const id = useStableId("cp-hex-");
|
|
13
|
+
const inputRef = React.useRef(null);
|
|
14
|
+
const focused = React.useRef(false);
|
|
15
|
+
const format = React.useRef(withAlpha);
|
|
16
|
+
React.useEffect(() => {
|
|
17
|
+
format.current = withAlpha;
|
|
18
|
+
});
|
|
19
|
+
const render = (c) => format.current ? toHexa(c) : toHex(c);
|
|
20
|
+
useTransientColor(store, (c) => {
|
|
21
|
+
if (focused.current) return;
|
|
22
|
+
const el = inputRef.current;
|
|
23
|
+
if (el !== null) {
|
|
24
|
+
el.value = render(c);
|
|
25
|
+
el.setAttribute("aria-invalid", "false");
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
const handleChange = (event) => {
|
|
29
|
+
const parsed = parse(event.currentTarget.value);
|
|
30
|
+
event.currentTarget.setAttribute("aria-invalid", parsed === null ? "true" : "false");
|
|
31
|
+
if (parsed !== null) store.ingest(parsed);
|
|
32
|
+
};
|
|
33
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
34
|
+
className: cx("cp-field", classNames.field, className),
|
|
35
|
+
children: [/* @__PURE__ */ jsx("label", {
|
|
36
|
+
className: "cp-field-label",
|
|
37
|
+
htmlFor: id,
|
|
38
|
+
children: label
|
|
39
|
+
}), /* @__PURE__ */ jsx("input", {
|
|
40
|
+
ref: inputRef,
|
|
41
|
+
id,
|
|
42
|
+
className: "cp-input",
|
|
43
|
+
type: "text",
|
|
44
|
+
spellCheck: false,
|
|
45
|
+
autoComplete: "off",
|
|
46
|
+
autoCapitalize: "off",
|
|
47
|
+
defaultValue: render(store.get()),
|
|
48
|
+
disabled,
|
|
49
|
+
onFocus: () => {
|
|
50
|
+
focused.current = true;
|
|
51
|
+
},
|
|
52
|
+
onChange: handleChange,
|
|
53
|
+
onBlur: (e) => {
|
|
54
|
+
focused.current = false;
|
|
55
|
+
e.currentTarget.value = render(store.get());
|
|
56
|
+
e.currentTarget.setAttribute("aria-invalid", "false");
|
|
57
|
+
store.commit();
|
|
58
|
+
},
|
|
59
|
+
onKeyDown: (e) => {
|
|
60
|
+
if (e.key === "Enter") e.currentTarget.blur();
|
|
61
|
+
}
|
|
62
|
+
})]
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
export { ColorField };
|
|
67
|
+
|