@expcat/tigercat-react 2.0.0 → 2.0.19

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 (64) hide show
  1. package/dist/{chunk-JTFNGXOC.mjs → chunk-2ENQZECC.mjs} +53 -31
  2. package/dist/{chunk-O5RAMCBV.mjs → chunk-2JYJPNW3.mjs} +1 -1
  3. package/dist/{chunk-NBQ3Q6DD.mjs → chunk-2WGEHH5A.mjs} +1 -1
  4. package/dist/{chunk-K7MYQISG.mjs → chunk-54HN5BXW.mjs} +10 -4
  5. package/dist/{chunk-C6QK5MJT.mjs → chunk-5CKMYMTS.mjs} +1 -1
  6. package/dist/{chunk-Y7K27DVV.mjs → chunk-6H5Y7Y6E.mjs} +42 -28
  7. package/dist/chunk-6MGQAJ62.mjs +203 -0
  8. package/dist/{chunk-TO2URY7X.mjs → chunk-7AFRHC7P.mjs} +90 -61
  9. package/dist/{chunk-MGQWVJHX.mjs → chunk-ALSOPYM5.mjs} +69 -62
  10. package/dist/{chunk-YCKY72BW.mjs → chunk-BOGOQ44C.mjs} +1 -1
  11. package/dist/{chunk-Q327ESD2.mjs → chunk-BUXHI6UK.mjs} +17 -38
  12. package/dist/{chunk-TORX7SG4.mjs → chunk-CC7IOSNI.mjs} +10 -4
  13. package/dist/{chunk-OVE2ZUJJ.mjs → chunk-D33BIMGK.mjs} +1 -1
  14. package/dist/{chunk-PYDWF4ED.mjs → chunk-D3KP72UC.mjs} +34 -9
  15. package/dist/{chunk-ZEP7I6WB.mjs → chunk-DPWRXXXW.mjs} +16 -8
  16. package/dist/chunk-HKAZXG74.mjs +308 -0
  17. package/dist/{chunk-QWUDJC6K.mjs → chunk-HOYBHB7B.mjs} +38 -17
  18. package/dist/{chunk-3RY6M4AK.mjs → chunk-HS6KUPTI.mjs} +1 -1
  19. package/dist/{chunk-EKESN747.mjs → chunk-HSBN5MLS.mjs} +1 -1
  20. package/dist/{chunk-AJJJ6HWC.mjs → chunk-K4GIKSZE.mjs} +1 -1
  21. package/dist/{chunk-2UOGBS3C.mjs → chunk-KP6DEYWB.mjs} +27 -6
  22. package/dist/{chunk-PAN256RW.mjs → chunk-KVCI2346.mjs} +59 -55
  23. package/dist/{chunk-LBXNMCXN.mjs → chunk-OZ5XLR22.mjs} +6 -1
  24. package/dist/{chunk-5RVLBNLI.mjs → chunk-RJPNBYK5.mjs} +4 -4
  25. package/dist/{chunk-HELLYIX2.mjs → chunk-V6P7ZK6O.mjs} +3 -3
  26. package/dist/{chunk-4XGO3OSE.mjs → chunk-XE4YFBOZ.mjs} +12 -17
  27. package/dist/{chunk-YI7NQWUV.mjs → chunk-YI6YWH66.mjs} +14 -30
  28. package/dist/{chunk-SHCBCM2W.mjs → chunk-YIB6ZXZF.mjs} +142 -105
  29. package/dist/{chunk-SZBYEGKU.mjs → chunk-ZCGIZOMT.mjs} +1 -1
  30. package/dist/{chunk-S7IB6YST.mjs → chunk-ZG56T75O.mjs} +25 -40
  31. package/dist/{chunk-44BPUG24.mjs → chunk-ZH5ZBLAN.mjs} +38 -16
  32. package/dist/components/ActivityFeed.mjs +3 -3
  33. package/dist/components/AutoComplete.mjs +2 -1
  34. package/dist/components/Cascader.mjs +2 -1
  35. package/dist/components/CodeEditor.mjs +1 -1
  36. package/dist/components/ColorPicker.mjs +2 -1
  37. package/dist/components/CropUpload.mjs +3 -3
  38. package/dist/components/DataExport.mjs +3 -3
  39. package/dist/components/DataTableWithToolbar.mjs +6 -6
  40. package/dist/components/DatePicker.mjs +2 -1
  41. package/dist/components/Drawer.mjs +2 -2
  42. package/dist/components/Dropdown.mjs +2 -2
  43. package/dist/components/FormItem.mjs +2 -1
  44. package/dist/components/Image.mjs +5 -5
  45. package/dist/components/ImageGroup.mjs +3 -3
  46. package/dist/components/ImagePreview.mjs +2 -2
  47. package/dist/components/Loading.mjs +2 -2
  48. package/dist/components/Mentions.mjs +2 -1
  49. package/dist/components/Menu.mjs +2 -2
  50. package/dist/components/Modal.mjs +2 -2
  51. package/dist/components/NotificationCenter.mjs +3 -3
  52. package/dist/components/Popconfirm.mjs +3 -3
  53. package/dist/components/Popover.mjs +3 -3
  54. package/dist/components/Select.mjs +2 -1
  55. package/dist/components/Spotlight.mjs +2 -2
  56. package/dist/components/Table.mjs +3 -2
  57. package/dist/components/TimePicker.mjs +2 -1
  58. package/dist/components/Tooltip.mjs +3 -3
  59. package/dist/components/Tour.mjs +2 -2
  60. package/dist/components/TreeSelect.mjs +2 -1
  61. package/dist/index.mjs +5 -2
  62. package/package.json +2 -2
  63. package/dist/chunk-KVARQQAG.mjs +0 -181
  64. package/dist/chunk-SEWNVIHH.mjs +0 -153
