@flikk/ui 1.0.0-beta.22 → 1.0.0-beta.24

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 (161) hide show
  1. package/dist/components/ai/PromptInput/PromptInput.js +139 -7
  2. package/dist/components/ai/PromptInput/VoiceRecorder.js +84 -0
  3. package/dist/components/charts/AreaChart/AreaChart.types.d.ts +2 -2
  4. package/dist/components/charts/BarChart/BarChart.types.d.ts +2 -2
  5. package/dist/components/charts/ComboChart/ComboChart.types.d.ts +2 -2
  6. package/dist/components/charts/LineChart/LineChart.types.d.ts +2 -2
  7. package/dist/components/charts/ScatterPlot/ScatterPlot.types.d.ts +2 -2
  8. package/dist/components/charts/StackedBarChart/StackedBarChart.types.d.ts +2 -2
  9. package/dist/components/core/Accordion/AccordionTrigger.js +28 -1
  10. package/dist/components/core/Alert/Alert.js +2 -1
  11. package/dist/components/core/AlertDialog/AlertDialog.js +1 -1
  12. package/dist/components/core/Badge/Badge.js +6 -17
  13. package/dist/components/core/Breadcrumbs/Breadcrumbs.js +17 -28
  14. package/dist/components/core/Calendar/Calendar.js +1 -1
  15. package/dist/components/core/Carousel/CarouselBody.js +6 -1
  16. package/dist/components/core/ContextMenu/ContextMenuBody.js +6 -3
  17. package/dist/components/core/ContextMenu/ContextMenuSubBody.js +6 -3
  18. package/dist/components/core/DragDrop/DragDrop.js +170 -17
  19. package/dist/components/core/DragDrop/DragDrop.types.d.ts +6 -0
  20. package/dist/components/core/Drawer/Drawer.d.ts +1 -1
  21. package/dist/components/core/Drawer/Drawer.js +2 -0
  22. package/dist/components/core/Drawer/Drawer.types.d.ts +2 -0
  23. package/dist/components/core/Drawer/DrawerTitle.d.ts +1 -1
  24. package/dist/components/core/Drawer/DrawerTitle.js +2 -2
  25. package/dist/components/core/Dropdown/DropdownMenu.js +2 -30
  26. package/dist/components/core/Masonry/Masonry.js +7 -2
  27. package/dist/components/core/Modal/Modal.d.ts +1 -1
  28. package/dist/components/core/Modal/Modal.js +3 -3
  29. package/dist/components/core/Modal/Modal.types.d.ts +2 -0
  30. package/dist/components/core/Modal/ModalTitle.d.ts +1 -1
  31. package/dist/components/core/Modal/ModalTitle.js +2 -2
  32. package/dist/components/core/NavItem/NavItem.js +21 -6
  33. package/dist/components/core/NavItem/NavItem.theme.js +2 -2
  34. package/dist/components/core/Pagination/Pagination.js +1 -1
  35. package/dist/components/core/Popover/PopoverBody.js +3 -27
  36. package/dist/components/core/Popover/PopoverTrigger.js +1 -1
  37. package/dist/components/core/Progress/Progress.js +4 -4
  38. package/dist/components/core/Rating/Rating.js +1 -1
  39. package/dist/components/core/ScrollArea/ScrollArea.js +3 -2
  40. package/dist/components/core/Segmented/Segmented.js +6 -6
  41. package/dist/components/core/Segmented/SegmentedItem.js +28 -2
  42. package/dist/components/core/Sidebar/Sidebar.d.ts +1 -0
  43. package/dist/components/core/Sidebar/Sidebar.js +5 -3
  44. package/dist/components/core/Sidebar/Sidebar.types.d.ts +7 -1
  45. package/dist/components/core/Sidebar/SidebarContent.js +1 -1
  46. package/dist/components/core/Sidebar/SidebarFooter.js +1 -1
  47. package/dist/components/core/Sidebar/SidebarHeader.js +5 -2
  48. package/dist/components/core/Sidebar/SidebarLogo.d.ts +3 -0
  49. package/dist/components/core/Sidebar/SidebarLogo.js +17 -0
  50. package/dist/components/core/Sidebar/SidebarNavGroup.js +2 -1
  51. package/dist/components/core/Sidebar/SidebarToggle.js +2 -4
  52. package/dist/components/core/Sidebar/SidebarUserProfile.js +3 -6
  53. package/dist/components/core/Sidebar/index.d.ts +2 -1
  54. package/dist/components/core/Skeleton/Skeleton.js +2 -2
  55. package/dist/components/core/Sortable/Sortable.d.ts +1 -1
  56. package/dist/components/core/Sortable/Sortable.js +20 -4
  57. package/dist/components/core/Sortable/Sortable.types.d.ts +2 -0
  58. package/dist/components/core/Tabs/Tabs.js +6 -4
  59. package/dist/components/core/Tabs/Tabs.types.d.ts +2 -0
  60. package/dist/components/core/Tabs/TabsBody.js +3 -3
  61. package/dist/components/core/Tabs/TabsList.js +19 -21
  62. package/dist/components/core/Tabs/TabsTrigger.js +47 -28
  63. package/dist/components/core/Toast/Toast.js +1 -1
  64. package/dist/components/core/Toast/ToastProvider.js +3 -2
  65. package/dist/components/core/Tooltip/Tooltip.d.ts +1 -1
  66. package/dist/components/core/Tooltip/Tooltip.js +26 -35
  67. package/dist/components/core/Tooltip/Tooltip.types.d.ts +5 -1
  68. package/dist/components/core/Tree/Tree.js +178 -8
  69. package/dist/components/core/index.js +1 -0
  70. package/dist/components/data-display/GanttChart/GanttSplitter.js +15 -1
  71. package/dist/components/data-display/Table/Table.js +2 -2
  72. package/dist/components/data-display/Table/Table.types.d.ts +2 -0
  73. package/dist/components/data-display/Table/TableFilter.js +21 -18
  74. package/dist/components/effects/CustomCursor/CustomCursor.js +3 -7
  75. package/dist/components/effects/Overlay/Overlay.js +4 -9
  76. package/dist/components/effects/PageTransition/PageTransition.js +17 -6
  77. package/dist/components/effects/SpotlightBorder/SpotlightBorder.js +3 -4
  78. package/dist/components/forms/Checkbox/Checkbox.js +11 -1
  79. package/dist/components/forms/Checkbox/Checkbox.theme.js +4 -1
  80. package/dist/components/forms/Checkbox/Checkbox.types.d.ts +7 -5
  81. package/dist/components/forms/Checkbox/CheckboxGroup.js +9 -4
  82. package/dist/components/forms/ColorPicker/ColorPicker.js +7 -4
  83. package/dist/components/forms/ColorPicker/ColorPicker.types.d.ts +2 -2
  84. package/dist/components/forms/ColorPicker/ColorPickerBody.js +5 -3
  85. package/dist/components/forms/ColorPicker/ColorPickerEyeDropper.js +3 -3
  86. package/dist/components/forms/ColorPicker/ColorPickerGradient.js +8 -8
  87. package/dist/components/forms/ColorPicker/ColorPickerInput.js +1 -1
  88. package/dist/components/forms/ColorPicker/index.d.ts +1 -1
  89. package/dist/components/forms/Combobox/Combobox.js +20 -45
  90. package/dist/components/forms/Combobox/Combobox.types.d.ts +4 -2
  91. package/dist/components/forms/CronInput/CronInput.js +10 -4
  92. package/dist/components/forms/CronInput/CronInput.types.d.ts +12 -1
  93. package/dist/components/forms/DatePicker/DatePicker.js +2 -2
  94. package/dist/components/forms/DatePicker/DatePicker.types.d.ts +4 -2
  95. package/dist/components/forms/DatePicker/DatePickerBody.js +1 -29
  96. package/dist/components/forms/DatePicker/DatePickerTrigger.js +2 -2
  97. package/dist/components/forms/DateRangePicker/DateRangePicker.js +3 -3
  98. package/dist/components/forms/DateRangePicker/DateRangePicker.types.d.ts +4 -2
  99. package/dist/components/forms/DateRangePicker/DateRangePickerBody.js +1 -28
  100. package/dist/components/forms/DateRangePicker/DateRangePickerTrigger.js +2 -2
  101. package/dist/components/forms/FileUpload/FileUpload.js +99 -10
  102. package/dist/components/forms/FileUpload/FileUpload.types.d.ts +15 -0
  103. package/dist/components/forms/FormLabel/FormLabel.js +2 -2
  104. package/dist/components/forms/Input/Input.js +5 -3
  105. package/dist/components/forms/Input/Input.types.d.ts +2 -0
  106. package/dist/components/forms/InputAddress/InputAddress.d.ts +1 -1
  107. package/dist/components/forms/InputAddress/InputAddress.js +8 -9
  108. package/dist/components/forms/InputCounter/InputCounter.js +25 -18
  109. package/dist/components/forms/InputCounter/InputCounter.types.d.ts +8 -1
  110. package/dist/components/forms/InputCreditCard/InputCreditCard.d.ts +1 -1
  111. package/dist/components/forms/InputCreditCard/InputCreditCard.js +27 -9
  112. package/dist/components/forms/InputCreditCard/InputCreditCard.types.d.ts +5 -0
  113. package/dist/components/forms/InputOTP/InputOTP.js +26 -17
  114. package/dist/components/forms/InputOTP/InputOTP.types.d.ts +21 -4
  115. package/dist/components/forms/InputTag/InputTag.js +12 -39
  116. package/dist/components/forms/InputTag/InputTag.types.d.ts +2 -2
  117. package/dist/components/forms/Mention/Mention.js +13 -6
  118. package/dist/components/forms/Mention/Mention.types.d.ts +9 -0
  119. package/dist/components/forms/Radio/Radio.js +12 -2
  120. package/dist/components/forms/Radio/Radio.theme.js +5 -1
  121. package/dist/components/forms/Radio/Radio.types.d.ts +7 -5
  122. package/dist/components/forms/Radio/RadioGroup.js +8 -3
  123. package/dist/components/forms/RichTextEditor/RichTextEditor.js +21 -21
  124. package/dist/components/forms/RichTextEditor/RichTextEditor.types.d.ts +2 -2
  125. package/dist/components/forms/Select/Select.d.ts +2 -0
  126. package/dist/components/forms/Select/Select.js +26 -56
  127. package/dist/components/forms/Select/Select.types.d.ts +14 -0
  128. package/dist/components/forms/Signature/Signature.js +1 -1
  129. package/dist/components/forms/Signature/Signature.types.d.ts +3 -3
  130. package/dist/components/forms/Slider/Slider.js +18 -4
  131. package/dist/components/forms/Slider/Slider.types.d.ts +2 -2
  132. package/dist/components/forms/Switch/Switch.js +12 -19
  133. package/dist/components/forms/Switch/Switch.theme.js +12 -2
  134. package/dist/components/forms/Switch/Switch.types.d.ts +20 -2
  135. package/dist/components/forms/Textarea/Textarea.js +8 -3
  136. package/dist/components/forms/Textarea/Textarea.types.d.ts +2 -0
  137. package/dist/components/forms/TimePicker/TimePicker.js +1 -1
  138. package/dist/components/forms/TimePicker/TimePicker.types.d.ts +6 -2
  139. package/dist/components/forms/TimePicker/TimePickerContent.js +88 -30
  140. package/dist/components/forms/TimePicker/TimePickerTrigger.js +2 -2
  141. package/dist/components/forms/index.js +86 -1
  142. package/dist/components/layout/FormLayout/FormLayout.js +87 -1
  143. package/dist/components/layout/index.js +4 -0
  144. package/dist/hooks/index.d.ts +1 -0
  145. package/dist/hooks/useClickOutside.d.ts +10 -4
  146. package/dist/hooks/useClickOutside.js +44 -24
  147. package/dist/hooks/useDarkMode.d.ts +1 -0
  148. package/dist/hooks/useDarkMode.js +42 -0
  149. package/dist/hooks/useFormStateMachine.d.ts +1 -1
  150. package/dist/hooks/useNetworkStatus.js +1 -1
  151. package/dist/hooks/useOverlay.js +4 -0
  152. package/dist/hooks/useScaleBackground.js +5 -2
  153. package/dist/hooks/useSelectPortal.js +14 -5
  154. package/dist/index.d.ts +0 -2
  155. package/dist/index.js +174 -223
  156. package/dist/shadcn-compat.css +80 -0
  157. package/dist/styles.css +1 -1
  158. package/dist/utils/stateMachine.d.ts +4 -4
  159. package/package.json +12 -10
  160. package/tailwind.preset.cjs +32 -3
  161. /package/{src/theme-plugin.css → dist/theme.css} +0 -0
