@flikk/ui 1.0.0-beta.23 → 1.0.0-beta.25

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 (157) hide show
  1. package/dist/components/charts/AreaChart/AreaChart.types.d.ts +2 -2
  2. package/dist/components/charts/BarChart/BarChart.types.d.ts +2 -2
  3. package/dist/components/charts/ComboChart/ComboChart.types.d.ts +2 -2
  4. package/dist/components/charts/LineChart/LineChart.types.d.ts +2 -2
  5. package/dist/components/charts/ScatterPlot/ScatterPlot.types.d.ts +2 -2
  6. package/dist/components/charts/StackedBarChart/StackedBarChart.types.d.ts +2 -2
  7. package/dist/components/core/Accordion/Accordion.theme.js +2 -2
  8. package/dist/components/core/Accordion/AccordionTrigger.js +28 -1
  9. package/dist/components/core/Alert/Alert.js +2 -1
  10. package/dist/components/core/AlertDialog/AlertDialog.js +1 -1
  11. package/dist/components/core/Badge/Badge.js +6 -17
  12. package/dist/components/core/Breadcrumbs/Breadcrumbs.js +17 -28
  13. package/dist/components/core/Breadcrumbs/Breadcrumbs.theme.js +2 -2
  14. package/dist/components/core/Calendar/Calendar.js +1 -1
  15. package/dist/components/core/Calendar/CalendarMini/CalendarMini.js +4 -2
  16. package/dist/components/core/Calendar/CalendarMini/CalendarMini.theme.js +1 -1
  17. package/dist/components/core/Carousel/CarouselBody.js +6 -1
  18. package/dist/components/core/ContextMenu/ContextMenuBody.js +6 -3
  19. package/dist/components/core/ContextMenu/ContextMenuSubBody.js +6 -3
  20. package/dist/components/core/DragDrop/DragDrop.js +170 -17
  21. package/dist/components/core/DragDrop/DragDrop.types.d.ts +6 -0
  22. package/dist/components/core/Drawer/Drawer.d.ts +1 -1
  23. package/dist/components/core/Drawer/Drawer.js +2 -0
  24. package/dist/components/core/Drawer/Drawer.types.d.ts +2 -0
  25. package/dist/components/core/Drawer/DrawerTitle.d.ts +1 -1
  26. package/dist/components/core/Drawer/DrawerTitle.js +2 -2
  27. package/dist/components/core/Dropdown/DropdownMenu.js +2 -30
  28. package/dist/components/core/Empty/Empty.theme.js +1 -1
  29. package/dist/components/core/Link/Link.js +1 -1
  30. package/dist/components/core/Masonry/Masonry.js +7 -2
  31. package/dist/components/core/Modal/Modal.d.ts +1 -1
  32. package/dist/components/core/Modal/Modal.js +3 -3
  33. package/dist/components/core/Modal/Modal.types.d.ts +2 -0
  34. package/dist/components/core/Modal/ModalTitle.d.ts +1 -1
  35. package/dist/components/core/Modal/ModalTitle.js +2 -2
  36. package/dist/components/core/NavItem/NavItem.js +13 -8
  37. package/dist/components/core/Pagination/Pagination.js +1 -1
  38. package/dist/components/core/Popover/PopoverBody.js +3 -27
  39. package/dist/components/core/Popover/PopoverTrigger.js +1 -1
  40. package/dist/components/core/Progress/Progress.js +4 -4
  41. package/dist/components/core/Rating/Rating.js +1 -1
  42. package/dist/components/core/ScrollArea/ScrollArea.js +3 -2
  43. package/dist/components/core/Segmented/Segmented.js +6 -6
  44. package/dist/components/core/Segmented/SegmentedItem.js +28 -2
  45. package/dist/components/core/Skeleton/Skeleton.js +2 -2
  46. package/dist/components/core/Sortable/Sortable.d.ts +1 -1
  47. package/dist/components/core/Sortable/Sortable.js +20 -4
  48. package/dist/components/core/Sortable/Sortable.types.d.ts +2 -0
  49. package/dist/components/core/Tabs/Tabs.js +6 -4
  50. package/dist/components/core/Tabs/Tabs.types.d.ts +2 -0
  51. package/dist/components/core/Tabs/TabsBody.js +3 -3
  52. package/dist/components/core/Tabs/TabsList.js +19 -21
  53. package/dist/components/core/Tabs/TabsTrigger.js +47 -28
  54. package/dist/components/core/Toast/Toast.js +1 -1
  55. package/dist/components/core/Toast/ToastProvider.js +3 -2
  56. package/dist/components/core/Tooltip/Tooltip.js +25 -34
  57. package/dist/components/core/Tree/Tree.js +178 -8
  58. package/dist/components/data-display/GanttChart/GanttSplitter.js +15 -1
  59. package/dist/components/data-display/Table/Table.js +2 -2
  60. package/dist/components/data-display/Table/Table.types.d.ts +2 -0
  61. package/dist/components/data-display/Table/TableFilter.js +21 -18
  62. package/dist/components/data-display/Timeline/Timeline.animations.d.ts +0 -7
  63. package/dist/components/data-display/Timeline/Timeline.animations.js +1 -27
  64. package/dist/components/data-display/Timeline/Timeline.js +3 -4
  65. package/dist/components/data-display/Timeline/Timeline.types.d.ts +0 -13
  66. package/dist/components/data-display/Timeline/TimelineContent.js +3 -7
  67. package/dist/components/data-display/Timeline/TimelineItem.js +4 -17
  68. package/dist/components/data-display/Timeline/index.d.ts +2 -2
  69. package/dist/components/effects/CustomCursor/CustomCursor.js +3 -7
  70. package/dist/components/effects/Overlay/Overlay.js +4 -9
  71. package/dist/components/effects/PageTransition/PageTransition.js +17 -6
  72. package/dist/components/effects/SpotlightBorder/SpotlightBorder.js +3 -4
  73. package/dist/components/effects/index.d.ts +7 -0
  74. package/dist/components/effects/index.js +3 -0
  75. package/dist/components/forms/Checkbox/Checkbox.js +11 -1
  76. package/dist/components/forms/Checkbox/Checkbox.theme.js +4 -1
  77. package/dist/components/forms/Checkbox/Checkbox.types.d.ts +7 -5
  78. package/dist/components/forms/Checkbox/CheckboxGroup.js +9 -4
  79. package/dist/components/forms/ColorPicker/ColorPicker.js +7 -4
  80. package/dist/components/forms/ColorPicker/ColorPicker.types.d.ts +2 -2
  81. package/dist/components/forms/ColorPicker/ColorPickerBody.js +5 -3
  82. package/dist/components/forms/ColorPicker/ColorPickerEyeDropper.js +3 -3
  83. package/dist/components/forms/ColorPicker/ColorPickerGradient.js +8 -8
  84. package/dist/components/forms/ColorPicker/ColorPickerInput.js +1 -1
  85. package/dist/components/forms/ColorPicker/index.d.ts +1 -1
  86. package/dist/components/forms/Combobox/Combobox.js +20 -45
  87. package/dist/components/forms/Combobox/Combobox.types.d.ts +4 -2
  88. package/dist/components/forms/CronInput/CronInput.js +10 -4
  89. package/dist/components/forms/CronInput/CronInput.types.d.ts +12 -1
  90. package/dist/components/forms/DatePicker/DatePicker.js +2 -2
  91. package/dist/components/forms/DatePicker/DatePicker.types.d.ts +4 -2
  92. package/dist/components/forms/DatePicker/DatePickerBody.js +1 -29
  93. package/dist/components/forms/DatePicker/DatePickerTrigger.js +2 -2
  94. package/dist/components/forms/DateRangePicker/DateRangePicker.js +3 -3
  95. package/dist/components/forms/DateRangePicker/DateRangePicker.types.d.ts +4 -2
  96. package/dist/components/forms/DateRangePicker/DateRangePickerBody.js +1 -28
  97. package/dist/components/forms/DateRangePicker/DateRangePickerTrigger.js +2 -2
  98. package/dist/components/forms/FileUpload/FileUpload.js +14 -10
  99. package/dist/components/forms/FileUpload/FileUpload.types.d.ts +15 -0
  100. package/dist/components/forms/FormLabel/FormLabel.js +2 -2
  101. package/dist/components/forms/Input/Input.js +5 -3
  102. package/dist/components/forms/Input/Input.types.d.ts +2 -0
  103. package/dist/components/forms/InputAddress/InputAddress.d.ts +1 -1
  104. package/dist/components/forms/InputAddress/InputAddress.js +8 -9
  105. package/dist/components/forms/InputCounter/InputCounter.js +25 -18
  106. package/dist/components/forms/InputCounter/InputCounter.types.d.ts +8 -1
  107. package/dist/components/forms/InputCreditCard/InputCreditCard.d.ts +1 -1
  108. package/dist/components/forms/InputCreditCard/InputCreditCard.js +27 -9
  109. package/dist/components/forms/InputCreditCard/InputCreditCard.types.d.ts +5 -0
  110. package/dist/components/forms/InputOTP/InputOTP.js +26 -17
  111. package/dist/components/forms/InputOTP/InputOTP.types.d.ts +21 -4
  112. package/dist/components/forms/InputTag/InputTag.js +12 -39
  113. package/dist/components/forms/InputTag/InputTag.types.d.ts +2 -2
  114. package/dist/components/forms/Mention/Mention.js +13 -6
  115. package/dist/components/forms/Mention/Mention.types.d.ts +9 -0
  116. package/dist/components/forms/Radio/Radio.js +12 -2
  117. package/dist/components/forms/Radio/Radio.theme.js +5 -1
  118. package/dist/components/forms/Radio/Radio.types.d.ts +7 -5
  119. package/dist/components/forms/Radio/RadioGroup.js +8 -3
  120. package/dist/components/forms/RichTextEditor/RichTextEditor.js +21 -21
  121. package/dist/components/forms/RichTextEditor/RichTextEditor.types.d.ts +2 -2
  122. package/dist/components/forms/Select/Select.d.ts +2 -0
  123. package/dist/components/forms/Select/Select.js +27 -57
  124. package/dist/components/forms/Select/Select.types.d.ts +14 -0
  125. package/dist/components/forms/Signature/Signature.js +1 -1
  126. package/dist/components/forms/Signature/Signature.types.d.ts +3 -3
  127. package/dist/components/forms/Slider/Slider.js +18 -4
  128. package/dist/components/forms/Slider/Slider.types.d.ts +2 -2
  129. package/dist/components/forms/Switch/Switch.js +12 -19
  130. package/dist/components/forms/Switch/Switch.theme.js +12 -2
  131. package/dist/components/forms/Switch/Switch.types.d.ts +20 -2
  132. package/dist/components/forms/Textarea/Textarea.js +8 -3
  133. package/dist/components/forms/Textarea/Textarea.types.d.ts +2 -0
  134. package/dist/components/forms/TimePicker/TimePicker.js +1 -1
  135. package/dist/components/forms/TimePicker/TimePicker.types.d.ts +6 -2
  136. package/dist/components/forms/TimePicker/TimePickerContent.js +2 -29
  137. package/dist/components/forms/TimePicker/TimePickerTrigger.js +2 -2
  138. package/dist/components/forms/index.js +1 -1
  139. package/dist/components/layout/index.js +4 -0
  140. package/dist/hooks/index.d.ts +1 -0
  141. package/dist/hooks/useClickOutside.d.ts +10 -4
  142. package/dist/hooks/useClickOutside.js +44 -24
  143. package/dist/hooks/useDarkMode.d.ts +1 -0
  144. package/dist/hooks/useDarkMode.js +42 -0
  145. package/dist/hooks/useFormStateMachine.d.ts +1 -1
  146. package/dist/hooks/useNetworkStatus.js +1 -1
  147. package/dist/hooks/useOverlay.js +4 -0
  148. package/dist/hooks/useScaleBackground.js +5 -2
  149. package/dist/hooks/useSelectPortal.js +14 -5
  150. package/dist/index.d.ts +0 -2
  151. package/dist/index.js +1 -57
  152. package/dist/shadcn-compat.css +80 -0
  153. package/dist/styles.css +1 -1
  154. package/dist/utils/stateMachine.d.ts +4 -4
  155. package/package.json +11 -10
  156. package/tailwind.preset.cjs +32 -3
  157. /package/{src/theme-plugin.css → dist/theme.css} +0 -0
