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,154 @@
1
+ "use client";
2
+ const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
3
+ const require_context = require("../core/context.cjs");
4
+ const require_useMediaQuery = require("../core/useMediaQuery.cjs");
5
+ let react = require("react");
6
+ react = require_runtime.__toESM(react, 1);
7
+ let react_jsx_runtime = require("react/jsx-runtime");
8
+ let react_dom = require("react-dom");
9
+ //#region src/components/Popover.tsx
10
+ const MARGIN = 8;
11
+ const MIN_AVAILABLE = 160;
12
+ const FOCUSABLE = "a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex=\"-1\"])";
13
+ function Popover(props) {
14
+ const { anchor, open, onClose, offset = 8, sheetOnMobile = true, className, children } = props;
15
+ const panelRef = react.useRef(null);
16
+ const [position, setPosition] = react.useState(null);
17
+ const compact = require_useMediaQuery.useMediaQuery(require_useMediaQuery.COMPACT_QUERY);
18
+ const asSheet = sheetOnMobile && compact;
19
+ const [mounted, setMounted] = react.useState(false);
20
+ react.useEffect(() => setMounted(true), []);
21
+ const place = react.useCallback(() => {
22
+ const panel = panelRef.current;
23
+ if (anchor === null || panel === null) return;
24
+ const a = anchor.getBoundingClientRect();
25
+ const p = panel.getBoundingClientRect();
26
+ const below = window.innerHeight - a.bottom - offset - MARGIN;
27
+ const above = a.top - offset - MARGIN;
28
+ let top;
29
+ let available;
30
+ if (p.height <= below || below >= above && p.height > above) {
31
+ top = a.bottom + offset;
32
+ available = below;
33
+ } else {
34
+ available = above;
35
+ top = Math.max(MARGIN, a.top - offset - p.height);
36
+ }
37
+ let left = a.left;
38
+ const maxLeft = window.innerWidth - p.width - MARGIN;
39
+ if (left > maxLeft) left = Math.max(MARGIN, maxLeft);
40
+ if (left < MARGIN) left = MARGIN;
41
+ setPosition({
42
+ top: top + window.scrollY,
43
+ left: left + window.scrollX,
44
+ available: Math.max(available, MIN_AVAILABLE)
45
+ });
46
+ }, [anchor, offset]);
47
+ react.useLayoutEffect(() => {
48
+ if (!open || asSheet) {
49
+ setPosition(null);
50
+ return;
51
+ }
52
+ place();
53
+ window.addEventListener("scroll", place, true);
54
+ window.addEventListener("resize", place);
55
+ return () => {
56
+ window.removeEventListener("scroll", place, true);
57
+ window.removeEventListener("resize", place);
58
+ };
59
+ }, [
60
+ open,
61
+ asSheet,
62
+ place
63
+ ]);
64
+ const hasFocused = react.useRef(false);
65
+ const visible = asSheet || position !== null;
66
+ react.useEffect(() => {
67
+ if (!open) {
68
+ hasFocused.current = false;
69
+ return;
70
+ }
71
+ const panel = panelRef.current;
72
+ if (panel === null || !visible || hasFocused.current) return;
73
+ hasFocused.current = true;
74
+ const previous = document.activeElement;
75
+ (panel.querySelector(FOCUSABLE) ?? panel).focus({ preventScroll: true });
76
+ return () => {
77
+ if (panel.contains(document.activeElement)) previous?.focus({ preventScroll: true });
78
+ };
79
+ }, [open, visible]);
80
+ react.useEffect(() => {
81
+ if (!open) return;
82
+ const onKeyDown = (event) => {
83
+ if (event.key === "Escape") {
84
+ event.stopPropagation();
85
+ onClose();
86
+ anchor?.focus({ preventScroll: true });
87
+ return;
88
+ }
89
+ if (event.key !== "Tab") return;
90
+ const panel = panelRef.current;
91
+ if (panel === null) return;
92
+ const items = Array.from(panel.querySelectorAll(FOCUSABLE)).filter((el) => el.offsetParent !== null || el === document.activeElement);
93
+ if (items.length === 0) return;
94
+ const first = items[0];
95
+ const last = items[items.length - 1];
96
+ if (event.shiftKey && document.activeElement === first) {
97
+ event.preventDefault();
98
+ last.focus();
99
+ } else if (!event.shiftKey && document.activeElement === last) {
100
+ event.preventDefault();
101
+ first.focus();
102
+ }
103
+ };
104
+ const onPointerDown = (event) => {
105
+ const target = event.target;
106
+ if (panelRef.current?.contains(target) === true) return;
107
+ if (anchor?.contains(target) === true) return;
108
+ onClose();
109
+ };
110
+ document.addEventListener("keydown", onKeyDown, true);
111
+ document.addEventListener("pointerdown", onPointerDown, true);
112
+ return () => {
113
+ document.removeEventListener("keydown", onKeyDown, true);
114
+ document.removeEventListener("pointerdown", onPointerDown, true);
115
+ };
116
+ }, [
117
+ open,
118
+ onClose,
119
+ anchor
120
+ ]);
121
+ if (!open || !mounted) return null;
122
+ if (asSheet) return (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
123
+ className: "cp-sheet-root",
124
+ "data-cp-open": "true",
125
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
126
+ className: "cp-scrim",
127
+ "aria-hidden": "true"
128
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
129
+ ref: panelRef,
130
+ className: require_context.cx("cp-sheet", className),
131
+ tabIndex: -1,
132
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
133
+ type: "button",
134
+ className: "cp-grabber",
135
+ "aria-label": "Close",
136
+ onClick: onClose
137
+ }), children]
138
+ })]
139
+ }), document.body);
140
+ return (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
141
+ ref: panelRef,
142
+ className: require_context.cx("cp-popover", className),
143
+ tabIndex: -1,
144
+ style: {
145
+ top: position?.top ?? 0,
146
+ left: position?.left ?? 0,
147
+ visibility: position === null ? "hidden" : "visible",
148
+ ...position === null ? null : { ["--cp-available-h"]: `${position.available}px` }
149
+ },
150
+ children
151
+ }), document.body);
152
+ }
153
+ //#endregion
154
+ exports.Popover = Popover;
@@ -0,0 +1,13 @@
1
+ import * as React from "react";
2
+ //#region src/components/Popover.d.ts
3
+ export interface PopoverProps {
4
+ anchor: HTMLElement | null;
5
+ open: boolean;
6
+ onClose: () => void;
7
+ offset?: number;
8
+ sheetOnMobile?: boolean;
9
+ className?: string;
10
+ children: React.ReactNode;
11
+ }
12
+ export declare function Popover(props: PopoverProps): React.ReactElement | null;
13
+ //#endregion
@@ -0,0 +1,13 @@
1
+ import * as React from "react";
2
+ //#region src/components/Popover.d.ts
3
+ export interface PopoverProps {
4
+ anchor: HTMLElement | null;
5
+ open: boolean;
6
+ onClose: () => void;
7
+ offset?: number;
8
+ sheetOnMobile?: boolean;
9
+ className?: string;
10
+ children: React.ReactNode;
11
+ }
12
+ export declare function Popover(props: PopoverProps): React.ReactElement | null;
13
+ //#endregion
@@ -0,0 +1,153 @@
1
+ "use client";
2
+ import { cx } from "../core/context.js";
3
+ import { COMPACT_QUERY, useMediaQuery } from "../core/useMediaQuery.js";
4
+ import * as React from "react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { createPortal } from "react-dom";
7
+ //#region src/components/Popover.tsx
8
+ const MARGIN = 8;
9
+ const MIN_AVAILABLE = 160;
10
+ const FOCUSABLE = "a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex=\"-1\"])";
11
+ function Popover(props) {
12
+ const { anchor, open, onClose, offset = 8, sheetOnMobile = true, className, children } = props;
13
+ const panelRef = React.useRef(null);
14
+ const [position, setPosition] = React.useState(null);
15
+ const compact = useMediaQuery(COMPACT_QUERY);
16
+ const asSheet = sheetOnMobile && compact;
17
+ const [mounted, setMounted] = React.useState(false);
18
+ React.useEffect(() => setMounted(true), []);
19
+ const place = React.useCallback(() => {
20
+ const panel = panelRef.current;
21
+ if (anchor === null || panel === null) return;
22
+ const a = anchor.getBoundingClientRect();
23
+ const p = panel.getBoundingClientRect();
24
+ const below = window.innerHeight - a.bottom - offset - MARGIN;
25
+ const above = a.top - offset - MARGIN;
26
+ let top;
27
+ let available;
28
+ if (p.height <= below || below >= above && p.height > above) {
29
+ top = a.bottom + offset;
30
+ available = below;
31
+ } else {
32
+ available = above;
33
+ top = Math.max(MARGIN, a.top - offset - p.height);
34
+ }
35
+ let left = a.left;
36
+ const maxLeft = window.innerWidth - p.width - MARGIN;
37
+ if (left > maxLeft) left = Math.max(MARGIN, maxLeft);
38
+ if (left < MARGIN) left = MARGIN;
39
+ setPosition({
40
+ top: top + window.scrollY,
41
+ left: left + window.scrollX,
42
+ available: Math.max(available, MIN_AVAILABLE)
43
+ });
44
+ }, [anchor, offset]);
45
+ React.useLayoutEffect(() => {
46
+ if (!open || asSheet) {
47
+ setPosition(null);
48
+ return;
49
+ }
50
+ place();
51
+ window.addEventListener("scroll", place, true);
52
+ window.addEventListener("resize", place);
53
+ return () => {
54
+ window.removeEventListener("scroll", place, true);
55
+ window.removeEventListener("resize", place);
56
+ };
57
+ }, [
58
+ open,
59
+ asSheet,
60
+ place
61
+ ]);
62
+ const hasFocused = React.useRef(false);
63
+ const visible = asSheet || position !== null;
64
+ React.useEffect(() => {
65
+ if (!open) {
66
+ hasFocused.current = false;
67
+ return;
68
+ }
69
+ const panel = panelRef.current;
70
+ if (panel === null || !visible || hasFocused.current) return;
71
+ hasFocused.current = true;
72
+ const previous = document.activeElement;
73
+ (panel.querySelector(FOCUSABLE) ?? panel).focus({ preventScroll: true });
74
+ return () => {
75
+ if (panel.contains(document.activeElement)) previous?.focus({ preventScroll: true });
76
+ };
77
+ }, [open, visible]);
78
+ React.useEffect(() => {
79
+ if (!open) return;
80
+ const onKeyDown = (event) => {
81
+ if (event.key === "Escape") {
82
+ event.stopPropagation();
83
+ onClose();
84
+ anchor?.focus({ preventScroll: true });
85
+ return;
86
+ }
87
+ if (event.key !== "Tab") return;
88
+ const panel = panelRef.current;
89
+ if (panel === null) return;
90
+ const items = Array.from(panel.querySelectorAll(FOCUSABLE)).filter((el) => el.offsetParent !== null || el === document.activeElement);
91
+ if (items.length === 0) return;
92
+ const first = items[0];
93
+ const last = items[items.length - 1];
94
+ if (event.shiftKey && document.activeElement === first) {
95
+ event.preventDefault();
96
+ last.focus();
97
+ } else if (!event.shiftKey && document.activeElement === last) {
98
+ event.preventDefault();
99
+ first.focus();
100
+ }
101
+ };
102
+ const onPointerDown = (event) => {
103
+ const target = event.target;
104
+ if (panelRef.current?.contains(target) === true) return;
105
+ if (anchor?.contains(target) === true) return;
106
+ onClose();
107
+ };
108
+ document.addEventListener("keydown", onKeyDown, true);
109
+ document.addEventListener("pointerdown", onPointerDown, true);
110
+ return () => {
111
+ document.removeEventListener("keydown", onKeyDown, true);
112
+ document.removeEventListener("pointerdown", onPointerDown, true);
113
+ };
114
+ }, [
115
+ open,
116
+ onClose,
117
+ anchor
118
+ ]);
119
+ if (!open || !mounted) return null;
120
+ if (asSheet) return createPortal(/* @__PURE__ */ jsxs("div", {
121
+ className: "cp-sheet-root",
122
+ "data-cp-open": "true",
123
+ children: [/* @__PURE__ */ jsx("div", {
124
+ className: "cp-scrim",
125
+ "aria-hidden": "true"
126
+ }), /* @__PURE__ */ jsxs("div", {
127
+ ref: panelRef,
128
+ className: cx("cp-sheet", className),
129
+ tabIndex: -1,
130
+ children: [/* @__PURE__ */ jsx("button", {
131
+ type: "button",
132
+ className: "cp-grabber",
133
+ "aria-label": "Close",
134
+ onClick: onClose
135
+ }), children]
136
+ })]
137
+ }), document.body);
138
+ return createPortal(/* @__PURE__ */ jsx("div", {
139
+ ref: panelRef,
140
+ className: cx("cp-popover", className),
141
+ tabIndex: -1,
142
+ style: {
143
+ top: position?.top ?? 0,
144
+ left: position?.left ?? 0,
145
+ visibility: position === null ? "hidden" : "visible",
146
+ ...position === null ? null : { ["--cp-available-h"]: `${position.available}px` }
147
+ },
148
+ children
149
+ }), document.body);
150
+ }
151
+ //#endregion
152
+ export { Popover };
153
+
@@ -0,0 +1,10 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_contrast = require("./a11y/contrast.cjs");
3
+ exports.apcaContrast = require_contrast.apcaContrast;
4
+ exports.contrastRatio = require_contrast.contrastRatio;
5
+ exports.contrastReport = require_contrast.contrastReport;
6
+ exports.meetsContrast = require_contrast.meetsContrast;
7
+ exports.meetsNonTextContrast = require_contrast.meetsNonTextContrast;
8
+ exports.readableTextColor = require_contrast.readableTextColor;
9
+ exports.relativeLuminance = require_contrast.relativeLuminance;
10
+ exports.wcagLevel = require_contrast.wcagLevel;
@@ -0,0 +1,2 @@
1
+ import { ContrastOptions, ContrastReport, TextSize, WcagLevel, apcaContrast, contrastRatio, contrastReport, meetsContrast, meetsNonTextContrast, readableTextColor, relativeLuminance, wcagLevel } from "./a11y/contrast.cjs";
2
+ export { type ContrastOptions, type ContrastReport, type TextSize, type WcagLevel, apcaContrast, contrastRatio, contrastReport, meetsContrast, meetsNonTextContrast, readableTextColor, relativeLuminance, wcagLevel };
@@ -0,0 +1,2 @@
1
+ import { ContrastOptions, ContrastReport, TextSize, WcagLevel, apcaContrast, contrastRatio, contrastReport, meetsContrast, meetsNonTextContrast, readableTextColor, relativeLuminance, wcagLevel } from "./a11y/contrast.js";
2
+ export { type ContrastOptions, type ContrastReport, type TextSize, type WcagLevel, apcaContrast, contrastRatio, contrastReport, meetsContrast, meetsNonTextContrast, readableTextColor, relativeLuminance, wcagLevel };
@@ -0,0 +1,2 @@
1
+ import { apcaContrast, contrastRatio, contrastReport, meetsContrast, meetsNonTextContrast, readableTextColor, relativeLuminance, wcagLevel } from "./a11y/contrast.js";
2
+ export { apcaContrast, contrastRatio, contrastReport, meetsContrast, meetsNonTextContrast, readableTextColor, relativeLuminance, wcagLevel };
@@ -0,0 +1,30 @@
1
+ "use client";
2
+ const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
3
+ let react = require("react");
4
+ react = require_runtime.__toESM(react, 1);
5
+ //#region src/core/context.ts
6
+ const PanelContext = react.createContext(null);
7
+ const PanelProvider = PanelContext.Provider;
8
+ function usePanel() {
9
+ const value = react.useContext(PanelContext);
10
+ if (value === null) throw new Error("chroma-panel: this component must be rendered inside <ChromaPanel> or <ColorInput>.");
11
+ return value;
12
+ }
13
+ function cx(...parts) {
14
+ let out = "";
15
+ for (const part of parts) if (typeof part === "string" && part !== "") out = out === "" ? part : out + " " + part;
16
+ return out;
17
+ }
18
+ let idCounter = 0;
19
+ function useStableId(prefix) {
20
+ const reactUseId = react.useId;
21
+ if (typeof reactUseId === "function") return prefix + reactUseId().replace(/:/g, "");
22
+ const ref = react.useRef(null);
23
+ if (ref.current === null) ref.current = prefix + String(++idCounter);
24
+ return ref.current;
25
+ }
26
+ //#endregion
27
+ exports.PanelProvider = PanelProvider;
28
+ exports.cx = cx;
29
+ exports.usePanel = usePanel;
30
+ exports.useStableId = useStableId;
@@ -0,0 +1,43 @@
1
+ import { ColorStore } from "./store.cjs";
2
+ import "react";
3
+ //#region src/core/context.d.ts
4
+ export interface ChromaClassNames {
5
+ root?: string;
6
+ titlebar?: string;
7
+ toolbar?: string;
8
+ tab?: string;
9
+ panel?: string;
10
+ footer?: string;
11
+ swatch?: string;
12
+ slider?: string;
13
+ thumb?: string;
14
+ field?: string;
15
+ trigger?: string;
16
+ popover?: string;
17
+ }
18
+ export interface ColorPalette {
19
+ name: string;
20
+ colors: (string | {
21
+ color: string;
22
+ name?: string;
23
+ })[];
24
+ }
25
+ export interface PanelOptions {
26
+ modeProps: Record<string, Record<string, unknown>>;
27
+ palettes: ColorPalette[] | undefined;
28
+ pencils: string[] | undefined;
29
+ showAlpha: boolean;
30
+ showEyedropper: boolean;
31
+ showRecentColors: boolean;
32
+ recentColors: string[];
33
+ onRecentColorsChange?: (colors: string[]) => void;
34
+ }
35
+ export interface PanelContextValue {
36
+ store: ColorStore;
37
+ disabled: boolean;
38
+ classNames: ChromaClassNames;
39
+ options: PanelOptions;
40
+ idPrefix: string;
41
+ }
42
+ export declare function usePanel(): PanelContextValue;
43
+ //#endregion
@@ -0,0 +1,43 @@
1
+ import { ColorStore } from "./store.js";
2
+ import "react";
3
+ //#region src/core/context.d.ts
4
+ export interface ChromaClassNames {
5
+ root?: string;
6
+ titlebar?: string;
7
+ toolbar?: string;
8
+ tab?: string;
9
+ panel?: string;
10
+ footer?: string;
11
+ swatch?: string;
12
+ slider?: string;
13
+ thumb?: string;
14
+ field?: string;
15
+ trigger?: string;
16
+ popover?: string;
17
+ }
18
+ export interface ColorPalette {
19
+ name: string;
20
+ colors: (string | {
21
+ color: string;
22
+ name?: string;
23
+ })[];
24
+ }
25
+ export interface PanelOptions {
26
+ modeProps: Record<string, Record<string, unknown>>;
27
+ palettes: ColorPalette[] | undefined;
28
+ pencils: string[] | undefined;
29
+ showAlpha: boolean;
30
+ showEyedropper: boolean;
31
+ showRecentColors: boolean;
32
+ recentColors: string[];
33
+ onRecentColorsChange?: (colors: string[]) => void;
34
+ }
35
+ export interface PanelContextValue {
36
+ store: ColorStore;
37
+ disabled: boolean;
38
+ classNames: ChromaClassNames;
39
+ options: PanelOptions;
40
+ idPrefix: string;
41
+ }
42
+ export declare function usePanel(): PanelContextValue;
43
+ //#endregion
@@ -0,0 +1,26 @@
1
+ "use client";
2
+ import * as React from "react";
3
+ //#region src/core/context.ts
4
+ const PanelContext = React.createContext(null);
5
+ const PanelProvider = PanelContext.Provider;
6
+ function usePanel() {
7
+ const value = React.useContext(PanelContext);
8
+ if (value === null) throw new Error("chroma-panel: this component must be rendered inside <ChromaPanel> or <ColorInput>.");
9
+ return value;
10
+ }
11
+ function cx(...parts) {
12
+ let out = "";
13
+ for (const part of parts) if (typeof part === "string" && part !== "") out = out === "" ? part : out + " " + part;
14
+ return out;
15
+ }
16
+ let idCounter = 0;
17
+ function useStableId(prefix) {
18
+ const reactUseId = React.useId;
19
+ if (typeof reactUseId === "function") return prefix + reactUseId().replace(/:/g, "");
20
+ const ref = React.useRef(null);
21
+ if (ref.current === null) ref.current = prefix + String(++idCounter);
22
+ return ref.current;
23
+ }
24
+ //#endregion
25
+ export { PanelProvider, cx, usePanel, useStableId };
26
+
@@ -0,0 +1,11 @@
1
+ //#region src/core/dev.ts
2
+ const isDev = typeof process !== "undefined" && typeof process.env === "object" ? process.env.NODE_ENV !== "production" : false;
3
+ const warned = /* @__PURE__ */ new Set();
4
+ function warnOnce(message) {
5
+ if (!isDev || warned.has(message)) return;
6
+ warned.add(message);
7
+ console.warn(`chroma-panel: ${message}`);
8
+ }
9
+ //#endregion
10
+ exports.isDev = isDev;
11
+ exports.warnOnce = warnOnce;
@@ -0,0 +1,11 @@
1
+ //#region src/core/dev.ts
2
+ const isDev = typeof process !== "undefined" && typeof process.env === "object" ? process.env.NODE_ENV !== "production" : false;
3
+ const warned = /* @__PURE__ */ new Set();
4
+ function warnOnce(message) {
5
+ if (!isDev || warned.has(message)) return;
6
+ warned.add(message);
7
+ console.warn(`chroma-panel: ${message}`);
8
+ }
9
+ //#endregion
10
+ export { isDev, warnOnce };
11
+
@@ -0,0 +1,43 @@
1
+ const require_sticky = require("../color/sticky.cjs");
2
+ //#region src/core/store.ts
3
+ function createColorStore(initial) {
4
+ let state = initial;
5
+ const listeners = /* @__PURE__ */ new Set();
6
+ const commitListeners = /* @__PURE__ */ new Set();
7
+ function emit() {
8
+ for (const listener of Array.from(listeners)) listener(state);
9
+ }
10
+ function set(next) {
11
+ if (require_sticky.sameHsva(state, next)) return;
12
+ state = next;
13
+ emit();
14
+ }
15
+ return {
16
+ get: () => state,
17
+ set,
18
+ patch: (partial) => set({
19
+ ...state,
20
+ ...partial
21
+ }),
22
+ ingest: (next) => set(require_sticky.ingest(next, state)),
23
+ commit: () => {
24
+ for (const listener of Array.from(commitListeners)) listener(state);
25
+ },
26
+ subscribe: (listener) => {
27
+ listeners.add(listener);
28
+ return () => {
29
+ listeners.delete(listener);
30
+ };
31
+ },
32
+ subscribeCommit: (listener) => {
33
+ commitListeners.add(listener);
34
+ return () => {
35
+ commitListeners.delete(listener);
36
+ };
37
+ },
38
+ getSnapshot: () => state,
39
+ getServerSnapshot: () => state
40
+ };
41
+ }
42
+ //#endregion
43
+ exports.createColorStore = createColorStore;
@@ -0,0 +1,17 @@
1
+ import { Hsva } from "../color/types.cjs";
2
+ //#region src/core/store.d.ts
3
+ export type ColorListener = (color: Hsva) => void;
4
+ export type Unsubscribe = () => void;
5
+ export interface ColorStore {
6
+ get(): Hsva;
7
+ set(next: Hsva): void;
8
+ patch(partial: Partial<Hsva>): void;
9
+ ingest(next: Hsva): void;
10
+ commit(): void;
11
+ subscribe(listener: ColorListener): Unsubscribe;
12
+ subscribeCommit(listener: ColorListener): Unsubscribe;
13
+ getSnapshot(): Hsva;
14
+ getServerSnapshot(): Hsva;
15
+ }
16
+ export declare function createColorStore(initial: Hsva): ColorStore;
17
+ //#endregion
@@ -0,0 +1,17 @@
1
+ import { Hsva } from "../color/types.js";
2
+ //#region src/core/store.d.ts
3
+ export type ColorListener = (color: Hsva) => void;
4
+ export type Unsubscribe = () => void;
5
+ export interface ColorStore {
6
+ get(): Hsva;
7
+ set(next: Hsva): void;
8
+ patch(partial: Partial<Hsva>): void;
9
+ ingest(next: Hsva): void;
10
+ commit(): void;
11
+ subscribe(listener: ColorListener): Unsubscribe;
12
+ subscribeCommit(listener: ColorListener): Unsubscribe;
13
+ getSnapshot(): Hsva;
14
+ getServerSnapshot(): Hsva;
15
+ }
16
+ export declare function createColorStore(initial: Hsva): ColorStore;
17
+ //#endregion
@@ -0,0 +1,44 @@
1
+ import { ingest, sameHsva } from "../color/sticky.js";
2
+ //#region src/core/store.ts
3
+ function createColorStore(initial) {
4
+ let state = initial;
5
+ const listeners = /* @__PURE__ */ new Set();
6
+ const commitListeners = /* @__PURE__ */ new Set();
7
+ function emit() {
8
+ for (const listener of Array.from(listeners)) listener(state);
9
+ }
10
+ function set(next) {
11
+ if (sameHsva(state, next)) return;
12
+ state = next;
13
+ emit();
14
+ }
15
+ return {
16
+ get: () => state,
17
+ set,
18
+ patch: (partial) => set({
19
+ ...state,
20
+ ...partial
21
+ }),
22
+ ingest: (next) => set(ingest(next, state)),
23
+ commit: () => {
24
+ for (const listener of Array.from(commitListeners)) listener(state);
25
+ },
26
+ subscribe: (listener) => {
27
+ listeners.add(listener);
28
+ return () => {
29
+ listeners.delete(listener);
30
+ };
31
+ },
32
+ subscribeCommit: (listener) => {
33
+ commitListeners.add(listener);
34
+ return () => {
35
+ commitListeners.delete(listener);
36
+ };
37
+ },
38
+ getSnapshot: () => state,
39
+ getServerSnapshot: () => state
40
+ };
41
+ }
42
+ //#endregion
43
+ export { createColorStore };
44
+