@@ -19,6 +19,8 @@ const ContextMenuSubBody = React__default.forwardRef(({ children, className, ani
19
19
  // Update position when submenu opens
20
20
  useEffect(() => {
21
21
  if (isOpen && triggerRef.current) {
22
+ if (typeof window === "undefined")
23
+ return;
22
24
  const triggerRect = triggerRef.current.getBoundingClientRect();
23
25
  // Position to the right of the trigger
24
26
  let x = triggerRect.right + 4; // 4px offset
@@ -44,6 +46,8 @@ const ContextMenuSubBody = React__default.forwardRef(({ children, className, ani
44
46
  useEffect(() => {
45
47
  if (!isOpen)
46
48
  return;
49
+ if (typeof window === "undefined")
50
+ return;
47
51
  const handleScroll = () => {
48
52
  onOpenChange(false);
49
53
  };
@@ -97,9 +101,8 @@ const ContextMenuSubBody = React__default.forwardRef(({ children, className, ani
97
101
  damping: 30,
98
102
  }, "data-state": isOpen ? "open" : "closed", ...domProps, children: children })) }));
99
103
  // Always use portal for submenus
100
- return isClient
101
- ? createPortal(submenuContent, document.body)
102
- : null;
104
+ const portalTarget = isClient ? document.body : null;
105
+ return portalTarget ? createPortal(submenuContent, portalTarget) : null;
103
106
  });
104
107
  ContextMenuSubBody.displayName = "ContextMenu.SubBody";
105
108
 
@@ -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",
@@ -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
 
@@ -120,7 +120,6 @@ notification, description, shortcut, href, onClick, active = false, disabled = f
120
120
  const dangerClasses = isDanger ? theme.danger : "";
121
121
  // Active indicator
122
122
  const activeIndicatorClasses = isActive && level === 0 ? theme.activeIndicator : "";
123
- // Build container classes
124
123
  const containerClasses = cn(theme.baseStyle, getStateClasses(), theme.levels[level], isCollapsedView && ((_a = theme.collapsed) === null || _a === void 0 ? void 0 : _a.container), dangerClasses, activeIndicatorClasses, className);
125
124
  // Get icon state classes
126
125
  const getIconStateClasses = () => {
@@ -146,7 +145,21 @@ notification, description, shortcut, href, onClick, active = false, disabled = f
146
145
  ? React__default.cloneElement(startContent, {
147
146
  className: cn(iconClasses, startContent.props.className),
148
147
  })
149
- : startContent, isCollapsedView && notificationElement && (jsx("span", { className: "absolute -top-1 -right-1", children: notificationElement }))] })), !isCollapsedView && (jsxs("div", { className: "flex-1 min-w-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 }))] })), !isCollapsedView && (jsxs("div", { className: "flex items-center gap-1.5 flex-shrink-0", children: [notificationElement, endContent, chevron] })), isCollapsedView && (jsx("span", { className: "sr-only", children: children }))] }));
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',
153
+ opacity: isCollapsedView ? 0 : 1,
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,
160
+ opacity: isCollapsedView ? 0 : 1,
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 }))] }));
150
163
  // Self-contained submenu