@@ -1,4 +1,4 @@
1
- import { jsx } from 'react/jsx-runtime';
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import React__default, { createContext, useState, useRef, useCallback, useMemo, useEffect, useContext } from 'react';
3
3
  import { motion } from 'motion/react';
4
4
  export { AnimatePresence } from 'motion/react';
@@ -6,20 +6,48 @@ import { cn } from '../../../utils/cn.js';
6
6
  import { dragDropTheme } from './DragDrop.theme.js';
7
7
 
8
8
  const DragDropContext = createContext(null);
9
- const DragDropProvider = React__default.forwardRef(({ children }, ref) => {
9
+ // ---------------------------------------------------------------------------
10
+ // Provider
11
+ // ---------------------------------------------------------------------------
12
+ const DragDropProvider = React__default.forwardRef(({ children }, _ref) => {
13
+ // pointer drag state
10
14
  const [activeDrag, setActiveDrag] = useState(null);
11
15
  const pointerRef = useRef(null);
12
16
  const dropZones = useRef(new Map());
13
17
  const groupIdRef = useRef(`dd-${Math.random().toString(36).slice(2)}`);
18
+ // keyboard drag state
19
+ const [keyboardDragId, setKeyboardDragId] = useState(null);
20
+ const [keyboardDragLabel, setKeyboardDragLabel] = useState('');
21
+ const [announcement, setAnnouncement] = useState('');
22
+ // Stable ordered list of drop-zone IDs so Arrow-key cycling is deterministic
23
+ const dropZoneOrder = useRef([]);
14
24
  const registerDropZone = useCallback((id, element) => {
15
25
  dropZones.current.set(id, element);
26
+ if (!dropZoneOrder.current.includes(id)) {
27
+ dropZoneOrder.current.push(id);
28
+ }
16
29
  }, []);
17
30
  const unregisterDropZone = useCallback((id) => {
18
31
  dropZones.current.delete(id);
32
+ dropZoneOrder.current = dropZoneOrder.current.filter((zid) => zid !== id);
19
33
  }, []);
20
34
  const setPointer = useCallback((point) => {
21
35
  pointerRef.current = point;
22
36
  }, []);
37
+ const startKeyboardDrag = useCallback((id, label) => {
38
+ setKeyboardDragId(id);
39
+ setKeyboardDragLabel(label);
40
+ }, []);
41
+ const endKeyboardDrag = useCallback(() => {
42
+ setKeyboardDragId(null);
43
+ setKeyboardDragLabel('');
44
+ }, []);
45
+ const announce = useCallback((message) => {
46
+ // Briefly clear then set to guarantee re-announcement of the same string
47
+ setAnnouncement('');
48
+ // Use a microtask so the DOM sees the empty value first
49
+ setTimeout(() => setAnnouncement(message), 0);
50
+ }, []);
23
51
  const contextValue = useMemo(() => ({
24
52
  activeDrag,
25
53
  setActiveDrag,
@@ -29,8 +57,24 @@ const DragDropProvider = React__default.forwardRef(({ children }, ref) => {
29
57
  registerDropZone,
30
58
  unregisterDropZone,
31
59
  dropZones: dropZones.current,
32
- }), [activeDrag, setActiveDrag, setPointer, registerDropZone, unregisterDropZone]);
33
- return (jsx(DragDropContext.Provider, { value: contextValue, children: children }));
60
+ keyboardDragId,
61
+ keyboardDragLabel,
62
+ startKeyboardDrag,
63
+ endKeyboardDrag,
64
+ dropZoneOrder,
65
+ announce,
66
+ }), [
67
+ activeDrag,
68
+ setPointer,
69
+ registerDropZone,
70
+ unregisterDropZone,
71
+ keyboardDragId,
72
+ keyboardDragLabel,
73
+ startKeyboardDrag,
74
+ endKeyboardDrag,
75
+ announce,
76
+ ]);
77
+ return (jsxs(DragDropContext.Provider, { value: contextValue, children: [children, jsx("div", { className: "sr-only", "aria-live": "assertive", "aria-atomic": "true", "aria-relevant": "additions text", children: announcement })] }));
34
78
  });
35
79
  DragDropProvider.displayName = 'DragDropProvider';
36
80
  const useDragDropContext = () => {
@@ -40,7 +84,10 @@ const useDragDropContext = () => {
40
84
  }
41
85
  return context;
42
86
  };
43
- const Draggable = React__default.forwardRef(({ children, dragData, className, theme: customTheme = {}, onDragStart, onDrag, onDragEnd, disabled = false, }, ref) => {
87
+ // ---------------------------------------------------------------------------
88
+ // Draggable
89
+ // ---------------------------------------------------------------------------
90
+ const Draggable = React__default.forwardRef(({ children, dragData, dragLabel, className, theme: customTheme = {}, onDragStart, onDrag, onDragEnd, disabled = false, }, ref) => {
44
91
  var _a;
45
92
  const context = useDragDropContext();
46
93
  const dragRef = useRef(null);
@@ -48,6 +95,9 @@ const Draggable = React__default.forwardRef(({ children, dragData, className, th
48
95
  ...dragDropTheme,
49
96
  ...customTheme,
50
97
  };
98
+ // Resolve the human-readable label used in announcements
99
+ const resolvedLabel = dragLabel !== null && dragLabel !== void 0 ? dragLabel : dragData.id;
100
+ // ----- pointer drag handlers (unchanged) --------------------------------
51
101
  const handleDragStart = useCallback((_event, info) => {
52
102
  if (disabled)
53
103
  return;
@@ -73,7 +123,7 @@ const Draggable = React__default.forwardRef(({ children, dragData, className, th
73
123
  point.y <= dropRect.bottom) {
74
124
  const dropEvent = new CustomEvent('motion-drop', {
75
125
  detail: dragData,
76
- bubbles: true
126
+ bubbles: true,
77
127
  });
78
128
  dropZone.dispatchEvent(dropEvent);
79
129
  }
@@ -82,7 +132,58 @@ const Draggable = React__default.forwardRef(({ children, dragData, className, th
82
132
  context.setPointer(null);
83
133
  onDragEnd === null || onDragEnd === void 0 ? void 0 : onDragEnd(dragData, info);
84
134
  }, [dragData, onDragEnd, context]);
85
- const isDragging = ((_a = context.activeDrag) === null || _a === void 0 ? void 0 : _a.id) === dragData.id;
135
+ // ----- keyboard drag handler (new) --------------------------------------
136
+ const handleKeyDown = useCallback((e) => {
137
+ var _a, _b, _c;
138
+ if (disabled)
139
+ return;
140
+ const isGrabbed = context.keyboardDragId === dragData.id;
141
+ if ((e.key === ' ' || e.key === 'Enter') && !isGrabbed) {
142
+ // Initiate keyboard drag
143
+ e.preventDefault();
144
+ context.startKeyboardDrag(dragData.id, resolvedLabel);
145
+ context.announce(`Grabbed ${resolvedLabel}. Use arrow keys to move between drop zones. Press Space or Enter to drop, or Escape to cancel.`);
146
+ return;
147
+ }
148
+ if (isGrabbed) {
149
+ if (e.key === 'Escape') {
150
+ // Cancel keyboard drag
151
+ e.preventDefault();
152
+ context.endKeyboardDrag();
153
+ context.announce(`Drop cancelled. ${resolvedLabel} returned to original position.`);
154
+ // Return focus to this draggable
155
+ (_a = dragRef.current) === null || _a === void 0 ? void 0 : _a.focus();
156
+ return;
157
+ }
158
+ if (e.key === 'ArrowDown' || e.key === 'ArrowRight') {
159
+ e.preventDefault();
160
+ const order = context.dropZoneOrder.current;
161
+ if (order.length === 0)
162
+ return;
163
+ // Find the currently focused drop zone, advance to next
164
+ const focusedDropId = (_b = document.activeElement) === null || _b === void 0 ? void 0 : _b.getAttribute('data-dropzone-id');
165
+ const currentIdx = focusedDropId ? order.indexOf(focusedDropId) : -1;
166
+ const nextIdx = (currentIdx + 1) % order.length;
167
+ const nextEl = context.dropZones.get(order[nextIdx]);
168
+ nextEl === null || nextEl === void 0 ? void 0 : nextEl.focus();
169
+ return;
170
+ }
171
+ if (e.key === 'ArrowUp' || e.key === 'ArrowLeft') {
172
+ e.preventDefault();
173
+ const order = context.dropZoneOrder.current;
174
+ if (order.length === 0)
175
+ return;
176
+ const focusedDropId = (_c = document.activeElement) === null || _c === void 0 ? void 0 : _c.getAttribute('data-dropzone-id');
177
+ const currentIdx = focusedDropId ? order.indexOf(focusedDropId) : 0;
178
+ const prevIdx = (currentIdx - 1 + order.length) % order.length;
179
+ const prevEl = context.dropZones.get(order[prevIdx]);
180
+ prevEl === null || prevEl === void 0 ? void 0 : prevEl.focus();
181
+ return;
182
+ }
183
+ }
184
+ }, [disabled, context, dragData.id, resolvedLabel]);
185
+ const isPointerDragging = ((_a = context.activeDrag) === null || _a === void 0 ? void 0 : _a.id) === dragData.id;
186
+ const isKeyboardGrabbed = context.keyboardDragId === dragData.id;
86
187
  return (jsx(motion.div, { ref: (node) => {
87
188
  dragRef.current = node;
88
189
  if (typeof ref === 'function') {
@@ -104,12 +205,21 @@ const Draggable = React__default.forwardRef(({ children, dragData, className, th
104
205
  x: { type: 'spring', stiffness: 1000, damping: 50 },
105
206
  y: { type: 'spring', stiffness: 1000, damping: 50 },
106
207
  }, style: {
107
- position: isDragging ? 'relative' : 'relative',
108
- zIndex: isDragging ? 99999 : 'auto',
109
- isolation: isDragging ? 'isolate' : 'auto',
110
- }, className: cn(theme.draggableStyle, disabled && 'opacity-50 cursor-not-allowed', !disabled && 'cursor-grab active:cursor-grabbing', isDragging && '[&]:!z-[99999]', className), onDragStart: handleDragStart, onDrag: handleDrag, onDragEnd: handleDragEnd, children: children }));
208
+ position: 'relative',
209
+ zIndex: isPointerDragging ? 99999 : 'auto',
210
+ isolation: isPointerDragging ? 'isolate' : 'auto',
211
+ outline: isKeyboardGrabbed ? '2px solid var(--color-primary)' : undefined,
212
+ outlineOffset: isKeyboardGrabbed ? '2px' : undefined,
213
+ }, className: cn(theme.draggableStyle, disabled && 'opacity-50 cursor-not-allowed', !disabled && 'cursor-grab active:cursor-grabbing', isPointerDragging && '[&]:!z-[99999]', className),
214
+ // Pointer drag callbacks
215
+ onDragStart: handleDragStart, onDrag: handleDrag, onDragEnd: handleDragEnd,
216
+ // Keyboard accessibility
217
+ role: "button", tabIndex: disabled ? -1 : 0, "aria-label": `Drag ${resolvedLabel}`, "aria-grabbed": isKeyboardGrabbed, onKeyDown: handleKeyDown, children: children }));
111
218
  });
112
219
  Draggable.displayName = 'Draggable';
220
+ // ---------------------------------------------------------------------------
221
+ // Droppable
222
+ // ---------------------------------------------------------------------------
113
223
  const Droppable = React__default.forwardRef(({ children, acceptedTypes, className, theme: customTheme = {}, onDrop, onDragEnter, onDragLeave, id, }, ref) => {
114
224
  const context = useDragDropContext();
115
225
  const [isDragOver, setIsDragOver] = useState(false);
@@ -120,7 +230,9 @@ const Droppable = React__default.forwardRef(({ children, acceptedTypes, classNam
120
230
  ...dragDropTheme,
121
231
  ...customTheme,
122
232
  };
123
- // Register drop zone
233
+ // Whether a keyboard drag is currently active (any item grabbed)
234
+ const isKeyboardDragActive = context.keyboardDragId !== null;
235
+ // ----- registration (unchanged) -----------------------------------------
124
236
  useEffect(() => {
125
237
  if (dropRef.current) {
126
238
  context.registerDropZone(stableId, dropRef.current);
@@ -129,7 +241,7 @@ const Droppable = React__default.forwardRef(({ children, acceptedTypes, classNam
129
241
  context.unregisterDropZone(stableId);
130
242
  };
131
243
  }, [stableId, context]);
132
- // Compute drag-over state precisely based on pointer location using rAF
244
+ // ----- pointer drag-over detection (unchanged) --------------------------
133
245
  useEffect(() => {
134
246
  if (!context.activeDrag) {
135
247
  if (isDragOver) {
@@ -173,12 +285,11 @@ const Droppable = React__default.forwardRef(({ children, acceptedTypes, classNam
173
285
  cancelAnimationFrame(rafIdRef.current);
174
286
  };
175
287
  }, [acceptedTypes, isDragOver, onDragEnter, onDragLeave, context.activeDrag]);
176
- // Handle drop
288
+ // ----- pointer drop handler (unchanged) ---------------------------------
177
289
  useEffect(() => {
178
290
  const handleDrop = (event) => {
179
291
  const customEvent = event;
180
292
  const data = customEvent.detail;
181
- // Check if type is accepted
182
293
  if (acceptedTypes && acceptedTypes.length > 0) {
183
294
  if (!acceptedTypes.includes(data.type || '')) {
184
295
  return;
@@ -197,6 +308,46 @@ const Droppable = React__default.forwardRef(({ children, acceptedTypes, classNam
197
308
  }
198
309
  };
199
310
  }, [acceptedTypes, onDrop]);
311
+ // ----- keyboard: announce when this zone receives focus -----------------
312
+ const handleFocus = useCallback(() => {
313
+ if (!isKeyboardDragActive)
314
+ return;
315
+ const order = context.dropZoneOrder.current;
316
+ const zoneIndex = order.indexOf(stableId);
317
+ const zoneNumber = zoneIndex === -1 ? '' : ` ${zoneIndex + 1}`;
318
+ context.announce(`Over drop zone${zoneNumber}.`);
319
+ }, [isKeyboardDragActive, context, stableId]);
320
+ // ----- keyboard: Space/Enter completes the drop -------------------------
321
+ const handleKeyDown = useCallback((e) => {
322
+ if (!isKeyboardDragActive)
323
+ return;
324
+ if (e.key !== ' ' && e.key !== 'Enter')
325
+ return;
326
+ e.preventDefault();
327
+ const grabbedId = context.keyboardDragId;
328
+ const grabbedLabel = context.keyboardDragLabel;
329
+ if (!grabbedId)
330
+ return;
331
+ // Check type acceptance
332
+ const draggedDragData = { id: grabbedId };
333
+ if (acceptedTypes && acceptedTypes.length > 0) ;
334
+ const order = context.dropZoneOrder.current;
335
+ const zoneIndex = order.indexOf(stableId);
336
+ const zoneNumber = zoneIndex === -1 ? '' : ` ${zoneIndex + 1}`;
337
+ // Fire the drop callback
338
+ onDrop === null || onDrop === void 0 ? void 0 : onDrop(draggedDragData);
339
+ // Also fire as a custom event so compound setups with `motion-drop`
340
+ // listeners on the DOM element are notified
341
+ if (dropRef.current) {
342
+ const dropEvent = new CustomEvent('motion-drop', {
343
+ detail: draggedDragData,
344
+ bubbles: true,
345
+ });
346
+ dropRef.current.dispatchEvent(dropEvent);
347
+ }
348
+ context.announce(`${grabbedLabel} dropped in position${zoneNumber}.`);
349
+ context.endKeyboardDrag();
350
+ }, [isKeyboardDragActive, context, stableId, acceptedTypes, onDrop]);
200
351
  return (jsx(motion.div, { ref: (node) => {
201
352
  dropRef.current = node;
202
353
  if (typeof ref === 'function') {
@@ -210,8 +361,10 @@ const Droppable = React__default.forwardRef(({ children, acceptedTypes, classNam
210
361
  zIndex: 0,
211
362
  }, className: cn(theme.droppableStyle, isDragOver && theme.dragOverStyle, className), animate: isDragOver ? 'dragOver' : 'idle', variants: {
212
363
  idle: { scale: 1 },
213
- dragOver: { scale: 1.01 }
214
- }, transition: { duration: 0.15 }, children: typeof children === 'function' ? children(isDragOver) : children }));
364
+ dragOver: { scale: 1.01 },
365
+ }, transition: { duration: 0.15 },
366
+ // Keyboard accessibility: become reachable only while a keyboard drag is active
367
+ tabIndex: isKeyboardDragActive ? 0 : undefined, role: isKeyboardDragActive ? 'button' : undefined, "aria-label": isKeyboardDragActive ? 'Drop here' : undefined, "data-dropzone-id": stableId, onFocus: handleFocus, onKeyDown: handleKeyDown, children: typeof children === 'function' ? children(isDragOver) : children }));
215
368
  });
216
369
  Droppable.displayName = 'Droppable';
217
370
 
@@ -34,6 +34,12 @@ export interface DraggableProps {
34
34
  onDragEnd?: (data: DragData, info: PanInfo) => void;
35
35
  /** Disable dragging */
36
36
  disabled?: boolean;
37
+ /**
38
+ * Accessible label used in keyboard-drag announcements.
39
+ * Defaults to the dragData.id when omitted.
40
+ * Example: "Task card – Fix login bug"
41
+ */
42
+ dragLabel?: string;
37
43
  }
38
44
  export interface DroppableProps {
39
45
  /** Content of the drop zone */
@@ -9,7 +9,7 @@ export declare const Drawer: {
9
9
  displayName: string;
10
10
  };
11
11
  Title: {
12
- ({ children, className, ...props }: import("./Drawer.types").DrawerTitleProps): import("react/jsx-runtime").JSX.Element;
12
+ ({ children, className, as: Tag, ...props }: import("./Drawer.types").DrawerTitleProps): import("react/jsx-runtime").JSX.Element;
13
13
  displayName: string;
14
14
  };
15
15
  Subtitle: {
@@ -17,6 +17,8 @@ function useCloseOnBack(isOpen, onClose, enabled) {
17
17
  useEffect(() => {
18
18
  if (!enabled || !isOpen)
19
19
  return;
20
+ if (typeof window === "undefined")
21
+ return;
20
22
  closedByPopstate.current = false;
21
23
  history.pushState({ flikDrawer: true }, "");
22
24
  const handlePopstate = () => {
@@ -78,6 +78,8 @@ export interface DrawerHeaderProps extends React.HTMLAttributes<HTMLDivElement>
78
78
  export interface DrawerTitleProps extends React.HTMLAttributes<HTMLHeadingElement> {
79
79
  children: React.ReactNode;
80
80
  className?: string;
81
+ /** Heading level to render. Defaults to 'h2'. */
82
+ as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
81
83
  }
82
84
  export interface DrawerSubtitleProps extends React.HTMLAttributes<HTMLParagraphElement> {
83
85
  children: React.ReactNode;
@@ -1,5 +1,5 @@
1
1
  import { DrawerTitleProps } from "./Drawer.types";
2
2
  export declare const DrawerTitle: {
3
- ({ children, className, ...props }: DrawerTitleProps): import("react/jsx-runtime").JSX.Element;
3
+ ({ children, className, as: Tag, ...props }: DrawerTitleProps): import("react/jsx-runtime").JSX.Element;
4
4
  displayName: string;
5
5
  };
@@ -2,9 +2,9 @@ import { jsx } from 'react/jsx-runtime';
2
2
  import { cn } from '../../../utils/cn.js';
3
3
  import { useDrawerContext } from './Drawer.js';
4
4
 
5
- const DrawerTitle = ({ children, className, ...props }) => {
5
+ const DrawerTitle = ({ children, className, as: Tag = 'h2', ...props }) => {
6
6
  const { theme, titleId } = useDrawerContext();
7
- return (jsx("h2", { id: titleId, className: cn(theme.title, className), ...props, children: children }));
7
+ return (jsx(Tag, { id: titleId, className: cn(theme.title, className), ...props, children: children }));
8
8
  };
9
9
  DrawerTitle.displayName = "Drawer.Title";
10
10
 
@@ -7,36 +7,8 @@ import { useDropdownContext } from './DropdownContext.js';
7
7
  import { useClickOutside } from '../../../hooks/useClickOutside.js';
8
8
  import { useSelectPortal } from '../../../hooks/useSelectPortal.js';
9
9
  import { useIsClient } from '../../../hooks/useIsClient.js';
10
+ import { useDarkMode } from '../../../hooks/useDarkMode.js';
10
11
 
11
- /**
12
- * Hook to detect dark mode state from document
13
- */
14
- const useDarkMode = () => {
15
- const [isDark, setIsDark] = useState(false);
16
- useEffect(() => {
17
- if (typeof document === "undefined")
18
- return;
19
- const checkDarkMode = () => {
20
- const hasDarkClass = document.documentElement.classList.contains("dark") ||
21
- document.body.classList.contains("dark") ||
22
- document.querySelector(".dark") !== null;
23
- setIsDark(hasDarkClass);
24
- };
25
- checkDarkMode();
26
- // Observe class changes on html and body
27
- const observer = new MutationObserver(checkDarkMode);
28
- observer.observe(document.documentElement, {
29
- attributes: true,
30
- attributeFilter: ["class"],
31
- });
32
- observer.observe(document.body, {
33
- attributes: true,
34
- attributeFilter: ["class"],
35
- });
36
- return () => observer.disconnect();
37
- }, []);
38
- return isDark;
39
- };
40
12
  /**
41
13
  * DropdownMenu component - renders the menu with keyboard navigation
42
14
  */
@@ -208,7 +180,7 @@ const DropdownMenu = React__default.forwardRef(({ children, className, animation
208
180
  ...cssVariables,
209
181
  top: `${position.top}px`,
210
182
  left: `${position.left}px`,
211
- }, id: menuId, role: "menu", "aria-label": ariaLabel || "Menu", "aria-orientation": horizontal ? "horizontal" : "vertical", tabIndex: -1, onKeyDown: handleKeyDown, variants: shouldReduceMotion || !animation ? {} : menuVariants, initial: shouldReduceMotion || !animation ? undefined : "hidden", animate: shouldReduceMotion || !animation ? undefined : "visible", exit: shouldReduceMotion || !animation ? undefined : "exit", transition: shouldReduceMotion || !animation
183
+ }, id: menuId, role: "menu", "aria-label": ariaLabel || undefined, "aria-orientation": horizontal ? "horizontal" : "vertical", tabIndex: -1, onKeyDown: handleKeyDown, variants: shouldReduceMotion || !animation ? {} : menuVariants, initial: shouldReduceMotion || !animation ? undefined : "hidden", animate: shouldReduceMotion || !animation ? undefined : "visible", exit: shouldReduceMotion || !animation ? undefined : "exit", transition: shouldReduceMotion || !animation
212
184
  ? { duration: 0 }
213
185
  : {
214
186
  type: "spring",
@@ -5,7 +5,7 @@ const emptyTheme = {
5
5
  // Base container styles - customizable spacing, colors, and layout
6
6
  baseStyle: "flex flex-col items-center justify-center text-center w-full max-w-md mx-auto space-y-3 py-12 px-6 ",
7
7
  // Title text styles - customizable typography and colors
8
- titleStyle: "text-base font-semibold text-[var(--color-text-primary)]",
8
+ titleStyle: "text-sm font-semibold text-[var(--color-text-primary)]",
9
9
  // Description text styles - customizable typography and colors
10
10
  subtitleStyle: "text-sm text-[var(--color-text-muted)]",
11
11
  };
@@ -35,7 +35,7 @@ onAnimationStart: _onAnimationStart, onAnimationEnd: _onAnimationEnd, onDrag: _o
35
35
  }, [shouldReduceMotion]);
36
36
  return (jsx(motion.a, { ref: ref, href: disabled ? undefined : href, className: cn(buttonTheme.baseStyle, themeClasses.colorClasses, themeClasses.variantClasses, themeClasses.sizeClasses, themeClasses.stateClasses,
37
37
  // Special case for link variant to have an underline
38
- "underline underline-offset-4 rounded-none font-semibold", className), "data-color": color, "data-variant": resolvedVariant, "data-size": size, "aria-disabled": disabled || undefined, ...(disabled ? {} : animationProps), ...props, children: children }));
38
+ "underline underline-offset-4 rounded-none font-semibold text-sm", className), "data-color": color, "data-variant": resolvedVariant, "data-size": size, "aria-disabled": disabled || undefined, ...(disabled ? {} : animationProps), ...props, children: children }));
39
39
  });
40
40
  Link.displayName = "Link";
41
41
 
@@ -13,6 +13,7 @@ const MASONRY_ITEM_TRANSITION_BASE = {
13
13
  };
14
14
  const Masonry = React__default.forwardRef(({ children, columns = 3, gap = 16, gapBreakpoints, className, style, minColumns = 1, maxColumns = 10, sequential = false, themeOverrides, loading = false, ...props }, ref) => {
15
15
  const containerRef = useRef(null);
16
+ const arrangeItemsRef = useRef(() => { });
16
17
  const [currentColumns, setCurrentColumns] = useState(typeof columns === 'number' ? columns : 3);
17
18
  const [currentGap, setCurrentGap] = useState(gap);
18
19
  const [containerWidth, setContainerWidth] = useState(0);
@@ -174,6 +175,10 @@ const Masonry = React__default.forwardRef(({ children, columns = 3, gap = 16, ga
174
175
  }, 0);
175
176
  return () => clearTimeout(timer);
176
177
  }, [calculateLayout, arrangeItems, children, containerWidth]);
178
+ // Keep ref in sync so the MutationObserver always calls the latest version
179
+ useEffect(() => {
180
+ arrangeItemsRef.current = arrangeItems;
181
+ }, [arrangeItems]);
177
182
  // Re-arrange when children change (with debouncing)
178
183
  useEffect(() => {
179
184
  let timeoutId;
@@ -181,7 +186,7 @@ const Masonry = React__default.forwardRef(({ children, columns = 3, gap = 16, ga
181
186
  // Debounce multiple rapid changes
182
187
  clearTimeout(timeoutId);
183
188
  timeoutId = setTimeout(() => {
184
- arrangeItems();
189
+ arrangeItemsRef.current();
185
190
  }, 10);
186
191
  });
187
192
  if (containerRef.current) {
@@ -194,7 +199,7 @@ const Masonry = React__default.forwardRef(({ children, columns = 3, gap = 16, ga
194
199
  observer.disconnect();
195
200
  clearTimeout(timeoutId);
196
201
  };
197
- }, [arrangeItems]);
202
+ }, []);
198
203
  // Generate container classes
199
204
  const containerClasses = cn(theme.container.base, loading && theme.container.loading, className);
200
205
  // Wrap each child in a positioning div with theme styles
@@ -11,7 +11,7 @@ export declare const Modal: {
11
11
  displayName: string;
12
12
  };
13
13
  Title: {
14
- ({ children, className, ...props }: import("./Modal.types").ModalTitleProps): import("react/jsx-runtime").JSX.Element;
14
+ ({ children, className, as: Tag, ...props }: import("./Modal.types").ModalTitleProps): import("react/jsx-runtime").JSX.Element;
15
15
  displayName: string;
16
16
  };
17
17
  Subtitle: {
@@ -1,5 +1,5 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { createContext, useId, useState, useEffect, useContext } from 'react';
2
+ import { createContext, useId, useState, useEffect, useMemo, useContext } from 'react';
3
3
  import { cn } from '../../../utils/cn.js';
4
4
  import { Overlay } from '../../effects/Overlay/Overlay.js';
5
5
  import { modalTheme, modalSizeVariants } from './Modal.theme.js';
@@ -45,7 +45,7 @@ const ModalRoot = ({ isOpen, onClose, size = "md", variant = "default", closeOnO
45
45
  },
46
46
  };
47
47
  // Context value
48
- const contextValue = {
48
+ const contextValue = useMemo(() => ({
49
49
  isOpen,
50
50
  onClose,
51
51
  size,
@@ -58,7 +58,7 @@ const ModalRoot = ({ isOpen, onClose, size = "md", variant = "default", closeOnO
58
58
  setIsBodyScrollable,
59
59
  titleId,
60
60
  subtitleId,
61
- };
61
+ }), [isOpen, onClose, size, isSizeToken, closeOnOverlayClick, closeOnEsc, showCloseButton, theme, isBodyScrollable, setIsBodyScrollable, titleId, subtitleId]);
62
62
  return (jsx(Overlay, { isOpen: isOpen, onClose: onClose, closeOnOverlayClick: closeOnOverlayClick, closeOnEsc: closeOnEsc, position: "center", role: role, ariaModal: true, ariaLabelledBy: titleId, ariaDescribedBy: subtitleId, contentClassName: cn(theme.container, (_a = theme.containerVariants) === null || _a === void 0 ? void 0 : _a[variant], isSizeToken ? modalSizeVariants[size] : size, className), animations: {
63
63
  overlay: modalOverlayAnimations,
64
64
  content: modalContentAnimations,
@@ -89,6 +89,8 @@ export interface ModalFooterProps extends React.HTMLAttributes<HTMLDivElement> {
89
89
  export interface ModalTitleProps extends React.HTMLAttributes<HTMLHeadingElement> {
90
90
  children: React.ReactNode;
91
91
  className?: string;
92
+ /** Heading level to render. Defaults to 'h2'. */
93
+ as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
92
94
  }
93
95
  export interface ModalSubtitleProps extends React.HTMLAttributes<HTMLParagraphElement> {
94
96
  children: React.ReactNode;
@@ -1,5 +1,5 @@
1
1
  import { ModalTitleProps } from "./Modal.types";
2
2
  export declare const ModalTitle: {
3
- ({ children, className, ...props }: ModalTitleProps): import("react/jsx-runtime").JSX.Element;
3
+ ({ children, className, as: Tag, ...props }: ModalTitleProps): import("react/jsx-runtime").JSX.Element;
4
4
  displayName: string;
5
5
  };
@@ -2,9 +2,9 @@ import { jsx } from 'react/jsx-runtime';
2
2
  import { cn } from '../../../utils/cn.js';
3
3
  import { useModalContext } from './Modal.js';
4
4
 
5
- const ModalTitle = ({ children, className, ...props }) => {
5
+ const ModalTitle = ({ children, className, as: Tag = 'h2', ...props }) => {
6
6
  const { theme, titleId } = useModalContext();
7
- return (jsx("div", { id: titleId, className: cn(theme.title, className), ...props, children: children }));
7
+ return (jsx(Tag, { id: titleId, className: cn(theme.title, className), ...props, children: children }));
8
8
  };
9
9
  ModalTitle.displayName = "Modal.Title";
10
10
 
@@ -145,16 +145,21 @@ notification, description, shortcut, href, onClick, active = false, disabled = f
145
145
  ? React__default.cloneElement(startContent, {
146
146
  className: cn(iconClasses, startContent.props.className),
147
147
  })
148
- : startContent, isCollapsedView && notificationElement && (jsx("span", { className: "absolute -top-1 -right-1", children: notificationElement }))] })), jsxs("div", { className: "min-w-0 overflow-hidden", "aria-hidden": isCollapsedView || undefined, style: {
149
- flex: "1 1 auto",
150
- maxWidth: isCollapsedView ? 0 : 9999,
148
+ : startContent, isCollapsedView && notificationElement && (jsx("span", { className: "absolute -top-1 -right-1", children: notificationElement }))] })), jsx("div", { "aria-hidden": isCollapsedView || undefined, style: {
149
+ display: 'grid',
150
+ gridTemplateColumns: isCollapsedView ? '0fr' : '1fr',
151
+ overflow: 'hidden',
152
+ flex: '1 1 auto',
151
153
  opacity: isCollapsedView ? 0 : 1,
152
- transition: "max-width 0.18s cubic-bezier(0.4,0,0.2,1), opacity 0.12s ease-out",
153
- }, children: [jsxs("div", { className: "flex items-center justify-between gap-2", children: [jsx("span", { className: cn("truncate", textClasses), children: children }), shortcut && (jsx("kbd", { className: "hidden group-hover:inline-block text-sm text-[var(--color-text-muted)] font-sans border border-[var(--color-border)] rounded px-1.5 py-0.5", children: shortcut }))] }), description && (jsx("div", { className: "text-sm text-[var(--color-text-muted)] mt-0.5 truncate", children: description }))] }), jsxs("div", { className: "flex items-center gap-1.5 flex-shrink-0 overflow-hidden", style: {
154
- maxWidth: isCollapsedView ? 0 : 120,
154
+ transition: 'grid-template-columns 0.18s cubic-bezier(0.4,0,0.2,1), opacity 0.12s ease-out',
155
+ }, children: jsxs("div", { style: { overflow: 'hidden', minWidth: 0 }, children: [jsxs("div", { className: "flex items-center justify-between gap-2", children: [jsx("span", { className: cn("truncate", textClasses), children: children }), shortcut && (jsx("kbd", { className: "hidden group-hover:inline-block text-sm text-[var(--color-text-muted)] font-sans border border-[var(--color-border)] rounded px-1.5 py-0.5", children: shortcut }))] }), description && (jsx("div", { className: "text-sm text-[var(--color-text-muted)] mt-0.5 truncate", children: description }))] }) }), jsx("div", { style: {
156
+ display: 'grid',
157
+ gridTemplateColumns: isCollapsedView ? '0fr' : '1fr',
158
+ overflow: 'hidden',
159
+ flexShrink: 0,
155
160
  opacity: isCollapsedView ? 0 : 1,
156
- transition: "max-width 0.18s cubic-bezier(0.4,0,0.2,1), opacity 0.12s ease-out",
157
- }, children: [notificationElement, endContent, chevron] }), isCollapsedView && (jsx("span", { className: "sr-only", children: children }))] }));
161
+ transition: 'grid-template-columns 0.18s cubic-bezier(0.4,0,0.2,1), opacity 0.12s ease-out',
162
+ }, children: jsxs("div", { className: "flex items-center gap-1.5", style: { overflow: 'hidden', minWidth: 0 }, children: [notificationElement, endContent, chevron] }) }), isCollapsedView && (jsx("span", { className: "sr-only", children: children }))] }));
158
163
  // Self-contained submenu
159
164
  const submenu = hasSubmenu && items && items.length > 0 && !isCollapsedView ? (jsx(AnimatePresence, { initial: false, children: isExpanded && (jsx(motion.div, { initial: "collapsed", animate: "open", exit: "collapsed", variants: {
160
165
  open: { opacity: 1, height: "auto" },
@@ -79,7 +79,7 @@ const Pagination = React__default.forwardRef(({ currentPage, totalPages, onPageC
79
79
  const isLastPage = currentPage === totalPages;
80
80
  return (jsxs("nav", { ref: ref, role: "navigation", "aria-label": "Pagination Navigation", className: cn(theme.baseStyle, className), ...props, children: [showFirstLast && (jsxs(PaginationItem, { size: size, isDisabled: isFirstPage, onClick: () => handlePageChange(1), "aria-label": "Go to first page", children: [jsx(ChevronDoubleLeftIcon, { className: "w-4 h-4" }), jsx("span", { className: "sr-only", children: "First" })] })), showPrevNext && (jsxs(PaginationItem, { size: size, isDisabled: isFirstPage, onClick: () => handlePageChange(currentPage - 1), "aria-label": `Go to previous page (${currentPage - 1})`, children: [jsx(ChevronLeftIcon, { className: "w-4 h-4" }), jsx("span", { className: "sr-only", children: "Previous" })] })), paginationRange.map((pageNumber, index) => {
81
81
  if (pageNumber === "...") {
82
- return (jsxs(PaginationItem, { size: size, variant: "ellipsis", isDisabled: true, "aria-label": "More pages", role: "separator", children: [jsx("span", { "aria-hidden": "true", children: "\u2026" }), jsx("span", { className: "sr-only", children: "More pages" })] }, `ellipsis-${index}`));
82
+ return (jsx("span", { role: "separator", "aria-hidden": "true", children: "\u2026" }, `ellipsis-${index}`));
83
83
  }
84
84
  const page = pageNumber;
85
85
  const isActive = page === currentPage;
@@ -1,5 +1,5 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import React__default, { useRef, useEffect, useCallback, useState } from 'react';
2
+ import React__default, { useRef, useEffect, useCallback } from 'react';
3
3
  import { useReducedMotion, AnimatePresence, motion } from 'motion/react';
4
4
  import { createPortal } from 'react-dom';
5
5
  import { cn } from '../../../utils/cn.js';
@@ -9,6 +9,7 @@ import { popoverTransitions, popoverContentVariants } from './Popover.animations
9
9
  import { useSelectPortal } from '../../../hooks/useSelectPortal.js';
10
10
  import { Overlay } from '../../effects/Overlay/Overlay.js';
11
11
  import { useIsClient } from '../../../hooks/useIsClient.js';
12
+ import { useDarkMode } from '../../../hooks/useDarkMode.js';
12
13
 
13
14
  /** Overlay backdrop animations (fade in/out) */
14
15
  const overlayBackdropAnimations = {
@@ -22,31 +23,6 @@ const overlayContentAnimations = {
22
23
  animate: { opacity: 1, scale: 1, transition: { duration: 0.2 } },
23
24
  exit: { opacity: 0, scale: 0.95, transition: { duration: 0.15 } },
24
25
  };
25
- const useDarkMode = () => {
26
- const [isDark, setIsDark] = useState(false);
27
- useEffect(() => {
28
- if (typeof document === "undefined")
29
- return;
30
- const checkDarkMode = () => {
31
- const hasDarkClass = document.documentElement.classList.contains("dark") ||
32
- document.body.classList.contains("dark") ||
33
- document.querySelector(".dark") !== null;
34
- setIsDark(hasDarkClass);
35
- };
36
- checkDarkMode();
37
- const observer = new MutationObserver(checkDarkMode);
38
- observer.observe(document.documentElement, {
39
- attributes: true,
40
- attributeFilter: ["class"],
41
- });
42
- observer.observe(document.body, {
43
- attributes: true,
44
- attributeFilter: ["class"],
45
- });
46
- return () => observer.disconnect();
47
- }, []);
48
- return isDark;
49
- };
50
26
  /**
51
27
  * PopoverBody component displays the body/content of the popover
52
28
  */
@@ -140,7 +116,7 @@ const PopoverBody = React__default.forwardRef(({ children, className, animation
140
116
  : undefined, children: jsx("div", { id: contentId, "data-state": isOpen ? "open" : "closed", "data-placement": placement, "data-trigger": triggerType, ...domProps, children: children }) }));
141
117
  }
142
118
  // Without backdrop: manual portal + positioning + escape + click-outside
143
- const popoverContent = (jsx(AnimatePresence, { children: isOpen && (jsx(motion.div, { ref: handleRef, id: contentId, className: cn("fixed z-50", contentClasses), style: contentPositionStyle, role: "dialog", "aria-modal": "true", variants: shouldReduceMotion || !animation ? {} : popoverContentVariants, initial: shouldReduceMotion || !animation ? undefined : "hidden", animate: shouldReduceMotion || !animation ? undefined : (isReady ? "visible" : "hidden"), exit: shouldReduceMotion || !animation ? undefined : "exit", transition: shouldReduceMotion || !animation
119
+ const popoverContent = (jsx(AnimatePresence, { children: isOpen && (jsx(motion.div, { ref: handleRef, id: contentId, className: cn("fixed z-50", contentClasses), style: contentPositionStyle, variants: shouldReduceMotion || !animation ? {} : popoverContentVariants, initial: shouldReduceMotion || !animation ? undefined : "hidden", animate: shouldReduceMotion || !animation ? undefined : (isReady ? "visible" : "hidden"), exit: shouldReduceMotion || !animation ? undefined : "exit", transition: shouldReduceMotion || !animation
144
120
  ? { duration: 0 }
145
121
  : popoverTransitions.content, "data-state": isOpen ? "open" : "closed", "data-placement": placement, "data-trigger": triggerType, onClick: (e) => e.stopPropagation(), ...domProps, children: children })) }));
146
122
  if (portal && isClient) {