@@ -1,3 +1,7 @@
1
+ import {
2
+ renderOverlayPortal,
3
+ useAnchoredOverlay
4
+ } from "./chunk-HKAZXG74.mjs";
1
5
  import {
2
6
  useTigerConfig
3
7
  } from "./chunk-YSIXURBW.mjs";
@@ -89,6 +93,20 @@ var AutoComplete = (props) => {
89
93
  const [activeIndex, setActiveIndex] = useState(-1);
90
94
  const containerRef = useRef(null);
91
95
  const inputRef = useRef(null);
96
+ const dropdownRef = useRef(null);
97
+ const overlay = useAnchoredOverlay({
98
+ enabled: isOpen,
99
+ referenceRef: inputRef,
100
+ floatingRef: dropdownRef,
101
+ containerRef,
102
+ placement: "bottom-start",
103
+ offset: 4,
104
+ matchReferenceWidth: true,
105
+ dismissOnOutside: true,
106
+ dismissOnEscape: true,
107
+ restoreFocusOnDismiss: true,
108
+ onDismiss: closeDropdown
109
+ });
92
110
  useEffect(() => {
93
111
  if (searchValue !== void 0) {
94
112
  return;
@@ -191,17 +209,41 @@ var AutoComplete = (props) => {
191
209
  break;
192
210
  }
193
211
  }
194
- useEffect(() => {
195
- if (!isOpen) return;
196
- function handleClickOutside(e) {
197
- if (containerRef.current && !containerRef.current.contains(e.target)) {
198
- closeDropdown();
199
- }
200
- }
201
- document.addEventListener("click", handleClickOutside);
202
- return () => document.removeEventListener("click", handleClickOutside);
203
- }, [isOpen]);
204
212
  const containerClasses = classNames(autoCompleteBaseClasses, className);
213
+ const dropdown = isOpen && (filteredOptions.length > 0 || inputValue) ? /* @__PURE__ */ jsx(
214
+ "div",
215
+ {
216
+ ref: dropdownRef,
217
+ ...filteredOptions.length > 0 ? getPickerListboxAria({ id: listboxId }) : {},
218
+ className: classNames(
219
+ autoCompleteDropdownClasses,
220
+ filteredOptions.length === 0 && autoCompleteEmptyStateClasses,
221
+ overlay.floatingClasses
222
+ ),
223
+ style: overlay.floatingStyles,
224
+ "data-positioned": overlay.positioned,
225
+ children: filteredOptions.length > 0 ? filteredOptions.map((option, index) => /* @__PURE__ */ jsx(
226
+ "div",
227
+ {
228
+ id: getPickerOptionId(listboxId, index),
229
+ ...getPickerOptionAria({
230
+ selected: String(option.value) === String(value),
231
+ disabled: !!option.disabled
232
+ }),
233
+ className: getAutoCompleteOptionClasses(
234
+ String(option.value) === String(value),
235
+ !!option.disabled,
236
+ size
237
+ ),
238
+ onMouseDown: (event) => event.preventDefault(),
239
+ onClick: () => handleSelect(option),
240
+ onMouseEnter: () => setActiveIndex(index),
241
+ children: option.label
242
+ },
243
+ String(option.value)
244
+ )) : resolvedNotFoundText
245
+ }
246
+ ) : null;
205
247
  return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: containerClasses, ...divProps, children: [
206
248
  /* @__PURE__ */ jsx(
207
249
  "input",
@@ -239,27 +281,7 @@ var AutoComplete = (props) => {
239
281
  )
240
282
  }
241
283
  ),
242
- isOpen && filteredOptions.length > 0 && /* @__PURE__ */ jsx("div", { ...getPickerListboxAria({ id: listboxId }), className: autoCompleteDropdownClasses, children: filteredOptions.map((option, index) => /* @__PURE__ */ jsx(
243
- "div",
244
- {
245
- id: getPickerOptionId(listboxId, index),
246
- ...getPickerOptionAria({
247
- selected: String(option.value) === String(value),
248
- disabled: !!option.disabled
249
- }),
250
- className: getAutoCompleteOptionClasses(
251
- String(option.value) === String(value),
252
- !!option.disabled,
253
- size
254
- ),
255
- onMouseDown: (e) => e.preventDefault(),
256
- onClick: () => handleSelect(option),
257
- onMouseEnter: () => setActiveIndex(index),
258
- children: option.label
259
- },
260
- String(option.value)
261
- )) }),
262
- isOpen && inputValue && filteredOptions.length === 0 && /* @__PURE__ */ jsx("div", { className: classNames(autoCompleteDropdownClasses, autoCompleteEmptyStateClasses), children: resolvedNotFoundText })
284
+ renderOverlayPortal(dropdown, overlay.target)
263
285
  ] });
