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,128 @@
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
+ const require_store = require("../core/store.cjs");
8
+ const require_useFormControl = require("../core/useFormControl.cjs");
9
+ const require_styleInjector = require("../core/styleInjector.cjs");
10
+ const require_css = require("../styles/css.cjs");
11
+ const require_ChromaPanel = require("./ChromaPanel.cjs");
12
+ const require_Popover = require("./Popover.cjs");
13
+ let react = require("react");
14
+ react = require_runtime.__toESM(react, 1);
15
+ let react_jsx_runtime = require("react/jsx-runtime");
16
+ //#region src/components/ColorInput.tsx
17
+ function ColorInput(props) {
18
+ const { open, defaultOpen = false, onOpenChange, name, form, required = false, readOnly = false, autoComplete, validationBehavior = "native", id, "aria-label": ariaLabel = "Choose a colour", triggerClassName, disabled: disabledProp = false, className, classNames = {}, format = "hex", value, defaultValue = require_ChromaPanel.DEFAULT_COLOR, store: externalStore, mode, defaultMode, onModeChange, ...panelProps } = props;
19
+ const triggerId = require_context.useStableId("cp-trigger-");
20
+ const hiddenRef = react.useRef(null);
21
+ const fieldsetDisabled = require_useFormControl.useFieldsetDisabled(hiddenRef);
22
+ const disabled = disabledProp || fieldsetDisabled;
23
+ const [trigger, setTrigger] = react.useState(null);
24
+ const shouldInject = panelProps.injectStyles ?? true;
25
+ react.useEffect(() => {
26
+ if (shouldInject) require_styleInjector.injectStyles(require_css.css, "v2", trigger);
27
+ }, [shouldInject, trigger]);
28
+ const [internalOpen, setInternalOpen] = react.useState(defaultOpen);
29
+ const isOpen = open ?? internalOpen;
30
+ const setOpen = react.useCallback((next) => {
31
+ if (open === void 0) setInternalOpen(next);
32
+ onOpenChange?.(next);
33
+ }, [open, onOpenChange]);
34
+ const ownStore = react.useMemo(() => {
35
+ const seed = value ?? defaultValue;
36
+ const parsed = typeof seed === "string" ? require_parse.parse(seed) : seed;
37
+ return require_store.createColorStore(parsed ?? require_ChromaPanel.FALLBACK);
38
+ }, []);
39
+ const store = externalStore ?? ownStore;
40
+ const [internalMode, setInternalMode] = react.useState(defaultMode);
41
+ const activeMode = mode ?? internalMode;
42
+ const handleModeChange = react.useCallback((next) => {
43
+ if (mode === void 0) setInternalMode(next);
44
+ onModeChange?.(next);
45
+ }, [mode, onModeChange]);
46
+ const closeFromPanel = react.useCallback(() => {
47
+ setOpen(false);
48
+ trigger?.focus({ preventScroll: true });
49
+ }, [setOpen, trigger]);
50
+ const formatRef = react.useRef(format);
51
+ react.useEffect(() => {
52
+ formatRef.current = format;
53
+ });
54
+ require_useColorStore.useTransientColor(store, (c) => {
55
+ trigger?.style.setProperty("--cp-trigger-color", require_serialize.toRgbaString(c));
56
+ const hidden = hiddenRef.current;
57
+ if (hidden !== null) require_useFormControl.setNativeValue(hidden, require_serialize.toFormat(c, formatRef.current));
58
+ });
59
+ require_useFormControl.useFormReset(hiddenRef, () => {
60
+ const parsed = typeof defaultValue === "string" ? require_parse.parse(defaultValue) : defaultValue;
61
+ if (parsed !== null && parsed !== void 0) store.ingest(parsed);
62
+ });
63
+ require_useFormControl.useConstraintValidation(hiddenRef, {
64
+ behavior: validationBehavior,
65
+ required,
66
+ isEmpty: false,
67
+ focusTrigger: () => trigger?.focus()
68
+ });
69
+ const seed = store.get();
70
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
71
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
72
+ ref: setTrigger,
73
+ type: "button",
74
+ id: id ?? triggerId,
75
+ className: require_context.cx("cp-trigger", classNames.trigger, triggerClassName, className),
76
+ style: { ["--cp-trigger-color"]: require_serialize.toRgbaString(seed) },
77
+ "aria-label": ariaLabel,
78
+ "aria-haspopup": "dialog",
79
+ "aria-expanded": isOpen,
80
+ "aria-readonly": readOnly || void 0,
81
+ disabled,
82
+ onClick: () => {
83
+ if (!readOnly) setOpen(!isOpen);
84
+ }
85
+ }),
86
+ name !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
87
+ ref: hiddenRef,
88
+ type: "text",
89
+ name,
90
+ form,
91
+ defaultValue: require_serialize.toFormat(seed, format),
92
+ disabled,
93
+ required,
94
+ readOnly,
95
+ autoComplete,
96
+ tabIndex: -1,
97
+ "aria-hidden": "true",
98
+ style: require_useFormControl.visuallyHiddenInput,
99
+ onChange: () => {}
100
+ }),
101
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Popover.Popover, {
102
+ anchor: trigger,
103
+ open: isOpen,
104
+ onClose: () => setOpen(false),
105
+ className: classNames.popover,
106
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
107
+ className: "cp-dialog",
108
+ role: "dialog",
109
+ "aria-label": ariaLabel,
110
+ "aria-modal": "false",
111
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ChromaPanel.ChromaPanel, {
112
+ ...panelProps,
113
+ store,
114
+ value,
115
+ defaultValue,
116
+ format,
117
+ disabled: disabled || readOnly,
118
+ classNames,
119
+ mode: activeMode,
120
+ onModeChange: handleModeChange,
121
+ onClose: closeFromPanel
122
+ })
123
+ })
124
+ })
125
+ ] });
126
+ }
127
+ //#endregion
128
+ exports.ColorInput = ColorInput;
@@ -0,0 +1,19 @@
1
+ import { ChromaPanelProps } from "./ChromaPanel.cjs";
2
+ import * as React from "react";
3
+ //#region src/components/ColorInput.d.ts
4
+ export interface ColorInputProps extends ChromaPanelProps {
5
+ open?: boolean;
6
+ defaultOpen?: boolean;
7
+ onOpenChange?: (open: boolean) => void;
8
+ name?: string;
9
+ form?: string;
10
+ required?: boolean;
11
+ readOnly?: boolean;
12
+ autoComplete?: string;
13
+ validationBehavior?: "native" | "aria";
14
+ id?: string;
15
+ "aria-label"?: string;
16
+ triggerClassName?: string;
17
+ }
18
+ export declare function ColorInput(props: ColorInputProps): React.ReactElement;
19
+ //#endregion
@@ -0,0 +1,19 @@
1
+ import { ChromaPanelProps } from "./ChromaPanel.js";
2
+ import * as React from "react";
3
+ //#region src/components/ColorInput.d.ts
4
+ export interface ColorInputProps extends ChromaPanelProps {
5
+ open?: boolean;
6
+ defaultOpen?: boolean;
7
+ onOpenChange?: (open: boolean) => void;
8
+ name?: string;
9
+ form?: string;
10
+ required?: boolean;
11
+ readOnly?: boolean;
12
+ autoComplete?: string;
13
+ validationBehavior?: "native" | "aria";
14
+ id?: string;
15
+ "aria-label"?: string;
16
+ triggerClassName?: string;
17
+ }
18
+ export declare function ColorInput(props: ColorInputProps): React.ReactElement;
19
+ //#endregion
@@ -0,0 +1,127 @@
1
+ "use client";
2
+ import { cx, useStableId } from "../core/context.js";
3
+ import { useTransientColor } from "../core/useColorStore.js";
4
+ import { parse } from "../color/parse.js";
5
+ import { toFormat, toRgbaString } from "../color/serialize.js";
6
+ import { createColorStore } from "../core/store.js";
7
+ import { setNativeValue, useConstraintValidation, useFieldsetDisabled, useFormReset, visuallyHiddenInput } from "../core/useFormControl.js";
8
+ import { injectStyles } from "../core/styleInjector.js";
9
+ import { css } from "../styles/css.js";
10
+ import { ChromaPanel, DEFAULT_COLOR, FALLBACK } from "./ChromaPanel.js";
11
+ import { Popover } from "./Popover.js";
12
+ import * as React from "react";
13
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
14
+ //#region src/components/ColorInput.tsx
15
+ function ColorInput(props) {
16
+ const { open, defaultOpen = false, onOpenChange, name, form, required = false, readOnly = false, autoComplete, validationBehavior = "native", id, "aria-label": ariaLabel = "Choose a colour", triggerClassName, disabled: disabledProp = false, className, classNames = {}, format = "hex", value, defaultValue = DEFAULT_COLOR, store: externalStore, mode, defaultMode, onModeChange, ...panelProps } = props;
17
+ const triggerId = useStableId("cp-trigger-");
18
+ const hiddenRef = React.useRef(null);
19
+ const fieldsetDisabled = useFieldsetDisabled(hiddenRef);
20
+ const disabled = disabledProp || fieldsetDisabled;
21
+ const [trigger, setTrigger] = React.useState(null);
22
+ const shouldInject = panelProps.injectStyles ?? true;
23
+ React.useEffect(() => {
24
+ if (shouldInject) injectStyles(css, "v2", trigger);
25
+ }, [shouldInject, trigger]);
26
+ const [internalOpen, setInternalOpen] = React.useState(defaultOpen);
27
+ const isOpen = open ?? internalOpen;
28
+ const setOpen = React.useCallback((next) => {
29
+ if (open === void 0) setInternalOpen(next);
30
+ onOpenChange?.(next);
31
+ }, [open, onOpenChange]);
32
+ const ownStore = React.useMemo(() => {
33
+ const seed = value ?? defaultValue;
34
+ const parsed = typeof seed === "string" ? parse(seed) : seed;
35
+ return createColorStore(parsed ?? FALLBACK);
36
+ }, []);
37
+ const store = externalStore ?? ownStore;
38
+ const [internalMode, setInternalMode] = React.useState(defaultMode);
39
+ const activeMode = mode ?? internalMode;
40
+ const handleModeChange = React.useCallback((next) => {
41
+ if (mode === void 0) setInternalMode(next);
42
+ onModeChange?.(next);
43
+ }, [mode, onModeChange]);
44
+ const closeFromPanel = React.useCallback(() => {
45
+ setOpen(false);
46
+ trigger?.focus({ preventScroll: true });
47
+ }, [setOpen, trigger]);
48
+ const formatRef = React.useRef(format);
49
+ React.useEffect(() => {
50
+ formatRef.current = format;
51
+ });
52
+ useTransientColor(store, (c) => {
53
+ trigger?.style.setProperty("--cp-trigger-color", toRgbaString(c));
54
+ const hidden = hiddenRef.current;
55
+ if (hidden !== null) setNativeValue(hidden, toFormat(c, formatRef.current));
56
+ });
57
+ useFormReset(hiddenRef, () => {
58
+ const parsed = typeof defaultValue === "string" ? parse(defaultValue) : defaultValue;
59
+ if (parsed !== null && parsed !== void 0) store.ingest(parsed);
60
+ });
61
+ useConstraintValidation(hiddenRef, {
62
+ behavior: validationBehavior,
63
+ required,
64
+ isEmpty: false,
65
+ focusTrigger: () => trigger?.focus()
66
+ });
67
+ const seed = store.get();
68
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
69
+ /* @__PURE__ */ jsx("button", {
70
+ ref: setTrigger,
71
+ type: "button",
72
+ id: id ?? triggerId,
73
+ className: cx("cp-trigger", classNames.trigger, triggerClassName, className),
74
+ style: { ["--cp-trigger-color"]: toRgbaString(seed) },
75
+ "aria-label": ariaLabel,
76
+ "aria-haspopup": "dialog",
77
+ "aria-expanded": isOpen,
78
+ "aria-readonly": readOnly || void 0,
79
+ disabled,
80
+ onClick: () => {
81
+ if (!readOnly) setOpen(!isOpen);
82
+ }
83
+ }),
84
+ name !== void 0 && /* @__PURE__ */ jsx("input", {
85
+ ref: hiddenRef,
86
+ type: "text",
87
+ name,
88
+ form,
89
+ defaultValue: toFormat(seed, format),
90
+ disabled,
91
+ required,
92
+ readOnly,
93
+ autoComplete,
94
+ tabIndex: -1,
95
+ "aria-hidden": "true",
96
+ style: visuallyHiddenInput,
97
+ onChange: () => {}
98
+ }),
99
+ /* @__PURE__ */ jsx(Popover, {
100
+ anchor: trigger,
101
+ open: isOpen,
102
+ onClose: () => setOpen(false),
103
+ className: classNames.popover,
104
+ children: /* @__PURE__ */ jsx("div", {
105
+ className: "cp-dialog",
106
+ role: "dialog",
107
+ "aria-label": ariaLabel,
108
+ "aria-modal": "false",
109
+ children: /* @__PURE__ */ jsx(ChromaPanel, {
110
+ ...panelProps,
111
+ store,
112
+ value,
113
+ defaultValue,
114
+ format,
115
+ disabled: disabled || readOnly,
116
+ classNames,
117
+ mode: activeMode,
118
+ onModeChange: handleModeChange,
119
+ onClose: closeFromPanel
120
+ })
121
+ })
122
+ })
123
+ ] });
124
+ }
125
+ //#endregion
126
+ export { ColorInput };
127
+
@@ -0,0 +1,33 @@
1
+ "use client";
2
+ const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
3
+ const require_context = require("../core/context.cjs");
4
+ const require_SegmentedControl = require("../primitives/SegmentedControl.cjs");
5
+ let react = require("react");
6
+ react = require_runtime.__toESM(react, 1);
7
+ let react_jsx_runtime = require("react/jsx-runtime");
8
+ //#region src/components/ModeToolbar.tsx
9
+ function ModeToolbar(props) {
10
+ const { modes, activeId, onSelect } = props;
11
+ const { classNames, idPrefix, disabled } = require_context.usePanel();
12
+ const items = react.useMemo(() => modes.map((mode) => {
13
+ const Icon = mode.icon;
14
+ return {
15
+ id: mode.id,
16
+ label: mode.label,
17
+ content: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {})
18
+ };
19
+ }), [modes]);
20
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_SegmentedControl.SegmentedControl, {
21
+ items,
22
+ value: activeId,
23
+ onChange: onSelect,
24
+ ariaLabel: "Picker mode",
25
+ disabled,
26
+ segmentId: (id) => `${idPrefix}-tab-${id}`,
27
+ controls: (id) => `${idPrefix}-panel-${id}`,
28
+ className: require_context.cx("cp-toolbar", classNames.toolbar),
29
+ tabClassName: require_context.cx(classNames.tab)
30
+ });
31
+ }
32
+ //#endregion
33
+ exports.ModeToolbar = ModeToolbar;
@@ -0,0 +1,10 @@
1
+ import { PickerMode } from "../modes/registry.cjs";
2
+ import * as React from "react";
3
+ //#region src/components/ModeToolbar.d.ts
4
+ export interface ModeToolbarProps {
5
+ modes: PickerMode[];
6
+ activeId: string;
7
+ onSelect: (id: string) => void;
8
+ }
9
+ export declare function ModeToolbar(props: ModeToolbarProps): React.ReactElement;
10
+ //#endregion
@@ -0,0 +1,10 @@
1
+ import { PickerMode } from "../modes/registry.js";
2
+ import * as React from "react";
3
+ //#region src/components/ModeToolbar.d.ts
4
+ export interface ModeToolbarProps {
5
+ modes: PickerMode[];
6
+ activeId: string;
7
+ onSelect: (id: string) => void;
8
+ }
9
+ export declare function ModeToolbar(props: ModeToolbarProps): React.ReactElement;
10
+ //#endregion
@@ -0,0 +1,32 @@
1
+ "use client";
2
+ import { cx, usePanel } from "../core/context.js";
3
+ import { SegmentedControl } from "../primitives/SegmentedControl.js";
4
+ import * as React from "react";
5
+ import { jsx } from "react/jsx-runtime";
6
+ //#region src/components/ModeToolbar.tsx
7
+ function ModeToolbar(props) {
8
+ const { modes, activeId, onSelect } = props;
9
+ const { classNames, idPrefix, disabled } = usePanel();
10
+ const items = React.useMemo(() => modes.map((mode) => {
11
+ const Icon = mode.icon;
12
+ return {
13
+ id: mode.id,
14
+ label: mode.label,
15
+ content: /* @__PURE__ */ jsx(Icon, {})
16
+ };
17
+ }), [modes]);
18
+ return /* @__PURE__ */ jsx(SegmentedControl, {
19
+ items,
20
+ value: activeId,
21
+ onChange: onSelect,
22
+ ariaLabel: "Picker mode",
23
+ disabled,
24
+ segmentId: (id) => `${idPrefix}-tab-${id}`,
25
+ controls: (id) => `${idPrefix}-panel-${id}`,
26
+ className: cx("cp-toolbar", classNames.toolbar),
27
+ tabClassName: cx(classNames.tab)
28
+ });
29
+ }
30
+ //#endregion
31
+ export { ModeToolbar };
32
+
@@ -0,0 +1,82 @@
1
+ "use client";
2
+ const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
3
+ const require_context = require("../core/context.cjs");
4
+ const require_parse = require("../color/parse.cjs");
5
+ const require_serialize = require("../color/serialize.cjs");
6
+ const require_icons = require("../primitives/icons.cjs");
7
+ const require_useScrollFade = require("../core/useScrollFade.cjs");
8
+ const require_useEyedropper = require("../primitives/useEyedropper.cjs");
9
+ let react = require("react");
10
+ react = require_runtime.__toESM(react, 1);
11
+ let react_jsx_runtime = require("react/jsx-runtime");
12
+ //#region src/components/PanelFooter.tsx
13
+ function PanelFooter() {
14
+ const { store, classNames, options, disabled } = require_context.usePanel();
15
+ const { supported, pick } = require_useEyedropper.useEyedropper();
16
+ const handlePick = async () => {
17
+ const hex = await pick();
18
+ if (hex === null) return;
19
+ const parsed = require_parse.parse(hex);
20
+ if (parsed === null) return;
21
+ store.ingest(parsed);
22
+ store.commit();
23
+ };
24
+ const recentsRef = react.useRef(null);
25
+ const [current, setCurrent] = react.useState(null);
26
+ react.useEffect(() => store.subscribeCommit((c) => setCurrent(require_serialize.toHex(c).toLowerCase())), [store]);
27
+ const recents = options.showRecentColors ? options.recentColors.filter((color) => {
28
+ if (current === null) return true;
29
+ const parsed = require_parse.parse(color);
30
+ return (parsed === null ? color : require_serialize.toHex(parsed)).toLowerCase() !== current;
31
+ }).slice(0, 10) : [];
32
+ const showEyedropper = options.showEyedropper && supported;
33
+ require_useScrollFade.useScrollFade(recentsRef, recents.length, "x");
34
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
35
+ className: require_context.cx("cp-footer", classNames.footer),
36
+ children: [
37
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
38
+ className: "cp-preview",
39
+ "aria-hidden": "true"
40
+ }),
41
+ recents.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
42
+ ref: recentsRef,
43
+ className: "cp-recents",
44
+ "aria-label": "Recent colours",
45
+ children: recents.map((color, index) => /* @__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", "cp-swatch-round", classNames.swatch),
48
+ style: { ["--cp-swatch-color"]: color },
49
+ "aria-label": `Recent colour ${color}`,
50
+ disabled,
51
+ onClick: () => {
52
+ const parsed = require_parse.parse(color);
53
+ if (parsed === null) return;
54
+ store.ingest(parsed);
55
+ store.commit();
56
+ }
57
+ }) }, `${color}-${index}`))
58
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "cp-footer-spacer" }),
59
+ showEyedropper && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
60
+ type: "button",
61
+ className: "cp-icon-button",
62
+ "aria-label": "Pick a colour from the screen",
63
+ title: "Pick a colour from the screen",
64
+ disabled,
65
+ onClick: () => {
66
+ handlePick();
67
+ },
68
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_icons.EyedropperIcon, {})
69
+ })
70
+ ]
71
+ });
72
+ }
73
+ function pushRecent(list, hex, limit = 10) {
74
+ const key = hex.toLowerCase();
75
+ return [hex, ...list.filter((c) => {
76
+ const parsed = require_parse.parse(c);
77
+ return parsed === null ? c.toLowerCase() !== key : require_serialize.toHex(parsed).toLowerCase() !== key;
78
+ })].slice(0, limit);
79
+ }
80
+ //#endregion
81
+ exports.PanelFooter = PanelFooter;
82
+ exports.pushRecent = pushRecent;
@@ -0,0 +1,5 @@
1
+ import * as React from "react";
2
+ //#region src/components/PanelFooter.d.ts
3
+ export declare function PanelFooter(): React.ReactElement | null;
4
+ export declare function pushRecent(list: string[], hex: string, limit?: number): string[];
5
+ //#endregion
@@ -0,0 +1,5 @@
1
+ import * as React from "react";
2
+ //#region src/components/PanelFooter.d.ts
3
+ export declare function PanelFooter(): React.ReactElement | null;
4
+ export declare function pushRecent(list: string[], hex: string, limit?: number): string[];
5
+ //#endregion
@@ -0,0 +1,80 @@
1
+ "use client";
2
+ import { cx, usePanel } from "../core/context.js";
3
+ import { parse } from "../color/parse.js";
4
+ import { toHex } from "../color/serialize.js";
5
+ import { EyedropperIcon } from "../primitives/icons.js";
6
+ import { useScrollFade } from "../core/useScrollFade.js";
7
+ import { useEyedropper } from "../primitives/useEyedropper.js";
8
+ import * as React from "react";
9
+ import { jsx, jsxs } from "react/jsx-runtime";
10
+ //#region src/components/PanelFooter.tsx
11
+ function PanelFooter() {
12
+ const { store, classNames, options, disabled } = usePanel();
13
+ const { supported, pick } = useEyedropper();
14
+ const handlePick = async () => {
15
+ const hex = await pick();
16
+ if (hex === null) return;
17
+ const parsed = parse(hex);
18
+ if (parsed === null) return;
19
+ store.ingest(parsed);
20
+ store.commit();
21
+ };
22
+ const recentsRef = React.useRef(null);
23
+ const [current, setCurrent] = React.useState(null);
24
+ React.useEffect(() => store.subscribeCommit((c) => setCurrent(toHex(c).toLowerCase())), [store]);
25
+ const recents = options.showRecentColors ? options.recentColors.filter((color) => {
26
+ if (current === null) return true;
27
+ const parsed = parse(color);
28
+ return (parsed === null ? color : toHex(parsed)).toLowerCase() !== current;
29
+ }).slice(0, 10) : [];
30
+ const showEyedropper = options.showEyedropper && supported;
31
+ useScrollFade(recentsRef, recents.length, "x");
32
+ return /* @__PURE__ */ jsxs("div", {
33
+ className: cx("cp-footer", classNames.footer),
34
+ children: [
35
+ /* @__PURE__ */ jsx("div", {
36
+ className: "cp-preview",
37
+ "aria-hidden": "true"
38
+ }),
39
+ recents.length > 0 ? /* @__PURE__ */ jsx("ul", {
40
+ ref: recentsRef,
41
+ className: "cp-recents",
42
+ "aria-label": "Recent colours",
43
+ children: recents.map((color, index) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("button", {
44
+ type: "button",
45
+ className: cx("cp-swatch", "cp-swatch-round", classNames.swatch),
46
+ style: { ["--cp-swatch-color"]: color },
47
+ "aria-label": `Recent colour ${color}`,
48
+ disabled,
49
+ onClick: () => {
50
+ const parsed = parse(color);
51
+ if (parsed === null) return;
52
+ store.ingest(parsed);
53
+ store.commit();
54
+ }
55
+ }) }, `${color}-${index}`))
56
+ }) : /* @__PURE__ */ jsx("div", { className: "cp-footer-spacer" }),
57
+ showEyedropper && /* @__PURE__ */ jsx("button", {
58
+ type: "button",
59
+ className: "cp-icon-button",
60
+ "aria-label": "Pick a colour from the screen",
61
+ title: "Pick a colour from the screen",
62
+ disabled,
63
+ onClick: () => {
64
+ handlePick();
65
+ },
66
+ children: /* @__PURE__ */ jsx(EyedropperIcon, {})
67
+ })
68
+ ]
69
+ });
70
+ }
71
+ function pushRecent(list, hex, limit = 10) {
72
+ const key = hex.toLowerCase();
73
+ return [hex, ...list.filter((c) => {
74
+ const parsed = parse(c);
75
+ return parsed === null ? c.toLowerCase() !== key : toHex(parsed).toLowerCase() !== key;
76
+ })].slice(0, limit);
77
+ }
78
+ //#endregion
79
+ export { PanelFooter, pushRecent };
80
+