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.
Files changed (202) hide show
  1. package/LICENSE +44 -0
  2. package/README.md +119 -0
  3. package/dist/_virtual/_rolldown/runtime.cjs +23 -0
  4. package/dist/a11y/contrast.cjs +107 -0
  5. package/dist/a11y/contrast.d.cts +34 -0
  6. package/dist/a11y/contrast.d.ts +34 -0
  7. package/dist/a11y/contrast.js +101 -0
  8. package/dist/color/convert.cjs +162 -0
  9. package/dist/color/convert.d.cts +16 -0
  10. package/dist/color/convert.d.ts +16 -0
  11. package/dist/color/convert.js +153 -0
  12. package/dist/color/parse.cjs +153 -0
  13. package/dist/color/parse.d.cts +7 -0
  14. package/dist/color/parse.d.ts +7 -0
  15. package/dist/color/parse.js +151 -0
  16. package/dist/color/serialize.cjs +79 -0
  17. package/dist/color/serialize.d.cts +11 -0
  18. package/dist/color/serialize.d.ts +11 -0
  19. package/dist/color/serialize.js +73 -0
  20. package/dist/color/sticky.cjs +20 -0
  21. package/dist/color/sticky.d.cts +6 -0
  22. package/dist/color/sticky.d.ts +6 -0
  23. package/dist/color/sticky.js +19 -0
  24. package/dist/color/types.d.cts +43 -0
  25. package/dist/color/types.d.ts +43 -0
  26. package/dist/components/ChromaPanel.cjs +254 -0
  27. package/dist/components/ChromaPanel.d.cts +47 -0
  28. package/dist/components/ChromaPanel.d.ts +47 -0
  29. package/dist/components/ChromaPanel.js +251 -0
  30. package/dist/components/ColorInput.cjs +128 -0
  31. package/dist/components/ColorInput.d.cts +19 -0
  32. package/dist/components/ColorInput.d.ts +19 -0
  33. package/dist/components/ColorInput.js +127 -0
  34. package/dist/components/ModeToolbar.cjs +33 -0
  35. package/dist/components/ModeToolbar.d.cts +10 -0
  36. package/dist/components/ModeToolbar.d.ts +10 -0
  37. package/dist/components/ModeToolbar.js +32 -0
  38. package/dist/components/PanelFooter.cjs +82 -0
  39. package/dist/components/PanelFooter.d.cts +5 -0
  40. package/dist/components/PanelFooter.d.ts +5 -0
  41. package/dist/components/PanelFooter.js +80 -0
  42. package/dist/components/Popover.cjs +154 -0
  43. package/dist/components/Popover.d.cts +13 -0
  44. package/dist/components/Popover.d.ts +13 -0
  45. package/dist/components/Popover.js +153 -0
  46. package/dist/contrast.cjs +10 -0
  47. package/dist/contrast.d.cts +2 -0
  48. package/dist/contrast.d.ts +2 -0
  49. package/dist/contrast.js +2 -0
  50. package/dist/core/context.cjs +30 -0
  51. package/dist/core/context.d.cts +43 -0
  52. package/dist/core/context.d.ts +43 -0
  53. package/dist/core/context.js +26 -0
  54. package/dist/core/dev.cjs +11 -0
  55. package/dist/core/dev.js +11 -0
  56. package/dist/core/store.cjs +43 -0
  57. package/dist/core/store.d.cts +17 -0
  58. package/dist/core/store.d.ts +17 -0
  59. package/dist/core/store.js +44 -0
  60. package/dist/core/styleInjector.cjs +38 -0
  61. package/dist/core/styleInjector.d.cts +4 -0
  62. package/dist/core/styleInjector.d.ts +4 -0
  63. package/dist/core/styleInjector.js +38 -0
  64. package/dist/core/useColorStore.cjs +43 -0
  65. package/dist/core/useColorStore.d.cts +6 -0
  66. package/dist/core/useColorStore.d.ts +6 -0
  67. package/dist/core/useColorStore.js +41 -0
  68. package/dist/core/useFormControl.cjs +87 -0
  69. package/dist/core/useFormControl.js +82 -0
  70. package/dist/core/useMediaQuery.cjs +48 -0
  71. package/dist/core/useMediaQuery.js +46 -0
  72. package/dist/core/usePointerDrag.cjs +177 -0
  73. package/dist/core/usePointerDrag.d.cts +35 -0
  74. package/dist/core/usePointerDrag.d.ts +35 -0
  75. package/dist/core/usePointerDrag.js +175 -0
  76. package/dist/core/useScrollFade.cjs +44 -0
  77. package/dist/core/useScrollFade.js +43 -0
  78. package/dist/core.cjs +33 -0
  79. package/dist/core.d.cts +7 -0
  80. package/dist/core.d.ts +7 -0
  81. package/dist/core.js +6 -0
  82. package/dist/data/defaults.cjs +123 -0
  83. package/dist/data/defaults.d.cts +6 -0
  84. package/dist/data/defaults.d.ts +6 -0
  85. package/dist/data/defaults.js +122 -0
  86. package/dist/data/namedColors.cjs +11 -0
  87. package/dist/data/namedColors.d.cts +3 -0
  88. package/dist/data/namedColors.d.ts +3 -0
  89. package/dist/data/namedColors.js +12 -0
  90. package/dist/image/extract.cjs +98 -0
  91. package/dist/image/extract.d.cts +16 -0
  92. package/dist/image/extract.d.ts +16 -0
  93. package/dist/image/extract.js +99 -0
  94. package/dist/image/mmcq.cjs +182 -0
  95. package/dist/image/mmcq.d.cts +8 -0
  96. package/dist/image/mmcq.d.ts +8 -0
  97. package/dist/image/mmcq.js +183 -0
  98. package/dist/image-worker.js +202 -0
  99. package/dist/image.cjs +12 -0
  100. package/dist/image.d.cts +4 -0
  101. package/dist/image.d.ts +4 -0
  102. package/dist/image.js +9 -0
  103. package/dist/index.cjs +119 -0
  104. package/dist/index.d.cts +36 -0
  105. package/dist/index.d.ts +36 -0
  106. package/dist/index.js +44 -0
  107. package/dist/modes/gradients.cjs +48 -0
  108. package/dist/modes/gradients.js +43 -0
  109. package/dist/modes/image/index.cjs +193 -0
  110. package/dist/modes/image/index.d.cts +10 -0
  111. package/dist/modes/image/index.d.ts +10 -0
  112. package/dist/modes/image/index.js +191 -0
  113. package/dist/modes/palettes/index.cjs +76 -0
  114. package/dist/modes/palettes/index.d.cts +6 -0
  115. package/dist/modes/palettes/index.d.ts +6 -0
  116. package/dist/modes/palettes/index.js +74 -0
  117. package/dist/modes/pencils/index.cjs +36 -0
  118. package/dist/modes/pencils/index.d.cts +6 -0
  119. package/dist/modes/pencils/index.d.ts +6 -0
  120. package/dist/modes/pencils/index.js +34 -0
  121. package/dist/modes/registry.cjs +26 -0
  122. package/dist/modes/registry.d.cts +13 -0
  123. package/dist/modes/registry.d.ts +13 -0
  124. package/dist/modes/registry.js +25 -0
  125. package/dist/modes/sliders/index.cjs +300 -0
  126. package/dist/modes/sliders/index.d.cts +6 -0
  127. package/dist/modes/sliders/index.d.ts +6 -0
  128. package/dist/modes/sliders/index.js +298 -0
  129. package/dist/modes/wheel/index.cjs +62 -0
  130. package/dist/modes/wheel/index.d.cts +6 -0
  131. package/dist/modes/wheel/index.d.ts +6 -0
  132. package/dist/modes/wheel/index.js +60 -0
  133. package/dist/named-colors.cjs +3 -0
  134. package/dist/named-colors.d.cts +2 -0
  135. package/dist/named-colors.d.ts +2 -0
  136. package/dist/named-colors.js +2 -0
  137. package/dist/palettes.cjs +8 -0
  138. package/dist/palettes.d.cts +2 -0
  139. package/dist/palettes.d.ts +2 -0
  140. package/dist/palettes.js +7 -0
  141. package/dist/panel.cjs +80 -0
  142. package/dist/panel.d.cts +27 -0
  143. package/dist/panel.d.ts +27 -0
  144. package/dist/panel.js +27 -0
  145. package/dist/pencils.cjs +8 -0
  146. package/dist/pencils.d.cts +2 -0
  147. package/dist/pencils.d.ts +2 -0
  148. package/dist/pencils.js +7 -0
  149. package/dist/primitives/AxisInput.cjs +26 -0
  150. package/dist/primitives/AxisInput.js +25 -0
  151. package/dist/primitives/ChannelSlider.cjs +94 -0
  152. package/dist/primitives/ChannelSlider.d.cts +18 -0
  153. package/dist/primitives/ChannelSlider.d.ts +18 -0
  154. package/dist/primitives/ChannelSlider.js +93 -0
  155. package/dist/primitives/ColorArea.cjs +85 -0
  156. package/dist/primitives/ColorArea.d.cts +8 -0
  157. package/dist/primitives/ColorArea.d.ts +8 -0
  158. package/dist/primitives/ColorArea.js +84 -0
  159. package/dist/primitives/ColorDisc.cjs +95 -0
  160. package/dist/primitives/ColorDisc.d.cts +8 -0
  161. package/dist/primitives/ColorDisc.d.ts +8 -0
  162. package/dist/primitives/ColorDisc.js +94 -0
  163. package/dist/primitives/ColorField.cjs +68 -0
  164. package/dist/primitives/ColorField.d.cts +9 -0
  165. package/dist/primitives/ColorField.d.ts +9 -0
  166. package/dist/primitives/ColorField.js +67 -0
  167. package/dist/primitives/NumberField.cjs +65 -0
  168. package/dist/primitives/NumberField.d.cts +14 -0
  169. package/dist/primitives/NumberField.d.ts +14 -0
  170. package/dist/primitives/NumberField.js +64 -0
  171. package/dist/primitives/SegmentedControl.cjs +66 -0
  172. package/dist/primitives/SegmentedControl.d.cts +21 -0
  173. package/dist/primitives/SegmentedControl.d.ts +21 -0
  174. package/dist/primitives/SegmentedControl.js +65 -0
  175. package/dist/primitives/Swatch.cjs +22 -0
  176. package/dist/primitives/Swatch.d.cts +13 -0
  177. package/dist/primitives/Swatch.d.ts +13 -0
  178. package/dist/primitives/Swatch.js +21 -0
  179. package/dist/primitives/SwatchGrid.cjs +63 -0
  180. package/dist/primitives/SwatchGrid.d.cts +17 -0
  181. package/dist/primitives/SwatchGrid.d.ts +17 -0
  182. package/dist/primitives/SwatchGrid.js +62 -0
  183. package/dist/primitives/icons.cjs +149 -0
  184. package/dist/primitives/icons.d.cts +9 -0
  185. package/dist/primitives/icons.d.ts +9 -0
  186. package/dist/primitives/icons.js +141 -0
  187. package/dist/primitives/useEyedropper.cjs +30 -0
  188. package/dist/primitives/useEyedropper.d.cts +7 -0
  189. package/dist/primitives/useEyedropper.d.ts +7 -0
  190. package/dist/primitives/useEyedropper.js +29 -0
  191. package/dist/sliders.cjs +8 -0
  192. package/dist/sliders.d.cts +2 -0
  193. package/dist/sliders.d.ts +2 -0
  194. package/dist/sliders.js +7 -0
  195. package/dist/style.css +2 -0
  196. package/dist/styles/css.cjs +4 -0
  197. package/dist/styles/css.js +5 -0
  198. package/dist/wheel.cjs +8 -0
  199. package/dist/wheel.d.cts +2 -0
  200. package/dist/wheel.d.ts +2 -0
  201. package/dist/wheel.js +7 -0
  202. package/package.json +222 -0