264
286
  };
265
287
 
@@ -6,7 +6,7 @@ import {
6
6
  useBodyScrollLock,
7
7
  useEscapeKey,
8
8
  useFocusTrap
9
- } from "./chunk-SEWNVIHH.mjs";
9
+ } from "./chunk-HKAZXG74.mjs";
10
10
  import {
11
11
  useTigerConfig
12
12
  } from "./chunk-YSIXURBW.mjs";
@@ -10,7 +10,7 @@ import {
10
10
  } from "./chunk-5TE7KLE5.mjs";
11
11
  import {
12
12
  Loading
13
- } from "./chunk-AJJJ6HWC.mjs";
13
+ } from "./chunk-K4GIKSZE.mjs";
14
14
  import {
15
15
  Text
16
16
  } from "./chunk-HLS4CHWX.mjs";
@@ -6,7 +6,7 @@ import {
6
6
  useBodyScrollLock,
7
7
  useEscapeKey,
8
8
  useFocusTrap
9
- } from "./chunk-SEWNVIHH.mjs";
9
+ } from "./chunk-HKAZXG74.mjs";
10
10
  import {
11
11
  useTigerConfig
12
12
  } from "./chunk-YSIXURBW.mjs";
@@ -166,6 +166,7 @@ var Modal = ({
166
166
  const reactId = useId();
167
167
  const modalId = useMemo(() => `tiger-modal-${reactId}`, [reactId]);
168
168
  const titleId = `${modalId}-title`;
169
+ const overlayHostId = `${modalId}-overlay-host`;
169
170
  const {
170
171
  ["aria-labelledby"]: _ariaLabelledby,
171
172
  role: _role,
@@ -174,6 +175,7 @@ var Modal = ({
174
175
  } = rest;
175
176
  const ariaLabelledby = rest["aria-labelledby"] ?? (title || titleContent ? titleId : void 0);
176
177
  const dialogRef = useRef(null);
178
+ const rootRef = useRef(null);
177
179
  const closeButtonRef = useRef(null);
178
180
  const previousActiveElementRef = useRef(null);
179
181
  const touchStartRef = useRef(null);
@@ -188,9 +190,9 @@ var Modal = ({
188
190
  }
189
191
  restoreFocus(previousActiveElementRef.current);
190
192
  }, [open]);
191
- useEscapeKey({ enabled: open, onEscape: handleClose });
193
+ useEscapeKey({ enabled: open, onEscape: handleClose, layerRef: rootRef });
192
194
  useBodyScrollLock({ enabled: open });
193
- useFocusTrap({ enabled: open, containerRef: dialogRef });
195
+ useFocusTrap({ enabled: open, containerRef: rootRef });
194
196
  const resetTouchGesture = useCallback(() => {
195
197
  touchStartRef.current = null;
196
198
  touchCurrentRef.current = null;
@@ -263,10 +265,12 @@ var Modal = ({
263
265
  const modalContent = /* @__PURE__ */ jsxs(
264
266
  "div",
265
267
  {
268
+ ref: rootRef,
266
269
  className: classNames(modalWrapperClasses, !open && "pointer-events-none"),
267
270
  style: { zIndex },
268
271
  hidden: !open,
269
272
  "aria-hidden": !open ? "true" : void 0,
273
+ "data-tiger-overlay-layer": "",
270
274
  "data-tiger-modal-root": "",
271
275
  children: [
272
276
  mask && /* @__PURE__ */ jsx(
@@ -290,6 +294,7 @@ var Modal = ({
290
294
  role: "dialog",
291
295
  "aria-modal": "true",
292
296
  "aria-labelledby": ariaLabelledby,
297
+ "aria-owns": overlayHostId,
293
298
  tabIndex: -1,
294
299
  ref: dialogRef,
295
300
  onTouchStart: handleTouchStart,
@@ -327,7 +332,8 @@ var Modal = ({
327
332
  ] }) : null
328
333
  ]
329
334
  }
330
- ) })
335
+ ) }),
336
+ /* @__PURE__ */ jsx("div", { id: overlayHostId, className: "contents", "data-tiger-overlay-host": "" })
331
337
  ]
332
338
  }
333
339
  );
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-XZVQ3PJS.mjs";
7
7
  import {
8
8
  Loading
9
- } from "./chunk-AJJJ6HWC.mjs";
9
+ } from "./chunk-K4GIKSZE.mjs";
10
10
  import {
11
11
  Tag
12
12
  } from "./chunk-7EXOY7GD.mjs";