151
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: {
152
165
  open: { opacity: 1, height: "auto" },
@@ -159,12 +172,14 @@ notification, description, shortcut, href, onClick, active = false, disabled = f
159
172
  }
160
173
  return node;
161
174
  };
162
- // Show tooltip in collapsed sidebar mode
175
+ // Always render Tooltip when in a sidebar (keeps tree structure stable across
176
+ // collapse/expand so CSS transitions aren't interrupted by DOM remounts).
177
+ // The tooltip is disabled when not in collapsed view.
163
178
  const renderWithTooltip = (node) => {
164
- if (isCollapsedView && showTooltipWhenCollapsed) {
165
- return (jsx(Tooltip, { content: children, placement: "right", children: node }));
179
+ if (!isInSidebar || !showTooltipWhenCollapsed) {
180
+ return node;
166
181
  }
167
- return node;
182
+ return (jsx(Tooltip, { content: children, placement: "right", disabled: !isCollapsedView, triggerClassName: "block w-full", children: node }));
168
183
  };
169
184
  return (jsxs(Fragment, { children: [renderWithTooltip(renderWrapped(content)), submenu] }));
170
185
  });
@@ -1,5 +1,5 @@
1
1
  const navItemTheme = {
2
- baseStyle: "relative flex items-center gap-2 px-2 py-1.5 text-sm font-medium cursor-pointer select-none transition-all duration-150 w-full rounded-[var(--nav-item-radius)] outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-primary)] group",
2
+ baseStyle: "relative flex items-center gap-2 px-2 py-1.5 text-sm font-medium cursor-pointer select-none transition-colors duration-150 w-full rounded-[var(--nav-item-radius)] outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-primary)] group overflow-hidden",
3
3
  icon: "size-4 text-[var(--color-text-secondary)]",
4
4
  text: "flex-1 min-w-0 truncate",
5
5
  states: {
@@ -19,7 +19,7 @@ const navItemTheme = {
19
19
  2: "pl-10",
20
20
  },
21
21
  collapsed: {
22
- container: "!gap-0 justify-center p-2 aspect-square",
22
+ container: "!gap-0 justify-center !p-2",
23
23
  icon: "size-5",
24
24
  },
25
25
  activeIndicator: "before:absolute before:left-0 before:top-1/2 before:-translate-y-1/2 before:h-5 before:w-[3px] before:rounded-full before:bg-[var(--color-primary)]",
@@ -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;