@@ -0,0 +1,65 @@
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
+ let react = require("react");
7
+ react = require_runtime.__toESM(react, 1);
8
+ let react_jsx_runtime = require("react/jsx-runtime");
9
+ //#region src/primitives/NumberField.tsx
10
+ function NumberField(props) {
11
+ const { label, min, max, step, read, write, className } = props;
12
+ const { store, disabled, classNames } = require_context.usePanel();
13
+ const id = require_context.useStableId("cp-num-");
14
+ const inputRef = react.useRef(null);
15
+ const focused = react.useRef(false);
16
+ const fns = react.useRef({
17
+ read,
18
+ write
19
+ });
20
+ react.useEffect(() => {
21
+ fns.current = {
22
+ read,
23
+ write
24
+ };
25
+ });
26
+ require_useColorStore.useTransientColor(store, (c) => {
27
+ if (focused.current) return;
28
+ const el = inputRef.current;
29
+ if (el !== null) el.value = String(Math.round(fns.current.read(c)));
30
+ });
31
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
32
+ className: require_context.cx("cp-field", classNames.field, className),
33
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
34
+ className: "cp-field-label",
35
+ htmlFor: id,
36
+ children: label
37
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
38
+ ref: inputRef,
39
+ id,
40
+ className: "cp-input",
41
+ type: "number",
42
+ inputMode: "numeric",
43
+ min,
44
+ max,
45
+ step: step ?? 1,
46
+ defaultValue: Math.round(read(store.get())),
47
+ disabled,
48
+ onFocus: () => {
49
+ focused.current = true;
50
+ },
51
+ onChange: (e) => {
52
+ const raw = e.currentTarget.valueAsNumber;
53
+ if (Number.isNaN(raw)) return;
54
+ store.set(fns.current.write(require_convert.clamp(raw, min, max), store.get()));
55
+ },
56
+ onBlur: (e) => {
57
+ focused.current = false;
58
+ e.currentTarget.value = String(Math.round(fns.current.read(store.get())));
59
+ store.commit();
60
+ }
61
+ })]
62
+ });
63
+ }
64
+ //#endregion
65
+ exports.NumberField = NumberField;
@@ -0,0 +1,14 @@
1
+ import { Hsva } from "../color/types.cjs";
2
+ import * as React from "react";
3
+ //#region src/primitives/NumberField.d.ts
4
+ export interface NumberFieldProps {
5
+ label: string;
6
+ min: number;
7
+ max: number;
8
+ step?: number;
9
+ read: (color: Hsva) => number;
10
+ write: (value: number, current: Hsva) => Hsva;
11
+ className?: string;
12
+ }
13
+ export declare function NumberField(props: NumberFieldProps): React.ReactElement;
14
+ //#endregion
@@ -0,0 +1,14 @@
1
+ import { Hsva } from "../color/types.js";
2
+ import * as React from "react";
3
+ //#region src/primitives/NumberField.d.ts
4
+ export interface NumberFieldProps {
5
+ label: string;
6
+ min: number;
7
+ max: number;
8
+ step?: number;
9
+ read: (color: Hsva) => number;
10
+ write: (value: number, current: Hsva) => Hsva;
11
+ className?: string;
12
+ }
13
+ export declare function NumberField(props: NumberFieldProps): React.ReactElement;
14
+ //#endregion
@@ -0,0 +1,64 @@
1
+ "use client";
2
+ import { cx, usePanel, useStableId } from "../core/context.js";
3
+ import { clamp } from "../color/convert.js";
4
+ import { useTransientColor } from "../core/useColorStore.js";
5
+ import * as React from "react";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ //#region src/primitives/NumberField.tsx
8
+ function NumberField(props) {
9
+ const { label, min, max, step, read, write, className } = props;
10
+ const { store, disabled, classNames } = usePanel();
11
+ const id = useStableId("cp-num-");
12
+ const inputRef = React.useRef(null);
13
+ const focused = React.useRef(false);
14
+ const fns = React.useRef({
15
+ read,
16
+ write
17
+ });
18
+ React.useEffect(() => {
19
+ fns.current = {
20
+ read,
21
+ write
22
+ };
23
+ });
24
+ useTransientColor(store, (c) => {
25
+ if (focused.current) return;
26
+ const el = inputRef.current;
27
+ if (el !== null) el.value = String(Math.round(fns.current.read(c)));
28
+ });
29
+ return /* @__PURE__ */ jsxs("div", {
30
+ className: cx("cp-field", classNames.field, className),
31
+ children: [/* @__PURE__ */ jsx("label", {
32
+ className: "cp-field-label",
33
+ htmlFor: id,
34
+ children: label
35
+ }), /* @__PURE__ */ jsx("input", {
36
+ ref: inputRef,
37
+ id,
38
+ className: "cp-input",
39
+ type: "number",
40
+ inputMode: "numeric",
41
+ min,
42
+ max,
43
+ step: step ?? 1,
44
+ defaultValue: Math.round(read(store.get())),
45
+ disabled,
46
+ onFocus: () => {
47
+ focused.current = true;
48
+ },
49
+ onChange: (e) => {
50
+ const raw = e.currentTarget.valueAsNumber;
51
+ if (Number.isNaN(raw)) return;
52
+ store.set(fns.current.write(clamp(raw, min, max), store.get()));
53
+ },
54
+ onBlur: (e) => {
55
+ focused.current = false;
56
+ e.currentTarget.value = String(Math.round(fns.current.read(store.get())));
57
+ store.commit();
58
+ }
59
+ })]
60
+ });
61
+ }
62
+ //#endregion
63
+ export { NumberField };
64
+
@@ -0,0 +1,66 @@
1
+ "use client";
2
+ const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
3
+ const require_context = require("../core/context.cjs");
4
+ let react = require("react");
5
+ react = require_runtime.__toESM(react, 1);
6
+ let react_jsx_runtime = require("react/jsx-runtime");
7
+ //#region src/primitives/SegmentedControl.tsx
8
+ function SegmentedControl(props) {
9
+ const { items, value, onChange, size = "md", ariaLabel, controls, segmentId, disabled = false, className, tabClassName } = props;
10
+ const refs = react.useRef([]);
11
+ const activeIndex = Math.max(0, items.findIndex((item) => item.id === value));
12
+ const move = (to) => {
13
+ const wrapped = (to + items.length) % items.length;
14
+ const item = items[wrapped];
15
+ if (item === void 0) return;
16
+ onChange(item.id);
17
+ refs.current[wrapped]?.focus();
18
+ };
19
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
20
+ className: require_context.cx("cp-seg", size === "sm" && "cp-seg-sm", className),
21
+ role: "tablist",
22
+ "aria-label": ariaLabel,
23
+ "aria-orientation": "horizontal",
24
+ style: {
25
+ ["--cp-seg-count"]: items.length,
26
+ ["--cp-seg-active"]: activeIndex
27
+ },
28
+ children: items.map((item, index) => {
29
+ const selected = item.id === value;
30
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
31
+ ref: (el) => {
32
+ refs.current[index] = el;
33
+ },
34
+ type: "button",
35
+ role: "tab",
36
+ id: segmentId?.(item.id),
37
+ "aria-controls": controls?.(item.id),
38
+ "aria-selected": selected,
39
+ "aria-label": item.label,
40
+ title: item.label,
41
+ tabIndex: selected ? 0 : -1,
42
+ disabled,
43
+ className: require_context.cx("cp-tab", tabClassName),
44
+ onClick: () => onChange(item.id),
45
+ onKeyDown: (event) => {
46
+ if (event.key === "ArrowRight") {
47
+ event.preventDefault();
48
+ move(index + 1);
49
+ } else if (event.key === "ArrowLeft") {
50
+ event.preventDefault();
51
+ move(index - 1);
52
+ } else if (event.key === "Home") {
53
+ event.preventDefault();
54
+ move(0);
55
+ } else if (event.key === "End") {
56
+ event.preventDefault();
57
+ move(items.length - 1);
58
+ }
59
+ },
60
+ children: item.content
61
+ }, item.id);
62
+ })
63
+ });
64
+ }
65
+ //#endregion
66
+ exports.SegmentedControl = SegmentedControl;
@@ -0,0 +1,21 @@
1
+ import * as React from "react";
2
+ //#region src/primitives/SegmentedControl.d.ts
3
+ export interface SegmentedItem {
4
+ id: string;
5
+ label: string;
6
+ content: React.ReactNode;
7
+ }
8
+ export interface SegmentedControlProps {
9
+ items: SegmentedItem[];
10
+ value: string;
11
+ onChange: (id: string) => void;
12
+ size?: "md" | "sm";
13
+ ariaLabel: string;
14
+ controls?: (id: string) => string;
15
+ segmentId?: (id: string) => string;
16
+ disabled?: boolean;
17
+ className?: string;
18
+ tabClassName?: string;
19
+ }
20
+ export declare function SegmentedControl(props: SegmentedControlProps): React.ReactElement;
21
+ //#endregion
@@ -0,0 +1,21 @@
1
+ import * as React from "react";
2
+ //#region src/primitives/SegmentedControl.d.ts
3
+ export interface SegmentedItem {
4
+ id: string;
5
+ label: string;
6
+ content: React.ReactNode;
7
+ }
8
+ export interface SegmentedControlProps {
9
+ items: SegmentedItem[];
10
+ value: string;
11
+ onChange: (id: string) => void;
12
+ size?: "md" | "sm";
13
+ ariaLabel: string;
14
+ controls?: (id: string) => string;
15
+ segmentId?: (id: string) => string;
16
+ disabled?: boolean;
17
+ className?: string;
18
+ tabClassName?: string;
19
+ }
20
+ export declare function SegmentedControl(props: SegmentedControlProps): React.ReactElement;
21
+ //#endregion
@@ -0,0 +1,65 @@
1
+ "use client";
2
+ import { cx } from "../core/context.js";
3
+ import * as React from "react";
4
+ import { jsx } from "react/jsx-runtime";
5
+ //#region src/primitives/SegmentedControl.tsx
6
+ function SegmentedControl(props) {
7
+ const { items, value, onChange, size = "md", ariaLabel, controls, segmentId, disabled = false, className, tabClassName } = props;
8
+ const refs = React.useRef([]);
9
+ const activeIndex = Math.max(0, items.findIndex((item) => item.id === value));
10
+ const move = (to) => {
11
+ const wrapped = (to + items.length) % items.length;
12
+ const item = items[wrapped];
13
+ if (item === void 0) return;
14
+ onChange(item.id);
15
+ refs.current[wrapped]?.focus();
16
+ };
17
+ return /* @__PURE__ */ jsx("div", {
18
+ className: cx("cp-seg", size === "sm" && "cp-seg-sm", className),
19
+ role: "tablist",
20
+ "aria-label": ariaLabel,
21
+ "aria-orientation": "horizontal",
22
+ style: {
23
+ ["--cp-seg-count"]: items.length,
24
+ ["--cp-seg-active"]: activeIndex
25
+ },
26
+ children: items.map((item, index) => {
27
+ const selected = item.id === value;
28
+ return /* @__PURE__ */ jsx("button", {
29
+ ref: (el) => {
30
+ refs.current[index] = el;
31
+ },
32
+ type: "button",
33
+ role: "tab",
34
+ id: segmentId?.(item.id),
35
+ "aria-controls": controls?.(item.id),
36
+ "aria-selected": selected,
37
+ "aria-label": item.label,
38
+ title: item.label,
39
+ tabIndex: selected ? 0 : -1,
40
+ disabled,
41
+ className: cx("cp-tab", tabClassName),
42
+ onClick: () => onChange(item.id),
43
+ onKeyDown: (event) => {
44
+ if (event.key === "ArrowRight") {
45
+ event.preventDefault();
46
+ move(index + 1);
47
+ } else if (event.key === "ArrowLeft") {
48
+ event.preventDefault();
49
+ move(index - 1);
50
+ } else if (event.key === "Home") {
51
+ event.preventDefault();
52
+ move(0);
53
+ } else if (event.key === "End") {
54
+ event.preventDefault();
55
+ move(items.length - 1);
56
+ }
57
+ },
58
+ children: item.content
59
+ }, item.id);
60
+ })
61
+ });
62
+ }
63
+ //#endregion
64
+ export { SegmentedControl };
65
+
@@ -0,0 +1,22 @@
1
+ "use client";
2
+ const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
3
+ const require_context = require("../core/context.cjs");
4
+ let react = require("react");
5
+ react = require_runtime.__toESM(react, 1);
6
+ let react_jsx_runtime = require("react/jsx-runtime");
7
+ //#region src/primitives/Swatch.tsx
8
+ function Swatch(props) {
9
+ const { color, label, matchKey, round, disabled, onSelect, className } = props;
10
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
11
+ type: "button",
12
+ className: require_context.cx("cp-swatch", round === true && "cp-swatch-round", className),
13
+ style: { ["--cp-swatch-color"]: color },
14
+ "data-cp-color": matchKey ?? color,
15
+ "aria-label": label ?? color,
16
+ "aria-pressed": false,
17
+ disabled,
18
+ onClick: () => onSelect?.(color)
19
+ });
20
+ }
21
+ //#endregion
22
+ exports.Swatch = Swatch;
@@ -0,0 +1,13 @@
1
+ import * as React from "react";
2
+ //#region src/primitives/Swatch.d.ts
3
+ export interface SwatchProps {
4
+ color: string;
5
+ label?: string;
6
+ matchKey?: string;
7
+ round?: boolean;
8
+ disabled?: boolean;
9
+ onSelect?: (color: string) => void;
10
+ className?: string;
11
+ }
12
+ export declare function Swatch(props: SwatchProps): React.ReactElement;
13
+ //#endregion
@@ -0,0 +1,13 @@
1
+ import * as React from "react";
2
+ //#region src/primitives/Swatch.d.ts
3
+ export interface SwatchProps {
4
+ color: string;
5
+ label?: string;
6
+ matchKey?: string;
7
+ round?: boolean;
8
+ disabled?: boolean;
9
+ onSelect?: (color: string) => void;
10
+ className?: string;
11
+ }
12
+ export declare function Swatch(props: SwatchProps): React.ReactElement;
13
+ //#endregion
@@ -0,0 +1,21 @@
1
+ "use client";
2
+ import { cx } from "../core/context.js";
3
+ import "react";
4
+ import { jsx } from "react/jsx-runtime";
5
+ //#region src/primitives/Swatch.tsx
6
+ function Swatch(props) {
7
+ const { color, label, matchKey, round, disabled, onSelect, className } = props;
8
+ return /* @__PURE__ */ jsx("button", {
9
+ type: "button",
10
+ className: cx("cp-swatch", round === true && "cp-swatch-round", className),
11
+ style: { ["--cp-swatch-color"]: color },
12
+ "data-cp-color": matchKey ?? color,
13
+ "aria-label": label ?? color,
14
+ "aria-pressed": false,
15
+ disabled,
16
+ onClick: () => onSelect?.(color)
17
+ });
18
+ }
19
+ //#endregion
20
+ export { Swatch };
21
+
@@ -0,0 +1,63 @@
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/SwatchGrid.tsx
11
+ function SwatchGrid(props) {
12
+ const { swatches, columns = 10, variant = "spaced", round = false, label, className } = props;
13
+ const { store, disabled, classNames } = require_context.usePanel();
14
+ const gridRef = react.useRef(null);
15
+ const selected = react.useRef(null);
16
+ require_useColorStore.useTransientColor(store, (c) => {
17
+ const grid = gridRef.current;
18
+ if (grid === null) return;
19
+ const hex = require_serialize.toHex(c);
20
+ const next = grid.querySelector(`[data-cp-color="${hex}"]`);
21
+ if (next === selected.current) return;
22
+ selected.current?.setAttribute("aria-pressed", "false");
23
+ next?.setAttribute("aria-pressed", "true");
24
+ selected.current = next;
25
+ });
26
+ const handleClick = (event) => {
27
+ const target = event.target.closest("[data-cp-color]");
28
+ if (target === null) return;
29
+ const parsed = require_parse.parse(target.getAttribute("data-cp-color") ?? "");
30
+ if (parsed === null) return;
31
+ store.ingest(parsed);
32
+ store.commit();
33
+ };
34
+ const grid = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
35
+ ref: gridRef,
36
+ className: require_context.cx("cp-swatch-grid", variant === "spaced" && className),
37
+ style: { ["--cp-columns"]: columns },
38
+ "data-cp-variant": variant,
39
+ "data-cp-large": swatches.length > 1e3 ? "true" : void 0,
40
+ "aria-label": label,
41
+ onClick: handleClick,
42
+ children: swatches.map((swatch, index) => {
43
+ const key = require_parse.parse(swatch.color);
44
+ const match = key === null ? swatch.color : require_serialize.toHex(key);
45
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
46
+ type: "button",
47
+ className: require_context.cx("cp-swatch", round && "cp-swatch-round", classNames.swatch),
48
+ style: { ["--cp-swatch-color"]: swatch.color },
49
+ "data-cp-color": match,
50
+ "aria-label": swatch.name ?? swatch.color,
51
+ "aria-pressed": false,
52
+ disabled
53
+ }) }, `${swatch.color}-${index}`);
54
+ })
55
+ });
56
+ if (variant === "mosaic") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
57
+ className: require_context.cx("cp-mosaic", className),
58
+ children: grid
59
+ });
60
+ return grid;
61
+ }
62
+ //#endregion
63
+ exports.SwatchGrid = SwatchGrid;
@@ -0,0 +1,17 @@
1
+ import * as React from "react";
2
+ //#region src/primitives/SwatchGrid.d.ts
3
+ export interface SwatchEntry {
4
+ color: string;
5
+ name?: string;
6
+ }
7
+ export type SwatchVariant = "mosaic" | "spaced";
8
+ export interface SwatchGridProps {
9
+ swatches: SwatchEntry[];
10
+ columns?: number;
11
+ variant?: SwatchVariant;
12
+ round?: boolean;
13
+ label: string;
14
+ className?: string;
15
+ }
16
+ export declare function SwatchGrid(props: SwatchGridProps): React.ReactElement;
17
+ //#endregion
@@ -0,0 +1,17 @@
1
+ import * as React from "react";
2
+ //#region src/primitives/SwatchGrid.d.ts
3
+ export interface SwatchEntry {
4
+ color: string;
5
+ name?: string;
6
+ }
7
+ export type SwatchVariant = "mosaic" | "spaced";
8
+ export interface SwatchGridProps {
9
+ swatches: SwatchEntry[];
10
+ columns?: number;
11
+ variant?: SwatchVariant;
12
+ round?: boolean;
13
+ label: string;
14
+ className?: string;
15
+ }
16
+ export declare function SwatchGrid(props: SwatchGridProps): React.ReactElement;
17
+ //#endregion
@@ -0,0 +1,62 @@
1
+ "use client";
2
+ import { cx, usePanel } from "../core/context.js";
3
+ import { useTransientColor } from "../core/useColorStore.js";
4
+ import { parse } from "../color/parse.js";
5
+ import { toHex } from "../color/serialize.js";
6
+ import * as React from "react";
7
+ import { jsx } from "react/jsx-runtime";
8
+ //#region src/primitives/SwatchGrid.tsx
9
+ function SwatchGrid(props) {
10
+ const { swatches, columns = 10, variant = "spaced", round = false, label, className } = props;
11
+ const { store, disabled, classNames } = usePanel();
12
+ const gridRef = React.useRef(null);
13
+ const selected = React.useRef(null);
14
+ useTransientColor(store, (c) => {
15
+ const grid = gridRef.current;
16
+ if (grid === null) return;
17
+ const hex = toHex(c);
18
+ const next = grid.querySelector(`[data-cp-color="${hex}"]`);
19
+ if (next === selected.current) return;
20
+ selected.current?.setAttribute("aria-pressed", "false");
21
+ next?.setAttribute("aria-pressed", "true");
22
+ selected.current = next;
23
+ });
24
+ const handleClick = (event) => {
25
+ const target = event.target.closest("[data-cp-color]");
26
+ if (target === null) return;
27
+ const parsed = parse(target.getAttribute("data-cp-color") ?? "");
28
+ if (parsed === null) return;
29
+ store.ingest(parsed);
30
+ store.commit();
31
+ };
32
+ const grid = /* @__PURE__ */ jsx("ul", {
33
+ ref: gridRef,
34
+ className: cx("cp-swatch-grid", variant === "spaced" && className),
35
+ style: { ["--cp-columns"]: columns },
36
+ "data-cp-variant": variant,
37
+ "data-cp-large": swatches.length > 1e3 ? "true" : void 0,
38
+ "aria-label": label,
39
+ onClick: handleClick,
40
+ children: swatches.map((swatch, index) => {
41
+ const key = parse(swatch.color);
42
+ const match = key === null ? swatch.color : toHex(key);
43
+ return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("button", {
44
+ type: "button",
45
+ className: cx("cp-swatch", round && "cp-swatch-round", classNames.swatch),
46
+ style: { ["--cp-swatch-color"]: swatch.color },
47
+ "data-cp-color": match,
48
+ "aria-label": swatch.name ?? swatch.color,
49
+ "aria-pressed": false,
50
+ disabled
51
+ }) }, `${swatch.color}-${index}`);
52
+ })
53
+ });
54
+ if (variant === "mosaic") return /* @__PURE__ */ jsx("div", {
55
+ className: cx("cp-mosaic", className),
56
+ children: grid
57
+ });
58
+ return grid;
59
+ }
60
+ //#endregion
61
+ export { SwatchGrid };
62
+