@@ -1,12 +1,16 @@
1
+ import {
2
+ renderOverlayPortal,
3
+ useAnchoredOverlay
4
+ } from "./chunk-HKAZXG74.mjs";
5
+
1
6
  // src/components/Mentions.tsx
2
- import { useState, useMemo, useCallback, useRef, useEffect } from "react";
7
+ import { useState, useMemo, useCallback, useRef } from "react";
3
8
  import { classNames } from "@expcat/tigercat-core";
4
9
  import {
5
10
  getMentionsInputClasses,
6
11
  mentionsDropdownClasses,
7
12
  getMentionsOptionClasses,
8
13
  extractMentionQuery,
9
- positionMentionsDropdown,
10
14
  getCyclicIndex
11
15
  } from "@expcat/tigercat-core";
12
16
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -34,6 +38,18 @@ var Mentions = ({
34
38
  const q = query.toLowerCase();
35
39
  return options.filter((o) => !o.disabled && o.label.toLowerCase().includes(q));
36
40
  }, [options, query]);
41
+ const overlay = useAnchoredOverlay({
42
+ enabled: isOpen && filteredOptions.length > 0,
43
+ referenceRef: textareaRef,
44
+ floatingRef: dropdownRef,
45
+ containerRef,
46
+ placement: "bottom-start",
47
+ offset: 4,
48
+ dismissOnOutside: true,
49
+ dismissOnEscape: true,
50
+ restoreFocusOnDismiss: true,
51
+ onDismiss: () => setIsOpen(false)
52
+ });
37
53
  const handleInput = useCallback(
38
54
  (e) => {
39
55
  const newValue = e.target.value;
@@ -83,21 +99,6 @@ var Mentions = ({
83
99
  },
84
100
  [isOpen, filteredOptions, activeIndex, selectOption]
85
101
  );
86
- useEffect(() => {
87
- if (!isOpen) return;
88
- const handler = (e) => {
89
- if (containerRef.current && !containerRef.current.contains(e.target)) {
90
- setIsOpen(false);
91
- }
92
- };
93
- document.addEventListener("mousedown", handler);
94
- return () => document.removeEventListener("mousedown", handler);
95
- }, [isOpen]);
96
- useEffect(() => {
97
- if (!isOpen || filteredOptions.length === 0) return;
98
- if (!textareaRef.current || !dropdownRef.current) return;
99
- void positionMentionsDropdown(textareaRef.current, dropdownRef.current);
100
- }, [isOpen, filteredOptions.length, size, rows, value]);
101
102
  const wrapperClass = classNames("relative", className);
102
103
  return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: wrapperClass, children: [
103
104
  /* @__PURE__ */ jsx(
@@ -113,17 +114,30 @@ var Mentions = ({
113
114
  onKeyDown: handleKeydown
114
115
  }
115
116
  ),
116
- isOpen && filteredOptions.length > 0 && /* @__PURE__ */ jsx("div", { ref: dropdownRef, className: mentionsDropdownClasses, role: "listbox", children: filteredOptions.map((opt, i) => /* @__PURE__ */ jsx(
117
- "div",
118
- {
119
- className: getMentionsOptionClasses(i === activeIndex, !!opt.disabled),
120
- role: "option",
121
- "aria-selected": i === activeIndex,
122
- onClick: () => selectOption(opt),
123
- children: opt.label
124
- },
125
- opt.value
126
- )) })
117
+ renderOverlayPortal(
118
+ isOpen && filteredOptions.length > 0 ? /* @__PURE__ */ jsx(
119
+ "div",
120
+ {
121
+ ref: dropdownRef,
122
+ className: classNames(mentionsDropdownClasses, overlay.floatingClasses),
123
+ style: overlay.floatingStyles,
124
+ "data-positioned": overlay.positioned,
125
+ role: "listbox",
126
+ children: filteredOptions.map((opt, i) => /* @__PURE__ */ jsx(
127
+ "div",
128
+ {
129
+ className: getMentionsOptionClasses(i === activeIndex, !!opt.disabled),
130
+ role: "option",
131
+ "aria-selected": i === activeIndex,
132
+ onClick: () => selectOption(opt),
133
+ children: opt.label
134
+ },
135
+ opt.value
136
+ ))
137
+ }
138
+ ) : null,
139
+ overlay.target
140
+ )
127
141
  ] });
128
142
  };
129
143
  var Mentions_default = Mentions;
@@ -0,0 +1,203 @@
1
+ import {
2
+ renderOverlayPortal,
3
+ useAnchoredOverlay
4
+ } from "./chunk-HKAZXG74.mjs";
5
+
6
+ // src/components/ColorPicker.tsx
7
+ import { useState, useMemo, useRef, useEffect } from "react";
8
+ import {
9
+ colorPickerBaseClasses,
10
+ getColorPickerTriggerClasses,
11
+ colorPickerPanelClasses,
12
+ colorPickerInputClasses,
13
+ colorPickerPresetClasses,
14
+ hexToRgb,
15
+ rgbToHex,
16
+ rgbToHsv,
17
+ hsvToRgb,
18
+ formatColorString,
19
+ parseColorInput,
20
+ classNames
21
+ } from "@expcat/tigercat-core";
22
+ import { jsx, jsxs } from "react/jsx-runtime";
23
+ var ColorPicker = ({
24
+ value = "#2563eb",
25
+ disabled = false,
26
+ size = "md",
27
+ showAlpha = false,
28
+ format = "hex",
29
+ presets,
30
+ className,
31
+ onChange
32
+ }) => {
33
+ const [isOpen, setIsOpen] = useState(false);
34
+ const [alpha, setAlpha] = useState(1);
35
+ const containerRef = useRef(null);
36
+ const triggerRef = useRef(null);
37
+ const panelRef = useRef(null);
38
+ const overlay = useAnchoredOverlay({
39
+ enabled: isOpen,
40
+ referenceRef: triggerRef,
41
+ floatingRef: panelRef,
42
+ containerRef,
43
+ placement: "bottom-start",
44
+ offset: 4,
45
+ dismissOnOutside: true,
46
+ dismissOnEscape: true,
47
+ restoreFocusOnDismiss: true,
48
+ onDismiss: () => setIsOpen(false)
49
+ });
50
+ const rgb = useMemo(() => hexToRgb(value), [value]);
51
+ const hsv = useMemo(() => rgbToHsv(rgb.r, rgb.g, rgb.b), [rgb]);
52
+ const displayValue = useMemo(
53
+ () => formatColorString(rgb.r, rgb.g, rgb.b, format, showAlpha ? alpha : void 0),
54
+ [rgb, format, showAlpha, alpha]
55
+ );
56
+ const swatchColor = showAlpha ? `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha})` : value;
57
+ const [inputValue, setInputValue] = useState(displayValue);
58
+ useEffect(() => {
59
+ setInputValue(displayValue);
60
+ }, [displayValue]);
61
+ function togglePanel() {
62
+ if (disabled) return;
63
+ setIsOpen((v) => !v);
64
+ }
65
+ function handleTriggerKeyDown(e) {
66
+ if (disabled) return;
67
+ if (e.key === "Enter" || e.key === " " || e.key === "Spacebar") {
68
+ e.preventDefault();
69
+ setIsOpen((v) => !v);
70
+ } else if (e.key === "Escape" && isOpen) {
71
+ setIsOpen(false);
72
+ }
73
+ }
74
+ function handleHueChange(e) {
75
+ const hue = Number(e.target.value);
76
+ const { r, g, b } = hsvToRgb(hue, hsv.s, hsv.v);
77
+ const hex = rgbToHex(r, g, b);
78
+ onChange?.(hex);
79
+ }
80
+ function handleInputChange(e) {
81
+ const val = e.target.value;
82
+ setInputValue(val);
83
+ const hex = parseColorInput(val);
84
+ if (hex) {
85
+ onChange?.(hex);
86
+ }
87
+ }
88
+ function handleAlphaChange(e) {
89
+ setAlpha(Number(e.target.value) / 100);
90
+ }
91
+ function handlePresetClick(color) {
92
+ onChange?.(color);
93
+ }
94
+ function handlePresetKeyDown(e, color) {
95
+ if (e.key === "Enter" || e.key === " " || e.key === "Spacebar") {
96
+ e.preventDefault();
97
+ handlePresetClick(color);
98
+ }
99
+ }
100
+ return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: classNames(colorPickerBaseClasses, className), children: [
101
+ /* @__PURE__ */ jsx(
102
+ "div",
103
+ {
104
+ ref: triggerRef,
105
+ className: getColorPickerTriggerClasses(size, disabled),
106
+ style: { backgroundColor: swatchColor },
107
+ role: "button",
108
+ "aria-label": "Pick color",
109
+ "aria-haspopup": "dialog",
110
+ "aria-expanded": isOpen,
111
+ "aria-disabled": disabled || void 0,
112
+ tabIndex: disabled ? -1 : 0,
113
+ onClick: togglePanel,
114
+ onKeyDown: handleTriggerKeyDown
115
+ }
116
+ ),
117
+ renderOverlayPortal(
118
+ isOpen ? /* @__PURE__ */ jsxs(
119
+ "div",
120
+ {
121
+ ref: panelRef,
122
+ className: classNames(colorPickerPanelClasses, overlay.floatingClasses),
123
+ style: overlay.floatingStyles,
124
+ "data-positioned": overlay.positioned,
125
+ children: [
126
+ /* @__PURE__ */ jsxs("div", { className: "mb-2", children: [
127
+ /* @__PURE__ */ jsx("label", { className: "block text-xs text-[var(--tiger-text-muted,#6b7280)] mb-1", children: "Hue" }),
128
+ /* @__PURE__ */ jsx(
129
+ "input",
130
+ {
131
+ type: "range",
132
+ min: 0,
133
+ max: 360,
134
+ value: hsv.h,
135
+ className: "w-full h-2 rounded-full cursor-pointer accent-[var(--tiger-primary,#2563eb)]",
136
+ "aria-label": "Hue",
137
+ onChange: handleHueChange
138
+ }
139
+ )
140
+ ] }),
141
+ showAlpha && /* @__PURE__ */ jsxs("div", { className: "mb-2", children: [
142
+ /* @__PURE__ */ jsx("label", { className: "block text-xs text-[var(--tiger-text-muted,#6b7280)] mb-1", children: "Alpha" }),
143
+ /* @__PURE__ */ jsx(
144
+ "input",
145
+ {
146
+ type: "range",
147
+ min: 0,
148
+ max: 100,
149
+ value: Math.round(alpha * 100),
150
+ className: "w-full h-2 rounded-full cursor-pointer accent-[var(--tiger-primary,#2563eb)]",
151
+ "aria-label": "Alpha",
152
+ onChange: handleAlphaChange
153
+ }
154
+ )
155
+ ] }),
156
+ /* @__PURE__ */ jsxs("div", { className: "mb-2", children: [
157
+ /* @__PURE__ */ jsx("label", { className: "block text-xs text-[var(--tiger-text-muted,#6b7280)] mb-1 uppercase", children: format }),
158
+ /* @__PURE__ */ jsx(
159
+ "input",
160
+ {
161
+ type: "text",
162
+ className: colorPickerInputClasses,
163
+ value: inputValue,
164
+ "aria-label": "Color value",
165
+ onChange: handleInputChange
166
+ }
167
+ )
168
+ ] }),
169
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-2", children: [
170
+ /* @__PURE__ */ jsx(
171
+ "div",
172
+ {
173
+ className: "w-8 h-8 rounded border border-[var(--tiger-border,#d1d5db)]",
174
+ style: { backgroundColor: swatchColor },
175
+ "aria-label": "Color preview"
176
+ }
177
+ ),
178
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-mono text-[var(--tiger-text,#111827)]", children: displayValue })
179
+ ] }),
180
+ presets && presets.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: presets.map((color) => /* @__PURE__ */ jsx(
181
+ "div",
182
+ {
183
+ className: colorPickerPresetClasses,
184
+ style: { backgroundColor: color },
185
+ role: "button",
186
+ tabIndex: 0,
187
+ "aria-label": `Select ${color}`,
188
+ onClick: () => handlePresetClick(color),
189
+ onKeyDown: (e) => handlePresetKeyDown(e, color)
190
+ },
191
+ color
192
+ )) })
193
+ ]
194
+ }
195
+ ) : null,
196
+ overlay.target
197
+ )
198
+ ] });
199
+ };
200
+
201
+ export {
202
+ ColorPicker
203
+ };