@flikk/ui 1.0.0-beta.31 → 1.0.0-beta.32

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 (428) hide show
  1. package/CHANGELOG.md +295 -22
  2. package/dist/components/ai/AgentRequest/AgentRequest.animations.d.ts +25 -0
  3. package/dist/components/ai/AgentRequest/AgentRequest.animations.js +81 -0
  4. package/dist/components/ai/AgentRequest/AgentRequest.d.ts +3 -0
  5. package/dist/components/ai/AgentRequest/AgentRequest.js +435 -0
  6. package/dist/components/ai/AgentRequest/AgentRequest.theme.d.ts +2 -0
  7. package/dist/components/ai/AgentRequest/AgentRequest.theme.js +106 -0
  8. package/dist/components/ai/AgentRequest/AgentRequest.types.d.ts +241 -0
  9. package/dist/components/ai/AgentRequest/index.d.ts +3 -0
  10. package/dist/components/ai/CodeBlock/CodeBlock.theme.js +1 -1
  11. package/dist/components/ai/PromptInput/PromptInput.js +2 -2
  12. package/dist/components/ai/PromptInput/PromptInput.theme.js +2 -2
  13. package/dist/components/ai/PromptSuggestion/PromptSuggestion.theme.js +2 -2
  14. package/dist/components/ai/Reasoning/Reasoning.js +27 -3
  15. package/dist/components/ai/Reasoning/Reasoning.theme.d.ts +6 -0
  16. package/dist/components/ai/Reasoning/Reasoning.theme.js +36 -0
  17. package/dist/components/ai/Reasoning/Reasoning.types.d.ts +58 -5
  18. package/dist/components/ai/Reasoning/ReasoningTrace.d.ts +11 -0
  19. package/dist/components/ai/Reasoning/ReasoningTrace.js +84 -0
  20. package/dist/components/ai/Reasoning/index.d.ts +2 -1
  21. package/dist/components/ai/StreamingResponse/AnimatedText.d.ts +7 -0
  22. package/dist/components/ai/StreamingResponse/AnimatedText.js +8 -7
  23. package/dist/components/ai/StreamingResponse/MarkdownRenderer.d.ts +5 -0
  24. package/dist/components/ai/StreamingResponse/MarkdownRenderer.js +4 -4
  25. package/dist/components/ai/StreamingResponse/StreamingCursor.d.ts +2 -2
  26. package/dist/components/ai/StreamingResponse/StreamingCursor.js +10 -7
  27. package/dist/components/ai/StreamingResponse/StreamingResponse.animations.d.ts +10 -0
  28. package/dist/components/ai/StreamingResponse/StreamingResponse.animations.js +59 -33
  29. package/dist/components/ai/StreamingResponse/StreamingResponse.js +13 -7
  30. package/dist/components/ai/StreamingResponse/StreamingResponse.types.d.ts +33 -2
  31. package/dist/components/ai/StreamingResponse/StreamingSurface.d.ts +13 -0
  32. package/dist/components/ai/StreamingResponse/StreamingSurface.js +38 -0
  33. package/dist/components/ai/StreamingResponse/WordAnimationContext.d.ts +5 -0
  34. package/dist/components/ai/StreamingResponse/WordAnimationContext.js +5 -4
  35. package/dist/components/ai/StreamingResponse/index.d.ts +4 -2
  36. package/dist/components/ai/TokenCounter/TokenCounter.theme.js +1 -1
  37. package/dist/components/ai/index.d.ts +3 -2
  38. package/dist/components/ai/index.js +4 -0
  39. package/dist/components/canvas/BaseNode.js +1 -1
  40. package/dist/components/canvas/CanvasToolbar.js +0 -1
  41. package/dist/components/canvas/Edge.js +2 -2
  42. package/dist/components/canvas/NodeControls.js +0 -1
  43. package/dist/components/canvas/NodeRenderer.js +2 -2
  44. package/dist/components/charts/ActivityRings/ActivityRings.js +2 -2
  45. package/dist/components/charts/ActivityRings/ActivityRings.theme.js +1 -1
  46. package/dist/components/charts/AreaChart/AreaChart.js +3 -3
  47. package/dist/components/charts/AreaChart/AreaChart.theme.js +3 -3
  48. package/dist/components/charts/BarChart/BarChart.js +4 -4
  49. package/dist/components/charts/ComboChart/BarRenderer.js +2 -2
  50. package/dist/components/charts/ComboChart/BarRenderer.types.d.ts +1 -1
  51. package/dist/components/charts/ComboChart/ComboChartCanvas.js +1 -1
  52. package/dist/components/charts/ComboChart/LineRenderer.js +1 -1
  53. package/dist/components/charts/ComboChart/LineRenderer.types.d.ts +1 -1
  54. package/dist/components/charts/DonutChart/DonutChart.theme.js +4 -4
  55. package/dist/components/charts/DonutChart/MultiSegmentDonutChart.theme.js +1 -1
  56. package/dist/components/charts/Heatmap/Heatmap.js +49 -42
  57. package/dist/components/charts/Heatmap/Heatmap.theme.d.ts +6 -2
  58. package/dist/components/charts/Heatmap/Heatmap.theme.js +20 -8
  59. package/dist/components/charts/Heatmap/Heatmap.types.d.ts +49 -82
  60. package/dist/components/charts/Heatmap/HeatmapCell.js +30 -81
  61. package/dist/components/charts/Heatmap/HeatmapLegend.d.ts +7 -6
  62. package/dist/components/charts/Heatmap/HeatmapLegend.js +6 -6
  63. package/dist/components/charts/Heatmap/index.d.ts +1 -1
  64. package/dist/components/charts/Heatmap/utils/heatmapUtils.d.ts +7 -12
  65. package/dist/components/charts/Heatmap/utils/heatmapUtils.js +16 -61
  66. package/dist/components/charts/Heatmap/utils/heatmapUtils.test.d.ts +1 -0
  67. package/dist/components/charts/HorizontalBarChart/HorizontalBarChart.js +1 -1
  68. package/dist/components/charts/LineChart/LineChart.js +2 -2
  69. package/dist/components/charts/LollipopChart/LollipopChart.js +1 -1
  70. package/dist/components/charts/RadarChart/RadarChart.js +1 -1
  71. package/dist/components/charts/StackedBarChart/StackedBarChart.js +3 -3
  72. package/dist/components/charts/hooks/useChartAccessibility.js +9 -6
  73. package/dist/components/charts/index.d.ts +4 -8
  74. package/dist/components/charts/index.js +2 -4
  75. package/dist/components/charts/shared/ChartText/ChartText.theme.js +1 -1
  76. package/dist/components/charts/shared/index.d.ts +1 -1
  77. package/dist/components/charts/theme/chart.theme.js +3 -3
  78. package/dist/components/charts/utils/animation-utils.d.ts +12 -7
  79. package/dist/components/charts/utils/animation-utils.js +19 -19
  80. package/dist/components/core/Accordion/Accordion.theme.js +1 -1
  81. package/dist/components/core/Alert/Alert.animations.d.ts +11 -4
  82. package/dist/components/core/Alert/Alert.animations.js +11 -4
  83. package/dist/components/core/Alert/Alert.js +16 -2
  84. package/dist/components/core/Alert/Alert.theme.js +1 -1
  85. package/dist/components/core/Alert/Alert.types.d.ts +4 -2
  86. package/dist/components/core/AlertDialog/AlertDialog.js +2 -2
  87. package/dist/components/core/Avatar/Avatar.theme.js +1 -1
  88. package/dist/components/core/Badge/Badge.animations.d.ts +0 -5
  89. package/dist/components/core/Badge/Badge.animations.js +5 -84
  90. package/dist/components/core/Badge/Badge.d.ts +7 -4
  91. package/dist/components/core/Badge/Badge.js +27 -64
  92. package/dist/components/core/Badge/Badge.theme.js +8 -12
  93. package/dist/components/core/Badge/Badge.types.d.ts +18 -34
  94. package/dist/components/core/Breadcrumbs/Breadcrumbs.theme.js +4 -4
  95. package/dist/components/core/Button/Button.js +7 -43
  96. package/dist/components/core/Button/Button.theme.js +2 -2
  97. package/dist/components/core/Button/Button.types.d.ts +8 -12
  98. package/dist/components/core/Button/index.d.ts +0 -2
  99. package/dist/components/core/Calendar/Calendar.theme.js +1 -1
  100. package/dist/components/core/Calendar/CalendarMini/CalendarMini.theme.js +2 -2
  101. package/dist/components/core/Card/Card.js +7 -2
  102. package/dist/components/core/Card/Card.theme.js +29 -1
  103. package/dist/components/core/Card/Card.types.d.ts +20 -0
  104. package/dist/components/core/Card/CardBody.js +9 -1
  105. package/dist/components/core/Card/CardContext.d.ts +13 -0
  106. package/dist/components/core/Card/CardContext.js +14 -0
  107. package/dist/components/core/Card/CardHeader.js +4 -1
  108. package/dist/components/core/ContextMenu/ContextMenu.theme.js +4 -3
  109. package/dist/components/core/ContextMenu/ContextMenu.types.d.ts +8 -1
  110. package/dist/components/core/ContextMenu/ContextMenuSub.d.ts +11 -1
  111. package/dist/components/core/ContextMenu/ContextMenuSub.js +35 -22
  112. package/dist/components/core/ContextMenu/ContextMenuSubBody.js +14 -3
  113. package/dist/components/core/ContextMenu/ContextMenuSubTrigger.js +21 -8
  114. package/dist/components/core/DragDrop/DragDrop.theme.js +2 -2
  115. package/dist/components/core/Drawer/Drawer.theme.js +1 -1
  116. package/dist/components/core/Drawer/DrawerHeader.js +0 -1
  117. package/dist/components/core/Dropdown/DropdownMenu.js +22 -7
  118. package/dist/components/core/Link/Link.js +1 -1
  119. package/dist/components/core/Masonry/Masonry.theme.js +1 -1
  120. package/dist/components/core/MenuItem/MenuItem.js +2 -1
  121. package/dist/components/core/MenuItem/MenuItem.theme.js +13 -1
  122. package/dist/components/core/Message/Message.js +2 -0
  123. package/dist/components/core/Message/Message.theme.js +3 -3
  124. package/dist/components/core/Modal/Modal.animations.d.ts +1 -1
  125. package/dist/components/core/Modal/Modal.animations.js +50 -11
  126. package/dist/components/core/Modal/Modal.js +5 -1
  127. package/dist/components/core/Modal/Modal.theme.js +1 -1
  128. package/dist/components/core/Modal/ModalHeader.js +0 -1
  129. package/dist/components/core/ModalStack/ModalStackModal.js +3 -1
  130. package/dist/components/core/NavItem/NavItem.js +3 -2
  131. package/dist/components/core/NavItem/NavItem.theme.js +1 -1
  132. package/dist/components/core/OfflineIndicator/OfflineIndicator.theme.js +4 -2
  133. package/dist/components/core/PageHeading/PageHeading.theme.js +1 -1
  134. package/dist/components/core/Pagination/Pagination.theme.js +2 -2
  135. package/dist/components/core/Pill/Pill.js +2 -1
  136. package/dist/components/core/Pill/Pill.theme.js +4 -2
  137. package/dist/components/core/Popover/PopoverBody.js +16 -5
  138. package/dist/components/core/Progress/Progress.d.ts +0 -25
  139. package/dist/components/core/Progress/Progress.js +79 -11
  140. package/dist/components/core/Progress/Progress.theme.js +17 -0
  141. package/dist/components/core/Progress/Progress.types.d.ts +47 -1
  142. package/dist/components/core/Rating/Rating.theme.js +1 -1
  143. package/dist/components/core/Rating/Rating.types.d.ts +3 -2
  144. package/dist/components/core/ScrollArea/ScrollArea.js +1 -1
  145. package/dist/components/core/ScrollArea/ScrollArea.theme.js +1 -1
  146. package/dist/components/core/Segmented/Segmented.theme.js +3 -3
  147. package/dist/components/core/Segmented/SegmentedContext.js +1 -0
  148. package/dist/components/core/Sidebar/Sidebar.js +5 -2
  149. package/dist/components/core/Sidebar/Sidebar.theme.js +2 -2
  150. package/dist/components/core/Sidebar/SidebarContent.js +1 -1
  151. package/dist/components/core/Sidebar/SidebarHeader.js +1 -1
  152. package/dist/components/core/Sidebar/SidebarSearch.js +2 -2
  153. package/dist/components/core/Sidebar/SidebarToggle.js +1 -1
  154. package/dist/components/core/Sidebar/SidebarUserProfile.js +1 -1
  155. package/dist/components/core/Sortable/Sortable.theme.js +1 -1
  156. package/dist/components/core/Tabs/Tabs.theme.js +1 -1
  157. package/dist/components/core/Tag/Tag.theme.js +1 -1
  158. package/dist/components/core/Toast/ToastProvider.js +1 -1
  159. package/dist/components/core/Tree/Tree.theme.js +1 -1
  160. package/dist/components/core/index.d.ts +0 -2
  161. package/dist/components/core/index.js +0 -4
  162. package/dist/components/core/shared/ChartTooltip/ChartTooltip.animations.d.ts +4 -0
  163. package/dist/components/core/shared/ChartTooltip/ChartTooltip.animations.js +20 -0
  164. package/dist/components/{charts → core}/shared/ChartTooltip/ChartTooltip.js +1 -1
  165. package/dist/components/core/shared/Ripple.d.ts +16 -0
  166. package/dist/components/core/shared/Ripple.js +141 -0
  167. package/dist/components/data-display/GanttChart/GanttChart.theme.js +6 -6
  168. package/dist/components/data-display/GanttChart/GanttTaskBar.js +1 -1
  169. package/dist/components/data-display/GanttChart/GanttTimelineHeader.js +1 -1
  170. package/dist/components/data-display/GanttChart/GanttToolbar.js +0 -1
  171. package/dist/components/data-display/KPI/KPI.js +11 -20
  172. package/dist/components/data-display/KPI/KPI.theme.js +8 -4
  173. package/dist/components/data-display/Metric/Metric.theme.js +4 -4
  174. package/dist/components/data-display/Table/Table.theme.js +2 -2
  175. package/dist/components/data-display/Table/TableColumnManager.js +1 -2
  176. package/dist/components/data-display/Table/TableContext.js +1 -0
  177. package/dist/components/data-display/Table/TableFilter.js +9 -2
  178. package/dist/components/data-display/Table/TableSelectionHeader.js +1 -1
  179. package/dist/components/data-display/Timeline/Timeline.theme.js +1 -1
  180. package/dist/components/effects/CustomCursor/CustomCursor.d.ts +1 -1
  181. package/dist/components/effects/CustomCursor/CustomCursor.js +1 -1
  182. package/dist/components/effects/CustomCursor/CustomCursor.theme.js +4 -4
  183. package/dist/components/effects/Neumorphic/InsetCircleButton.js +1 -1
  184. package/dist/components/effects/Overlay/Overlay.js +7 -3
  185. package/dist/components/effects/index.d.ts +0 -32
  186. package/dist/components/effects/index.js +0 -16
  187. package/dist/components/effects/shared/ShaderCanvas/ShaderCanvas.d.ts +0 -2
  188. package/dist/components/effects/shared/ShaderCanvas/ShaderCanvas.js +1 -93
  189. package/dist/components/effects/shared/ShaderCanvas/ShaderCanvas.types.d.ts +0 -10
  190. package/dist/components/effects/shared/ShaderCanvas/index.d.ts +1 -1
  191. package/dist/components/effects/shared/index.d.ts +1 -3
  192. package/dist/components/effects/shared/shaderNoise.glsl.d.ts +1 -1
  193. package/dist/components/effects/shared/shaderNoise.glsl.js +2 -11
  194. package/dist/components/forms/Checkbox/Checkbox.theme.js +1 -1
  195. package/dist/components/forms/ColorPicker/ColorPickerHeader.js +1 -1
  196. package/dist/components/forms/ColorPicker/ColorPickerImage.js +1 -1
  197. package/dist/components/forms/Combobox/Combobox.js +2 -0
  198. package/dist/components/forms/DateRangePicker/DateRangePicker.theme.js +1 -1
  199. package/dist/components/forms/DateRangePicker/DateRangePickerContext.js +1 -0
  200. package/dist/components/forms/FileUpload/FileUpload.theme.js +2 -2
  201. package/dist/components/forms/FileUpload/FileUploadProgress.theme.js +1 -1
  202. package/dist/components/forms/InputAddress/InputAddress.types.d.ts +2 -2
  203. package/dist/components/forms/Radio/Radio.theme.js +1 -1
  204. package/dist/components/forms/RichTextEditor/RichTextEditor.d.ts +12 -16
  205. package/dist/components/forms/RichTextEditor/RichTextEditor.js +165 -1680
  206. package/dist/components/forms/RichTextEditor/RichTextEditor.theme.d.ts +12 -56
  207. package/dist/components/forms/RichTextEditor/RichTextEditor.theme.js +60 -118
  208. package/dist/components/forms/RichTextEditor/RichTextEditor.types.d.ts +62 -126
  209. package/dist/components/forms/RichTextEditor/RichTextLinkField.d.ts +18 -0
  210. package/dist/components/forms/RichTextEditor/RichTextLinkField.js +46 -0
  211. package/dist/components/forms/RichTextEditor/RichTextToolbar.d.ts +15 -0
  212. package/dist/components/forms/RichTextEditor/RichTextToolbar.js +93 -0
  213. package/dist/components/forms/RichTextEditor/editorCommands.d.ts +50 -0
  214. package/dist/components/forms/RichTextEditor/editorCommands.js +58 -0
  215. package/dist/components/forms/RichTextEditor/editorState.d.ts +19 -0
  216. package/dist/components/forms/RichTextEditor/editorState.js +103 -0
  217. package/dist/components/forms/RichTextEditor/index.d.ts +5 -3
  218. package/dist/components/forms/RichTextEditor/sanitizeHtml.d.ts +38 -0
  219. package/dist/components/forms/RichTextEditor/sanitizeHtml.js +179 -0
  220. package/dist/components/forms/RichTextEditor/sanitizeHtml.test.d.ts +1 -0
  221. package/dist/components/forms/Select/Select.js +4 -4
  222. package/dist/components/forms/Select/Select.types.d.ts +70 -7
  223. package/dist/components/forms/Select/useSelectState.d.ts +9 -3
  224. package/dist/components/forms/Select/useSelectState.js +4 -1
  225. package/dist/components/forms/SelectableCard/SelectableCard.js +2 -1
  226. package/dist/components/forms/SelectableCard/SelectableCard.theme.js +1 -1
  227. package/dist/components/forms/Switch/Switch.theme.js +2 -2
  228. package/dist/components/forms/TimePicker/TimePicker.theme.js +1 -1
  229. package/dist/components/forms/TimePicker/TimePickerTrigger.js +1 -1
  230. package/dist/components/forms/forms.theme.js +19 -5
  231. package/dist/components/forms/index.js +1 -0
  232. package/dist/components/generative/FormShell.d.ts +22 -0
  233. package/dist/components/generative/FormShell.js +102 -0
  234. package/dist/components/generative/GenerativeView.d.ts +52 -1
  235. package/dist/components/generative/GenerativeView.js +203 -11
  236. package/dist/components/generative/actions.d.ts +5 -0
  237. package/dist/components/generative/ai-sdk/index.d.ts +1 -0
  238. package/dist/components/generative/ai-sdk/index.js +1 -0
  239. package/dist/components/generative/ai-sdk/useGenerativeChat.d.ts +52 -0
  240. package/dist/components/generative/ai-sdk/useGenerativeChat.js +73 -0
  241. package/dist/components/generative/ai-sdk/useGenerativeChat.test.d.ts +1 -0
  242. package/dist/components/generative/fieldBinding.d.ts +31 -0
  243. package/dist/components/generative/fieldBinding.js +33 -0
  244. package/dist/components/generative/fieldBinding.test.d.ts +1 -0
  245. package/dist/components/generative/formScope.d.ts +71 -0
  246. package/dist/components/generative/formScope.js +135 -0
  247. package/dist/components/generative/index.d.ts +4 -0
  248. package/dist/components/generative/index.js +4 -0
  249. package/dist/components/generative/registry.d.ts +2 -0
  250. package/dist/components/generative/registry.js +10 -10
  251. package/dist/components/generative/schema.generated.js +178 -292
  252. package/dist/components/generative/toToolResult.d.ts +21 -0
  253. package/dist/components/generative/toToolResult.js +15 -0
  254. package/dist/components/generative/toToolResult.test.d.ts +1 -0
  255. package/dist/components/generative/validate.d.ts +10 -1
  256. package/dist/components/generative/validate.js +126 -11
  257. package/dist/components/layout/Grid/Grid.js +1 -0
  258. package/dist/components/layout/Section/Section.theme.js +1 -1
  259. package/dist/components/layout/Stack/Stack.js +1 -0
  260. package/dist/generative.schema.json +178 -292
  261. package/dist/index.js +1 -4
  262. package/dist/registry.json +2599 -2375
  263. package/dist/shadcn-compat.css +5 -5
  264. package/dist/styles/theme.test.d.ts +1 -0
  265. package/dist/styles.css +1 -1
  266. package/dist/test/render.d.ts +17 -0
  267. package/dist/themes/precision.css +232 -0
  268. package/dist/tools.json +179 -294
  269. package/dist/utils/index.d.ts +0 -1
  270. package/package.json +31 -1
  271. package/src/global.scss +21 -28
  272. package/src/styles/theme.css +124 -41
  273. package/src/styles/theme.test.ts +119 -0
  274. package/tailwind.preset.cjs +30 -20
  275. package/dist/components/charts/FunnelChart/FunnelChart.animations.d.ts +0 -35
  276. package/dist/components/charts/FunnelChart/FunnelChart.animations.js +0 -59
  277. package/dist/components/charts/FunnelChart/FunnelChart.d.ts +0 -8
  278. package/dist/components/charts/FunnelChart/FunnelChart.js +0 -410
  279. package/dist/components/charts/FunnelChart/FunnelChart.theme.d.ts +0 -2
  280. package/dist/components/charts/FunnelChart/FunnelChart.theme.js +0 -12
  281. package/dist/components/charts/FunnelChart/FunnelChart.types.d.ts +0 -105
  282. package/dist/components/charts/FunnelChart/index.d.ts +0 -4
  283. package/dist/components/charts/ScatterPlot/ScatterPlot.d.ts +0 -9
  284. package/dist/components/charts/ScatterPlot/ScatterPlot.js +0 -208
  285. package/dist/components/charts/ScatterPlot/ScatterPlot.theme.d.ts +0 -18
  286. package/dist/components/charts/ScatterPlot/ScatterPlot.theme.js +0 -42
  287. package/dist/components/charts/ScatterPlot/ScatterPlot.types.d.ts +0 -60
  288. package/dist/components/charts/ScatterPlot/ScatterPlot.types.js +0 -19
  289. package/dist/components/charts/ScatterPlot/index.d.ts +0 -3
  290. package/dist/components/core/Button/Button.ripple.d.ts +0 -71
  291. package/dist/components/core/Button/Button.ripple.js +0 -236
  292. package/dist/components/core/Calendar/CalendarEvent/CalendarEvent.d.ts +0 -4
  293. package/dist/components/core/Calendar/CalendarEvent/CalendarEvent.theme.d.ts +0 -12
  294. package/dist/components/core/Calendar/CalendarEvent/CalendarEvent.types.d.ts +0 -23
  295. package/dist/components/core/Calendar/CalendarEvent/index.d.ts +0 -2
  296. package/dist/components/core/CardStack/CardStack.animations.d.ts +0 -47
  297. package/dist/components/core/CardStack/CardStack.d.ts +0 -3
  298. package/dist/components/core/CardStack/CardStack.js +0 -187
  299. package/dist/components/core/CardStack/CardStack.theme.d.ts +0 -6
  300. package/dist/components/core/CardStack/CardStack.theme.js +0 -33
  301. package/dist/components/core/CardStack/CardStack.types.d.ts +0 -139
  302. package/dist/components/core/CardStack/index.d.ts +0 -7
  303. package/dist/components/core/Carousel/Carousel.d.ts +0 -3
  304. package/dist/components/core/Carousel/Carousel.js +0 -83
  305. package/dist/components/core/Carousel/Carousel.theme.d.ts +0 -10
  306. package/dist/components/core/Carousel/Carousel.theme.js +0 -20
  307. package/dist/components/core/Carousel/Carousel.types.d.ts +0 -113
  308. package/dist/components/core/Carousel/CarouselBody.d.ts +0 -4
  309. package/dist/components/core/Carousel/CarouselBody.js +0 -59
  310. package/dist/components/core/Carousel/CarouselContext.d.ts +0 -3
  311. package/dist/components/core/Carousel/CarouselContext.js +0 -13
  312. package/dist/components/core/Carousel/CarouselItem.d.ts +0 -4
  313. package/dist/components/core/Carousel/CarouselItem.js +0 -11
  314. package/dist/components/core/Carousel/CarouselNext.d.ts +0 -4
  315. package/dist/components/core/Carousel/CarouselNext.js +0 -16
  316. package/dist/components/core/Carousel/CarouselPrevious.d.ts +0 -4
  317. package/dist/components/core/Carousel/CarouselPrevious.js +0 -16
  318. package/dist/components/core/Carousel/index.d.ts +0 -3
  319. package/dist/components/effects/ColorPanels/ColorPanels.d.ts +0 -8
  320. package/dist/components/effects/ColorPanels/ColorPanels.js +0 -66
  321. package/dist/components/effects/ColorPanels/ColorPanels.shaders.d.ts +0 -12
  322. package/dist/components/effects/ColorPanels/ColorPanels.shaders.js +0 -218
  323. package/dist/components/effects/ColorPanels/ColorPanels.types.d.ts +0 -29
  324. package/dist/components/effects/ColorPanels/ColorPanels.types.js +0 -3
  325. package/dist/components/effects/ColorPanels/index.d.ts +0 -2
  326. package/dist/components/effects/FlutedGlass/FlutedGlass.d.ts +0 -9
  327. package/dist/components/effects/FlutedGlass/FlutedGlass.js +0 -80
  328. package/dist/components/effects/FlutedGlass/FlutedGlass.shaders.d.ts +0 -12
  329. package/dist/components/effects/FlutedGlass/FlutedGlass.shaders.js +0 -335
  330. package/dist/components/effects/FlutedGlass/FlutedGlass.types.d.ts +0 -61
  331. package/dist/components/effects/FlutedGlass/FlutedGlass.types.js +0 -16
  332. package/dist/components/effects/FlutedGlass/index.d.ts +0 -3
  333. package/dist/components/effects/GlassEffect/GlassEffect.d.ts +0 -15
  334. package/dist/components/effects/GlassEffect/GlassEffect.js +0 -38
  335. package/dist/components/effects/GlassEffect/GlassEffect.types.d.ts +0 -19
  336. package/dist/components/effects/GlassEffect/index.d.ts +0 -2
  337. package/dist/components/effects/GlassSurface/GlassSurface.d.ts +0 -8
  338. package/dist/components/effects/GlassSurface/GlassSurface.js +0 -250
  339. package/dist/components/effects/GlassSurface/GlassSurface.types.d.ts +0 -66
  340. package/dist/components/effects/GlassSurface/index.d.ts +0 -2
  341. package/dist/components/effects/GodRays/GodRays.d.ts +0 -8
  342. package/dist/components/effects/GodRays/GodRays.js +0 -68
  343. package/dist/components/effects/GodRays/GodRays.shaders.d.ts +0 -10
  344. package/dist/components/effects/GodRays/GodRays.shaders.js +0 -128
  345. package/dist/components/effects/GodRays/GodRays.types.d.ts +0 -25
  346. package/dist/components/effects/GodRays/GodRays.types.js +0 -3
  347. package/dist/components/effects/GodRays/index.d.ts +0 -2
  348. package/dist/components/effects/GridPattern/GridPattern.d.ts +0 -18
  349. package/dist/components/effects/GridPattern/GridPattern.js +0 -65
  350. package/dist/components/effects/GridPattern/GridPattern.types.d.ts +0 -47
  351. package/dist/components/effects/GridPattern/index.d.ts +0 -2
  352. package/dist/components/effects/HalftoneCmyk/HalftoneCmyk.d.ts +0 -10
  353. package/dist/components/effects/HalftoneCmyk/HalftoneCmyk.js +0 -78
  354. package/dist/components/effects/HalftoneCmyk/HalftoneCmyk.shaders.d.ts +0 -22
  355. package/dist/components/effects/HalftoneCmyk/HalftoneCmyk.shaders.js +0 -239
  356. package/dist/components/effects/HalftoneCmyk/HalftoneCmyk.types.d.ts +0 -52
  357. package/dist/components/effects/HalftoneCmyk/index.d.ts +0 -2
  358. package/dist/components/effects/HalftoneDots/HalftoneDots.d.ts +0 -9
  359. package/dist/components/effects/HalftoneDots/HalftoneDots.js +0 -68
  360. package/dist/components/effects/HalftoneDots/HalftoneDots.shaders.d.ts +0 -13
  361. package/dist/components/effects/HalftoneDots/HalftoneDots.shaders.js +0 -296
  362. package/dist/components/effects/HalftoneDots/HalftoneDots.types.d.ts +0 -43
  363. package/dist/components/effects/HalftoneDots/HalftoneDots.types.js +0 -12
  364. package/dist/components/effects/HalftoneDots/index.d.ts +0 -3
  365. package/dist/components/effects/ImageDithering/ImageDithering.d.ts +0 -9
  366. package/dist/components/effects/ImageDithering/ImageDithering.js +0 -68
  367. package/dist/components/effects/ImageDithering/ImageDithering.shaders.d.ts +0 -12
  368. package/dist/components/effects/ImageDithering/ImageDithering.shaders.js +0 -117
  369. package/dist/components/effects/ImageDithering/ImageDithering.types.d.ts +0 -30
  370. package/dist/components/effects/ImageDithering/ImageDithering.types.js +0 -8
  371. package/dist/components/effects/ImageDithering/index.d.ts +0 -3
  372. package/dist/components/effects/MagneticElement/MagneticElement.d.ts +0 -30
  373. package/dist/components/effects/MagneticElement/MagneticElement.js +0 -111
  374. package/dist/components/effects/MagneticElement/MagneticElement.types.d.ts +0 -44
  375. package/dist/components/effects/MagneticElement/index.d.ts +0 -2
  376. package/dist/components/effects/Metaballs/Metaballs.d.ts +0 -8
  377. package/dist/components/effects/Metaballs/Metaballs.js +0 -59
  378. package/dist/components/effects/Metaballs/Metaballs.shaders.d.ts +0 -10
  379. package/dist/components/effects/Metaballs/Metaballs.shaders.js +0 -102
  380. package/dist/components/effects/Metaballs/Metaballs.types.d.ts +0 -16
  381. package/dist/components/effects/Metaballs/Metaballs.types.js +0 -3
  382. package/dist/components/effects/Metaballs/index.d.ts +0 -2
  383. package/dist/components/effects/PaperTexture/PaperTexture.d.ts +0 -9
  384. package/dist/components/effects/PaperTexture/PaperTexture.js +0 -61
  385. package/dist/components/effects/PaperTexture/PaperTexture.shaders.d.ts +0 -22
  386. package/dist/components/effects/PaperTexture/PaperTexture.shaders.js +0 -145
  387. package/dist/components/effects/PaperTexture/PaperTexture.types.d.ts +0 -19
  388. package/dist/components/effects/PaperTexture/index.d.ts +0 -2
  389. package/dist/components/effects/PulsingBorder/PulsingBorder.d.ts +0 -27
  390. package/dist/components/effects/PulsingBorder/PulsingBorder.js +0 -174
  391. package/dist/components/effects/PulsingBorder/PulsingBorder.shaders.d.ts +0 -14
  392. package/dist/components/effects/PulsingBorder/PulsingBorder.shaders.js +0 -258
  393. package/dist/components/effects/PulsingBorder/PulsingBorder.types.d.ts +0 -75
  394. package/dist/components/effects/PulsingBorder/PulsingBorder.types.js +0 -3
  395. package/dist/components/effects/PulsingBorder/index.d.ts +0 -2
  396. package/dist/components/effects/SmokeRing/SmokeRing.d.ts +0 -8
  397. package/dist/components/effects/SmokeRing/SmokeRing.js +0 -62
  398. package/dist/components/effects/SmokeRing/SmokeRing.shaders.d.ts +0 -14
  399. package/dist/components/effects/SmokeRing/SmokeRing.shaders.js +0 -130
  400. package/dist/components/effects/SmokeRing/SmokeRing.types.d.ts +0 -22
  401. package/dist/components/effects/SmokeRing/SmokeRing.types.js +0 -3
  402. package/dist/components/effects/SmokeRing/index.d.ts +0 -2
  403. package/dist/components/effects/StaticGradientMesh/StaticGradientMesh.d.ts +0 -9
  404. package/dist/components/effects/StaticGradientMesh/StaticGradientMesh.js +0 -59
  405. package/dist/components/effects/StaticGradientMesh/StaticGradientMesh.shaders.d.ts +0 -14
  406. package/dist/components/effects/StaticGradientMesh/StaticGradientMesh.shaders.js +0 -129
  407. package/dist/components/effects/StaticGradientMesh/StaticGradientMesh.types.d.ts +0 -23
  408. package/dist/components/effects/StaticGradientMesh/StaticGradientMesh.types.js +0 -3
  409. package/dist/components/effects/StaticGradientMesh/index.d.ts +0 -2
  410. package/dist/components/effects/Water/Water.d.ts +0 -9
  411. package/dist/components/effects/Water/Water.js +0 -65
  412. package/dist/components/effects/Water/Water.shaders.d.ts +0 -11
  413. package/dist/components/effects/Water/Water.shaders.js +0 -123
  414. package/dist/components/effects/Water/Water.types.d.ts +0 -25
  415. package/dist/components/effects/Water/index.d.ts +0 -2
  416. package/dist/components/effects/shared/bayerMatrices.glsl.d.ts +0 -10
  417. package/dist/components/effects/shared/bayerMatrices.glsl.js +0 -44
  418. package/dist/components/effects/shared/imageUV.glsl.d.ts +0 -12
  419. package/dist/components/effects/shared/imageUV.glsl.js +0 -26
  420. package/dist/components/forms/RichTextEditor/RichTextEditor.animations.d.ts +0 -7
  421. package/dist/components/forms/RichTextEditor/RichTextEditor.animations.js +0 -32
  422. package/dist/utils/calendarUtils.d.ts +0 -60
  423. /package/dist/components/{charts → core}/shared/ChartTooltip/ChartTooltip.d.ts +0 -0
  424. /package/dist/components/{charts → core}/shared/ChartTooltip/ChartTooltip.theme.d.ts +0 -0
  425. /package/dist/components/{charts → core}/shared/ChartTooltip/ChartTooltip.theme.js +0 -0
  426. /package/dist/components/{charts → core}/shared/ChartTooltip/ChartTooltip.types.d.ts +0 -0
  427. /package/dist/components/{charts → core}/shared/ChartTooltip/ChartTooltipContent.d.ts +0 -0
  428. /package/dist/components/{charts → core}/shared/ChartTooltip/index.d.ts +0 -0
@@ -7,10 +7,10 @@ import { CaretRight } from '@phosphor-icons/react';
7
7
  * Simple layout styles are inlined in the component
8
8
  */
9
9
  const breadcrumbsTheme = {
10
- link: "text-[var(--color-text-muted)] hover:text-[var(--color-text-primary)] transition-colors duration-150 font-medium",
10
+ link: "text-[var(--color-text-muted)] hover:text-[var(--color-text-primary)] transition-colors duration-[var(--motion-duration-fast)] font-medium",
11
11
  current: "text-[var(--color-text-primary)] font-medium",
12
12
  separator: "text-[var(--color-text-muted)] select-none",
13
- ellipsis: "text-sm text-[var(--color-text-muted)] hover:text-[var(--color-text-primary)] transition-colors duration-150 cursor-pointer p-1 rounded hover:bg-[var(--color-surface-hover)]",
13
+ ellipsis: "text-sm text-[var(--color-text-muted)] hover:text-[var(--color-text-primary)] transition-colors duration-[var(--motion-duration-fast)] cursor-pointer p-1 rounded hover:bg-[var(--color-surface-hover)]",
14
14
  };
15
15
  /**
16
16
  * Variant styles for different breadcrumb appearances
@@ -18,10 +18,10 @@ const breadcrumbsTheme = {
18
18
  const breadcrumbsVariants = {
19
19
  default: {},
20
20
  muted: {
21
- link: "text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)] transition-colors duration-150 font-normal",
21
+ link: "text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)] transition-colors duration-[var(--motion-duration-fast)] font-normal",
22
22
  current: "text-[var(--color-text-secondary)] font-normal",
23
23
  separator: "text-[var(--color-border)]",
24
- ellipsis: "text-sm text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)] transition-colors duration-150 cursor-pointer p-1 rounded hover:bg-[var(--color-background-secondary)]",
24
+ ellipsis: "text-sm text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)] transition-colors duration-[var(--motion-duration-fast)] cursor-pointer p-1 rounded hover:bg-[var(--color-surface)]",
25
25
  },
26
26
  };
27
27
  /**
@@ -1,25 +1,19 @@
1
1
  "use client";
2
2
  import { jsxs, jsx } from 'react/jsx-runtime';
3
- import React__default, { useCallback, useRef } from 'react';
3
+ import React__default, { useCallback } from 'react';
4
4
  import { useReducedMotion, motion } from 'motion/react';
5
5
  import { buttonTheme } from './Button.theme.js';
6
6
  import { cn } from '../../../utils/cn.js';
7
7
  import { Spinner } from '../Spinner/Spinner.js';
8
- import { useRipple, getRippleAnimation, getRippleColorClass } from './Button.ripple.js';
8
+ import { Ripple } from '../shared/Ripple.js';
9
9
  import { createPressVariants } from '../shared/interaction.animations.js';
10
10
 
11
11
  // Shared press physics (module-level constant)
12
12
  const BUTTON_PRESS_VARIANTS = createPressVariants(0.97);
13
- const Button = React__default.forwardRef(({ children, iconStart, iconEnd, className = "", iconOnly = false, state = "default", size = "md", color, variant, block = false, onClick, enableRipple = true, rippleEffect = "default", rippleClassName, rippleScale = 10, showReflection = true, darkMode = false, disabled: disabledProp, "aria-label": ariaLabelProp, onAnimationStart: _onAnimationStart, onAnimationEnd: _onAnimationEnd, onDrag: _onDrag, onDragStart: _onDragStart, onDragEnd: _onDragEnd, ...restProps }, ref) => {
13
+ const Button = React__default.forwardRef(({ children, iconStart, iconEnd, className = "", iconOnly = false, state = "default", size = "md", color, variant, block = false, onClick, enableRipple = true, showReflection = true, darkMode = false, disabled: disabledProp, "aria-label": ariaLabelProp, onAnimationStart: _onAnimationStart, onAnimationEnd: _onAnimationEnd, onDrag: _onDrag, onDragStart: _onDragStart, onDragEnd: _onDragEnd, ...restProps }, ref) => {
14
14
  var _a, _b, _c, _d, _e, _f, _g, _h;
15
15
  const shouldReduceMotion = useReducedMotion();
16
16
  const shouldDisableAnimations = !!shouldReduceMotion;
17
- // Initialize ripple hook
18
- const { ripples, createRipple, buttonRef, effect } = useRipple({
19
- scale: rippleScale,
20
- duration: 600,
21
- effect: rippleEffect,
22
- });
23
17
  // Resolve color and variant with defaults
24
18
  const resolvedColor = color || "primary";
25
19
  const resolvedVariant = variant || "filled";
@@ -34,13 +28,10 @@ const Button = React__default.forwardRef(({ children, iconStart, iconEnd, classN
34
28
  }
35
29
  }
36
30
  // Safe onClick handler - respect both state="disabled" and disabled={true}
31
+ // (the ripple wires itself to the DOM node — see <Ripple /> below)
37
32
  const handleClick = useCallback((event) => {
38
33
  if (isDisabled)
39
34
  return;
40
- // Create ripple effect if enabled
41
- if (enableRipple && !shouldReduceMotion) {
42
- createRipple(event);
43
- }
44
35
  try {
45
36
  onClick === null || onClick === void 0 ? void 0 : onClick(event);
46
37
  }
@@ -50,7 +41,7 @@ const Button = React__default.forwardRef(({ children, iconStart, iconEnd, classN
50
41
  console.error("Error in button click handler:", error);
51
42
  }
52
43
  }
53
- }, [onClick, isDisabled, enableRipple, shouldReduceMotion, createRipple]);
44
+ }, [onClick, isDisabled]);
54
45
  // Compute theme classes (direct computation - faster than useMemo)
55
46
  const sizeClasses = ((_b = (_a = buttonTheme.sizes) === null || _a === void 0 ? void 0 : _a[size]) === null || _b === void 0 ? void 0 : _b[iconOnly ? "iconOnly" : "default"]) || "";
56
47
  const colorClasses = ((_c = buttonTheme.variantColors[resolvedVariant]) === null || _c === void 0 ? void 0 : _c[resolvedColor]) || "";
@@ -84,36 +75,9 @@ const Button = React__default.forwardRef(({ children, iconStart, iconEnd, classN
84
75
  // single time below, instead of spreading `restProps` and then
85
76
  // unconditionally overwriting it with `state`.
86
77
  const consumerDataState = restProps["data-state"];
87
- // Track the latest forwarded ref to avoid mergedRef recreation on inline callback refs
88
- const forwardedRef = useRef(ref);
89
- forwardedRef.current = ref;
90
- // Merge refs - stable callback that won't cause DOM detach/attach cycles
91
- const mergedRef = useCallback((node) => {
92
- // Set ripple's buttonRef
93
- if (buttonRef) {
94
- buttonRef.current = node;
95
- }
96
- // Set forwarded ref
97
- const fRef = forwardedRef.current;
98
- if (typeof fRef === "function") {
99
- fRef(node);
100
- }
101
- else if (fRef) {
102
- fRef.current =
103
- node;
104
- }
105
- }, [buttonRef]);
106
- return (jsxs(motion.button, { type: "button", ...restProps, ...animationProps, ref: mergedRef, className: cn(buttonTheme.baseStyle, colorClasses, variantClasses, sizeClasses, blockStyle, stateClasses, darkMode && "dark", className), disabled: isDisabled, "data-state": consumerDataState !== null && consumerDataState !== void 0 ? consumerDataState : state, "data-color": resolvedColor, "data-variant": resolvedVariant, "data-size": size, "data-icon-only": iconOnly ? "true" : "false", "data-block": block ? "true" : "false", "aria-disabled": isDisabled || undefined, "aria-busy": isLoading || undefined, "aria-label": ariaLabel, onClick: handleClick, children: [showReflection &&
78
+ return (jsxs(motion.button, { type: "button", ...restProps, ...animationProps, ref: ref, className: cn(buttonTheme.baseStyle, colorClasses, variantClasses, sizeClasses, blockStyle, stateClasses, darkMode && "dark", className), disabled: isDisabled, "data-state": consumerDataState !== null && consumerDataState !== void 0 ? consumerDataState : state, "data-color": resolvedColor, "data-variant": resolvedVariant, "data-size": size, "data-icon-only": iconOnly ? "true" : "false", "data-block": block ? "true" : "false", "aria-disabled": isDisabled || undefined, "aria-busy": isLoading || undefined, "aria-label": ariaLabel, onClick: handleClick, children: [showReflection &&
107
79
  resolvedVariant !== "ghost" &&
108
- resolvedVariant !== "outline" && (jsx("div", { className: "pointer-events-none absolute inset-px border-t-[0.5px] border-white/50 rounded-[inherit] blur-[0.75px]" })), isLoading && (jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: jsx(Spinner, { size: "sm", color: color, className: spinnerClassName }) })), jsxs("span", { className: cn("inline-flex items-center gap-2 whitespace-nowrap", isLoading && "opacity-0"), children: [iconStart && (jsx("span", { className: cn("inline-flex shrink-0 items-center justify-center", (_g = buttonTheme.iconSizes) === null || _g === void 0 ? void 0 : _g[size]), "aria-hidden": "true", children: iconStart })), children, iconEnd && (jsx("span", { className: cn("inline-flex shrink-0 items-center justify-center", (_h = buttonTheme.iconSizes) === null || _h === void 0 ? void 0 : _h[size]), "aria-hidden": "true", children: iconEnd }))] }), enableRipple &&
109
- ripples.map((ripple) => {
110
- const animation = getRippleAnimation(effect, ripple, rippleScale);
111
- return (jsx(motion.span, { initial: animation.initial, animate: animation.animate, transition: animation.transition, className: cn("absolute rounded-full size-5 pointer-events-none ", animation.className, rippleClassName ||
112
- getRippleColorClass(resolvedVariant, resolvedColor)), style: {
113
- top: ripple.y - 10,
114
- left: ripple.x - 10,
115
- } }, ripple.id));
116
- })] }));
80
+ resolvedVariant !== "outline" && (jsx("div", { className: "pointer-events-none absolute inset-px border-t-[0.5px] border-white/50 rounded-[inherit] blur-[0.75px]" })), isLoading && (jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: jsx(Spinner, { size: "sm", color: color, className: spinnerClassName }) })), jsxs("span", { className: cn("inline-flex items-center gap-2 whitespace-nowrap", isLoading && "opacity-0"), children: [iconStart && (jsx("span", { className: cn("inline-flex shrink-0 items-center justify-center", (_g = buttonTheme.iconSizes) === null || _g === void 0 ? void 0 : _g[size]), "aria-hidden": "true", children: iconStart })), children, iconEnd && (jsx("span", { className: cn("inline-flex shrink-0 items-center justify-center", (_h = buttonTheme.iconSizes) === null || _h === void 0 ? void 0 : _h[size]), "aria-hidden": "true", children: iconEnd }))] }), enableRipple && jsx(Ripple, {})] }));
117
81
  });
118
82
  // Set display name for dev tools and Storybook
119
83
  Button.displayName = "Button";
@@ -3,7 +3,7 @@
3
3
  */
4
4
  const buttonTheme = {
5
5
  // Base styles for the button element
6
- baseStyle: "relative inline-flex items-center justify-center gap-2 focus:outline-none rounded-[var(--button-radius)] overflow-hidden cursor-pointer transition-[color,background-color,border-color,box-shadow,filter,opacity] duration-150 ease-out min-w-fit flex-shrink-0 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 cursor-pointer backdrop-blur-sm",
6
+ baseStyle: "relative inline-flex items-center justify-center gap-2 focus:outline-none rounded-[var(--button-radius)] overflow-hidden cursor-pointer transition-[color,background-color,border-color,box-shadow,filter,opacity] duration-[var(--motion-duration-fast)] ease-out min-w-fit flex-shrink-0 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 cursor-pointer backdrop-blur-sm",
7
7
  // Visual style variants - STRUCTURE only (no colors)
8
8
  variantStyles: {
9
9
  filled: "border border-black/15 hover:brightness-[0.9] dark:hover:brightness-[1.15]",
@@ -35,7 +35,7 @@ const buttonTheme = {
35
35
  mono: "text-[var(--color-text-primary)] border-[var(--color-border-secondary)] " +
36
36
  "hover:bg-[var(--color-mono-100)] " +
37
37
  "focus-visible:outline-[var(--color-text-secondary)] " +
38
- "dark:hover:bg-[var(--color-background-secondary)]",
38
+ "dark:hover:bg-[var(--color-surface)]",
39
39
  primary: "text-[var(--color-text-primary)] border-[var(--color-primary-600)]/30 " +
40
40
  "hover:bg-[var(--color-primary-100)] " +
41
41
  "focus-visible:outline-[var(--color-primary-600)] " +
@@ -1,5 +1,4 @@
1
1
  import React from "react";
2
- import { RippleEffectType } from "./Button.ripple";
3
2
  /**
4
3
  * Button component props
5
4
  * @property {ButtonColor} color - The semantic color/intent of the button
@@ -8,10 +7,7 @@ import { RippleEffectType } from "./Button.ripple";
8
7
  * @property {ButtonState} state - The state of the button (default, loading, disabled)
9
8
  * @property {boolean} iconOnly - Whether the button should display as icon-only (square padding)
10
9
  * @property {boolean} block - Whether the button should be full width
11
- * @property {boolean} enableRipple - Whether to enable ripple effect on click
12
- * @property {RippleEffectType} rippleEffect - Type of ripple effect (default, aurora, particle, glass, neon, echo)
13
- * @property {string} rippleClassName - Custom class name for ripple styling
14
- * @property {number} rippleScale - Scale multiplier for ripple expansion (default: 10)
10
+ * @property {boolean} enableRipple - Whether to enable the press ripple
15
11
  */
16
12
  export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
17
13
  /** The semantic color/intent of the button */
@@ -47,14 +43,14 @@ export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElemen
47
43
  children?: React.ReactNode;
48
44
  /** Additional class names */
49
45
  className?: string;
50
- /** Whether to enable ripple effect on click */
46
+ /**
47
+ * Whether to show the press ripple.
48
+ *
49
+ * The ripple is pointer-only — keyboard activation gets the focus ring
50
+ * instead — and is suppressed automatically under `prefers-reduced-motion`.
51
+ * @default true
52
+ */
51
53
  enableRipple?: boolean;
52
- /** Type of ripple effect: 'default' | 'aurora' | 'particle' | 'glass' | 'neon' | 'echo' */
53
- rippleEffect?: RippleEffectType;
54
- /** Custom class name for ripple styling */
55
- rippleClassName?: string;
56
- /** Scale multiplier for ripple expansion (default: 10) */
57
- rippleScale?: number;
58
54
  /** Whether to show the glass reflection effect (default: true) */
59
55
  showReflection?: boolean;
60
56
  /**
@@ -1,4 +1,2 @@
1
1
  export { Button } from './Button';
2
2
  export * from './Button.types';
3
- export { useRipple, getRippleColorClass, getRippleAnimation } from './Button.ripple';
4
- export type { RippleEffectType, RippleConfig, Ripple } from './Button.ripple';
@@ -15,7 +15,7 @@ const calendarTheme = {
15
15
  "data-[range-pos=end]:rounded-r-full " +
16
16
  "data-[range-pos=single]:rounded-full",
17
17
  dayButtonStyle: "relative z-10 flex items-center justify-center rounded-full border-0 bg-transparent font-medium cursor-pointer " +
18
- "transition-all duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-primary)] focus-visible:ring-offset-2 " +
18
+ "transition-all duration-[var(--motion-duration-base)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-primary)] focus-visible:ring-offset-2 " +
19
19
  // Base text color
20
20
  "text-[var(--color-text-primary)] " +
21
21
  // Hover state
@@ -1,9 +1,9 @@
1
1
  const calendarMiniTheme = {
2
- baseStyle: "flex items-center justify-center gap-1 transition-all duration-300 text-sm",
2
+ baseStyle: "flex items-center justify-center gap-1 transition-all duration-[var(--motion-duration-slow)] text-sm",
3
3
  monthRowStyle: "flex flex-1 gap-4 overflow-x-auto scrollbar-hide scroll-smooth snap-x snap-mandatory px-4 ml-3",
4
4
  monthItemStyle: "font-semibold text-[var(--color-text-secondary)] cursor-pointer transition-colors hover:text-[var(--color-text-primary)] flex-shrink-0 snap-center data-[state=active]:text-[var(--color-text-primary)] data-[state=active]:opacity-100",
5
5
  dateRowStyle: "relative overflow-hidden px-4 py-0.5",
6
- dateItemStyle: "px-0 py-1.5 min-w-[50px] flex flex-col items-center rounded-[var(--form-radius)] cursor-pointer transition-all text-[var(--color-text-primary)] hover:bg-[var(--color-surface-hover)] flex-shrink-0 snap-center ring-1 ring-transparent data-[state=selected]:bg-[var(--color-background-secondary)] data-[state=selected]:ring-[var(--color-border)] data-[state=selected]:hover:bg-[var(--color-background-secondary)] data-[state=selected]:z-2 data-[disabled]:opacity-40 data-[disabled]:cursor-not-allowed data-[disabled]:hover:bg-[var(--color-background-secondary)]",
6
+ dateItemStyle: "px-0 py-1.5 min-w-[50px] flex flex-col items-center rounded-[var(--form-radius)] cursor-pointer transition-all text-[var(--color-text-primary)] hover:bg-[var(--color-surface-hover)] flex-shrink-0 snap-center ring-1 ring-transparent data-[state=selected]:bg-[var(--color-surface)] data-[state=selected]:ring-[var(--color-border)] data-[state=selected]:hover:bg-[var(--color-surface)] data-[state=selected]:z-2 data-[disabled]:opacity-40 data-[disabled]:cursor-not-allowed data-[disabled]:hover:bg-[var(--color-surface)]",
7
7
  };
8
8
 
9
9
  export { calendarMiniTheme };
@@ -8,9 +8,10 @@ import { CardTitle } from './CardTitle.js';
8
8
  import { CardSubtitle } from './CardSubtitle.js';
9
9
  import { CardBody } from './CardBody.js';
10
10
  import { CardFooter } from './CardFooter.js';
11
+ import { CardContext } from './CardContext.js';
11
12
  import { useSurfaceElevation, SurfaceProvider, surfaceClasses } from '../../../theme/SurfaceContext.js';
12
13
 
13
- const CardRoot = React__default.forwardRef(({ children, className, theme: customTheme = {}, darkMode = false, title, subtitle, actions, footer, elevation, lift, ...props }, ref) => {
14
+ const CardRoot = React__default.forwardRef(({ children, className, theme: customTheme = {}, darkMode = false, title, subtitle, actions, footer, elevation, lift, inset = false, ...props }, ref) => {
14
15
  // Relative elevation: a Card lifts two rungs above its host substrate (base = 3, so a
15
16
  // standalone card on the floor reads rung 3). shadow:true (the engine default) supplies the
16
17
  // hairline ring + doubling shadow — the ONLY elevation cue in light mode, where rungs 3–8 are
@@ -20,11 +21,15 @@ const CardRoot = React__default.forwardRef(({ children, className, theme: custom
20
21
  ...cardTheme,
21
22
  ...customTheme,
22
23
  }), [customTheme]);
24
+ const cardContext = useMemo(() => ({ inset }), [inset]);
23
25
  const hasHeader = Boolean(title || subtitle || actions);
24
26
  // Slot-prop mode: any header/footer slot composes Header/Body/Footer for us.
25
27
  // Otherwise children render raw — the compound API path, unchanged.
26
28
  const managed = hasHeader || Boolean(footer);
27
- return (jsx("div", { ref: ref, className: cn(surfaceClasses(surfaceLevel), theme.baseStyle, darkMode && "dark", className), ...props, children: jsx(SurfaceProvider, { level: surfaceLevel, children: managed ? (jsxs(Fragment, { children: [hasHeader && (jsxs(CardHeader, { className: actions ? "flex-row items-start justify-between gap-4" : undefined, children: [(title || subtitle) && (jsxs("div", { className: "flex flex-col", children: [title && jsx(CardTitle, { children: title }), subtitle && jsx(CardSubtitle, { children: subtitle })] })), actions && (jsx("div", { className: "flex items-center gap-2 shrink-0", children: actions }))] })), children != null && jsx(CardBody, { children: children }), footer && jsx(CardFooter, { className: "justify-end gap-2", children: footer })] })) : (children) }) }));
29
+ return (jsx("div", { ref: ref, className: cn(surfaceClasses(surfaceLevel),
30
+ // Overrides only the rung bg from surfaceClasses (twMerge, last wins) — its
31
+ // shadow and --field-fill survive, and `className` still wins over both.
32
+ inset && theme.baseStyleInset, theme.baseStyle, darkMode && "dark", className), ...props, children: jsx(CardContext.Provider, { value: cardContext, children: jsx(SurfaceProvider, { level: surfaceLevel, children: managed ? (jsxs(Fragment, { children: [hasHeader && (jsxs(CardHeader, { className: actions ? "flex-row items-start justify-between gap-4" : undefined, children: [(title || subtitle) && (jsxs("div", { className: "flex flex-col", children: [title && jsx(CardTitle, { children: title }), subtitle && jsx(CardSubtitle, { children: subtitle })] })), actions && (jsx("div", { className: "flex items-center gap-2 shrink-0", children: actions }))] })), children != null && jsx(CardBody, { children: children }), footer && jsx(CardFooter, { className: "justify-end gap-2", children: footer })] })) : (children) }) }) }));
28
33
  });
29
34
  CardRoot.displayName = 'Card';
30
35
  // Create compound component with proper typing
@@ -5,7 +5,7 @@ const cardTheme = {
5
5
  headerStyle: "flex flex-col px-[var(--card-px)] py-[var(--card-py)] items-start",
6
6
  // text-[length:...] (not bare text-[var(...)]) is required — see TYPE ROLE
7
7
  // SYSTEM in theme.css for why a bare var() would resolve to color instead.
8
- titleStyle: "text-[length:var(--card-title-size)] font-semibold leading-none text-[var(--color-text-primary)]",
8
+ titleStyle: "text-[length:var(--card-title-size)]/[var(--card-title-line-height)] font-semibold text-[var(--color-text-primary)]",
9
9
  subtitleStyle: "text-sm text-[var(--color-text-secondary)] mt-2",
10
10
  // Default to full py (top included). [[data-card-region]~&]:pt-0 zeroes the seam
11
11
  // ONLY when an actual region (Header/Body) precedes this one — a general-sibling
@@ -15,6 +15,34 @@ const cardTheme = {
15
15
  // takes no layout space, so Body silently lost its top padding.
16
16
  bodyStyle: "px-[var(--card-px)] py-[var(--card-py)] [[data-card-region]~&]:pt-0",
17
17
  footerStyle: "flex items-center px-[var(--card-px)] py-[var(--card-py)] [[data-card-region]~&]:pt-0",
18
+ // ── inset mode ─────────────────────────────────────────────────────────────
19
+ // PROTOTYPE GEOMETRY: the 12px gap and the 16px panel radius are hardcoded on
20
+ // purpose so the look can be tuned by eye first. Tokenise both afterwards
21
+ // (--card-inset-gap + a --card-panel-radius on the sm cap tier, per §3's
22
+ // nested-well rule) — this is the only place the numbers appear.
23
+ //
24
+ // The frame sinks rather than the body rising: light-mode rungs 3-8 are all
25
+ // #ffffff, so lifting the body a rung would paint nothing. bg here overrides
26
+ // the rung bg from surfaceClasses via twMerge while its shadow + --field-fill
27
+ // survive; the panel then picks the rung bg back up.
28
+ baseStyleInset: "bg-[var(--color-surface-sunken)]",
29
+ // Header keeps its full top padding; only the seam down to the panel collapses
30
+ // to the gap. `pb-3` lands after `py-[…]` so twMerge resolves the bottom side.
31
+ headerStyleInset: "pb-3",
32
+ // Deliberately NOT carrying bodyStyle's `[[data-card-region]~&]:pt-0` — the
33
+ // panel is a closed box and keeps uniform padding on all four sides.
34
+ //
35
+ // ALIGNMENT CONTRACT: content inside the panel must stay flush with the header
36
+ // and footer text on the tray. The panel is offset by the gap, so its own
37
+ // padding is that gap subtracted from the card padding — 12 + (24-12) = 24,
38
+ // the same inset the header sits at. Derived from --card-px/--card-py rather
39
+ // than hardcoded so it holds when a theme redefines the card padding.
40
+ // The `_` are required: they become spaces, and calc() treats `-` as an operator
41
+ // ONLY when whitespace-separated. `calc(var(--card-px)-12px)` parses as the invalid
42
+ // `var(--card-px) -12px`, which Tailwind silently drops — no class is emitted at all.
43
+ // When these move to tokens, wrap in max(0px, …) so a theme that sets the card
44
+ // padding below the gap can't produce negative padding.
45
+ bodyStyleInset: "mx-3 mb-3 rounded-2xl px-[calc(var(--card-px)_-_12px)] py-[calc(var(--card-py)_-_12px)]",
18
46
  };
19
47
 
20
48
  export { cardTheme };
@@ -7,6 +7,12 @@ export interface CardTheme {
7
7
  subtitleStyle: string;
8
8
  bodyStyle: string;
9
9
  footerStyle: string;
10
+ /** Applied on top of `baseStyle` when `inset` — sinks the frame to a tray. */
11
+ baseStyleInset: string;
12
+ /** Applied on top of `headerStyle` when `inset` — collapses the seam to the panel. */
13
+ headerStyleInset: string;
14
+ /** Replaces `bodyStyle` when `inset` — the floating panel. */
15
+ bodyStyleInset: string;
10
16
  }
11
17
  export interface CardThemeOverrides {
12
18
  baseStyle?: string;
@@ -15,6 +21,9 @@ export interface CardThemeOverrides {
15
21
  subtitleStyle?: string;
16
22
  bodyStyle?: string;
17
23
  footerStyle?: string;
24
+ baseStyleInset?: string;
25
+ headerStyleInset?: string;
26
+ bodyStyleInset?: string;
18
27
  }
19
28
  export interface CardProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
20
29
  /**
@@ -53,6 +62,17 @@ export interface CardProps extends Omit<HTMLAttributes<HTMLDivElement>, "title">
53
62
  elevation?: SurfaceElevation;
54
63
  /** `false` opts out of the relative lift — paints at the card's base rung. */
55
64
  lift?: boolean;
65
+ /**
66
+ * Sink the card frame to a recessed tray and float the body as its own panel.
67
+ * Header and footer stay on the tray; body content remains flush with them.
68
+ *
69
+ * Works in both API modes — the root broadcasts it, so a compound
70
+ * `<Card.Body>` picks it up without being told twice. Has no effect on raw
71
+ * children (no slot-props and no `Card.Body`), since there is no body region
72
+ * to turn into a panel.
73
+ * @default false
74
+ */
75
+ inset?: boolean;
56
76
  /**
57
77
  * Custom class name for the card
58
78
  */
@@ -1,10 +1,18 @@
1
+ "use client";
1
2
  import { jsx } from 'react/jsx-runtime';
2
3
  import React__default from 'react';
3
4
  import { cn } from '../../../utils/cn.js';
4
5
  import { cardTheme } from './Card.theme.js';
6
+ import { useCardContext } from './CardContext.js';
7
+ import { useSurfaceLevel, surfaceClasses } from '../../../theme/SurfaceContext.js';
5
8
 
6
9
  const CardBody = React__default.forwardRef(({ children, className, ...props }, ref) => {
7
- return (jsx("div", { ref: ref, "data-card-region": "", className: cn(cardTheme.bodyStyle, className), ...props, children: children }));
10
+ const { inset } = useCardContext();
11
+ // The rung the root already computed and re-provided. In inset mode the frame gives
12
+ // that rung up to sink to a tray, so the panel is what paints it — bg, hairline ring
13
+ // and --field-fill all land here instead of on the frame.
14
+ const surfaceLevel = useSurfaceLevel();
15
+ return (jsx("div", { ref: ref, "data-card-region": "", className: cn(inset && surfaceClasses(surfaceLevel), inset ? cardTheme.bodyStyleInset : cardTheme.bodyStyle, className), ...props, children: children }));
8
16
  });
9
17
  CardBody.displayName = 'Card.Body';
10
18
 
@@ -0,0 +1,13 @@
1
+ export interface CardContextValue {
2
+ /** `true` when the root Card is in inset mode (sunken tray + floating body panel). */
3
+ inset: boolean;
4
+ }
5
+ /**
6
+ * Lives in its own module (not `Card.tsx`) so the sub-components can read it without
7
+ * importing the root — the zero-circular-dependency rule in CLAUDE.md §23.
8
+ *
9
+ * Defaults to `inset: false` so a bare `<Card.Body>` used outside a `<Card>` (which the
10
+ * existing API allows) keeps rendering exactly as it does today.
11
+ */
12
+ export declare const CardContext: import("react").Context<CardContextValue>;
13
+ export declare const useCardContext: () => CardContextValue;
@@ -0,0 +1,14 @@
1
+ "use client";
2
+ import { createContext, useContext } from 'react';
3
+
4
+ /**
5
+ * Lives in its own module (not `Card.tsx`) so the sub-components can read it without
6
+ * importing the root — the zero-circular-dependency rule in CLAUDE.md §23.
7
+ *
8
+ * Defaults to `inset: false` so a bare `<Card.Body>` used outside a `<Card>` (which the
9
+ * existing API allows) keeps rendering exactly as it does today.
10
+ */
11
+ const CardContext = createContext({ inset: false });
12
+ const useCardContext = () => useContext(CardContext);
13
+
14
+ export { CardContext, useCardContext };
@@ -1,10 +1,13 @@
1
+ "use client";
1
2
  import { jsx } from 'react/jsx-runtime';
2
3
  import React__default from 'react';
3
4
  import { cn } from '../../../utils/cn.js';
4
5
  import { cardTheme } from './Card.theme.js';
6
+ import { useCardContext } from './CardContext.js';
5
7
 
6
8
  const CardHeader = React__default.forwardRef(({ children, className, ...props }, ref) => {
7
- return (jsx("div", { ref: ref, "data-card-region": "", className: cn(cardTheme.headerStyle, className), ...props, children: children }));
9
+ const { inset } = useCardContext();
10
+ return (jsx("div", { ref: ref, "data-card-region": "", className: cn(cardTheme.headerStyle, inset && cardTheme.headerStyleInset, className), ...props, children: children }));
8
11
  });
9
12
  CardHeader.displayName = 'CardHeader';
10
13
 
@@ -3,8 +3,9 @@ import { dropdownTheme } from '../Dropdown/Dropdown.theme.js';
3
3
  const contextMenuTheme = {
4
4
  // Inherit all Dropdown styles for consistency
5
5
  ...dropdownTheme,
6
- // Content uses the same styling as Dropdown menu
7
- contentStyle: dropdownTheme.menuStyle.replace("flex", "flex-col p-1"),
6
+ // Content uses the same styling as Dropdown menu. The padding is the token, not a
7
+ // literal p-1 — it also feeds --dropdown-inner-radius (the first/last row's corner).
8
+ contentStyle: dropdownTheme.menuStyle.replace("flex", "flex-col p-[var(--dropdown-padding)]"),
8
9
  // Items use exact same styling as Dropdown items.
9
10
  itemStyle: dropdownTheme.itemBaseStyle,
10
11
  // Checked tick — sits in the leading icon slot (same gutter as startContent icons),
@@ -17,7 +18,7 @@ const contextMenuTheme = {
17
18
  // bg + shadow come from the relative-elevation engine (surfaceClasses) at
18
19
  // runtime so the submenu lifts above its parent menu; keep blur + border here.
19
20
  subContentStyle: "min-w-[180px] max-h-[400px] overflow-y-auto rounded-[var(--dropdown-radius)] border border-[var(--color-border)] ml-1 " +
20
- "backdrop-blur-md flex flex-col p-1 focus:outline-none",
21
+ "backdrop-blur-md flex flex-col p-[var(--dropdown-padding)] focus:outline-none",
21
22
  // Separator - horizontal divider (--color-border flips for dark on its own)
22
23
  separatorStyle: "h-px bg-[var(--color-border)] my-1 -mx-1",
23
24
  // Label - section header (matches Dropdown section title)
@@ -16,6 +16,14 @@ export interface SubMenuContextValue {
16
16
  isOpen: boolean;
17
17
  onOpenChange: (isOpen: boolean) => void;
18
18
  triggerRef: React.RefObject<HTMLDivElement | null>;
19
+ /**
20
+ * Cancel a pending close. The trigger and the submenu body are separate DOM
21
+ * subtrees (the body portals to `document.body`), so hovering either one has to
22
+ * call this to survive the hand-off across the gap between them.
23
+ */
24
+ cancelClose: () => void;
25
+ /** Start the short grace period before the submenu closes. */
26
+ scheduleClose: () => void;
19
27
  }
20
28
  export interface ContextMenuProps extends React.HTMLAttributes<HTMLDivElement> {
21
29
  children: ReactNode;
@@ -54,7 +62,6 @@ export interface ContextMenuItemProps extends Omit<React.HTMLAttributes<HTMLDivE
54
62
  }
55
63
  export interface ContextMenuSubProps {
56
64
  children: ReactNode;
57
- className?: string;
58
65
  }
59
66
  export interface ContextMenuSubTriggerProps extends React.HTMLAttributes<HTMLDivElement> {
60
67
  children: ReactNode;
@@ -1,6 +1,16 @@
1
1
  import React from "react";
2
2
  import { ContextMenuSubProps } from "./ContextMenu.types";
3
3
  /**
4
- * ContextMenuSub - Wrapper for nested submenu with hover logic
4
+ * ContextMenuSub - Wrapper for nested submenu with hover logic.
5
+ *
6
+ * Renders NO element of its own: the sub-trigger has to stay a direct sibling of the
7
+ * surrounding ContextMenu.Item rows, because MenuItem expresses its corner radius with
8
+ * `first:`/`last:` variants and those resolve against DOM siblings. Wrapping the trigger
9
+ * made it both the first AND the last child of that wrapper, so a mid-list sub-trigger
10
+ * rounded all four corners at --radius-base instead of the flat 4px its neighbours use.
11
+ *
12
+ * Hover coordination therefore lives here instead of on a wrapper's mouse handlers: the
13
+ * trigger and the (portalled) submenu body each cancel a pending close on enter and
14
+ * schedule one on leave, so the pointer can cross the gap between them.
5
15
  */
6
16
  export declare const ContextMenuSub: React.FC<ContextMenuSubProps>;
@@ -1,40 +1,53 @@
1
1
  "use client";
2
2
  import { jsx } from 'react/jsx-runtime';
3
- import { useState, useRef, useCallback, useMemo } from 'react';
3
+ import { useState, useRef, useCallback, useEffect, useMemo } from 'react';
4
4
  import { SubMenuContext } from './ContextMenuContext.js';
5
5
 
6
+ /** Grace period before a hovered-away submenu closes, in ms. */
7
+ const CLOSE_DELAY = 150;
6
8
  /**
7
- * ContextMenuSub - Wrapper for nested submenu with hover logic
9
+ * ContextMenuSub - Wrapper for nested submenu with hover logic.
10
+ *
11
+ * Renders NO element of its own: the sub-trigger has to stay a direct sibling of the
12
+ * surrounding ContextMenu.Item rows, because MenuItem expresses its corner radius with
13
+ * `first:`/`last:` variants and those resolve against DOM siblings. Wrapping the trigger
14
+ * made it both the first AND the last child of that wrapper, so a mid-list sub-trigger
15
+ * rounded all four corners at --radius-base instead of the flat 4px its neighbours use.
16
+ *
17
+ * Hover coordination therefore lives here instead of on a wrapper's mouse handlers: the
18
+ * trigger and the (portalled) submenu body each cancel a pending close on enter and
19
+ * schedule one on leave, so the pointer can cross the gap between them.
8
20
  */
9
- const ContextMenuSub = ({ children, className, }) => {
21
+ const ContextMenuSub = ({ children }) => {
10
22
  const [isOpen, setIsOpen] = useState(false);
11
23
  const triggerRef = useRef(null);
12
- const hoverTimeoutRef = useRef(null);
13
- const handleOpenChange = useCallback((value) => {
14
- setIsOpen(value);
15
- }, []);
16
- // Handle mouse enter - clear any close timeout
17
- const handleMouseEnter = useCallback(() => {
18
- if (hoverTimeoutRef.current) {
19
- clearTimeout(hoverTimeoutRef.current);
20
- hoverTimeoutRef.current = null;
24
+ const closeTimeoutRef = useRef(null);
25
+ const cancelClose = useCallback(() => {
26
+ if (closeTimeoutRef.current) {
27
+ clearTimeout(closeTimeoutRef.current);
28
+ closeTimeoutRef.current = null;
21
29
  }
22
30
  }, []);
23
- // Handle mouse leave - close submenu after delay
24
- const handleMouseLeave = useCallback(() => {
25
- if (hoverTimeoutRef.current) {
26
- clearTimeout(hoverTimeoutRef.current);
27
- }
28
- hoverTimeoutRef.current = setTimeout(() => {
31
+ const scheduleClose = useCallback(() => {
32
+ cancelClose();
33
+ closeTimeoutRef.current = setTimeout(() => {
34
+ closeTimeoutRef.current = null;
29
35
  setIsOpen(false);
30
- }, 150);
31
- }, []);
36
+ }, CLOSE_DELAY);
37
+ }, [cancelClose]);
38
+ const handleOpenChange = useCallback((value) => {
39
+ cancelClose();
40
+ setIsOpen(value);
41
+ }, [cancelClose]);
42
+ useEffect(() => cancelClose, [cancelClose]);
32
43
  const contextValue = useMemo(() => ({
33
44
  isOpen,
34
45
  onOpenChange: handleOpenChange,
35
46
  triggerRef,
36
- }), [isOpen, handleOpenChange, triggerRef]);
37
- return (jsx(SubMenuContext.Provider, { value: contextValue, children: jsx("div", { className: className, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, children: children }) }));
47
+ cancelClose,
48
+ scheduleClose,
49
+ }), [isOpen, handleOpenChange, cancelClose, scheduleClose]);
50
+ return (jsx(SubMenuContext.Provider, { value: contextValue, children: children }));
38
51
  };
39
52
  ContextMenuSub.displayName = "ContextMenuSub";
40
53
 
@@ -15,7 +15,7 @@ const ContextMenuSubBody = React__default.forwardRef(({ children, className, ani
15
15
  // Relative elevation: lift above the parent menu surface (overlay base = 5).
16
16
  const surfaceLevel = useSurfaceElevation({ baseRung: 5, offset: 2, elevation, lift });
17
17
  const { theme } = useContextMenuContext();
18
- const { isOpen, triggerRef, onOpenChange } = useSubMenuContext();
18
+ const { isOpen, triggerRef, onOpenChange, cancelClose, scheduleClose } = useSubMenuContext();
19
19
  const shouldReduceMotion = useReducedMotion();
20
20
  const isClient = useIsClient();
21
21
  const localRef = useRef(null);
@@ -88,7 +88,18 @@ const ContextMenuSubBody = React__default.forwardRef(({ children, className, ani
88
88
  },
89
89
  };
90
90
  // Extract DOM props to avoid conflicts
91
- const { onAnimationStart, onAnimationEnd, onDrag, onDragStart, onDragEnd, ...domProps } = props;
91
+ const { onAnimationStart, onAnimationEnd, onDrag, onDragStart, onDragEnd, onMouseEnter, onMouseLeave, ...domProps } = props;
92
+ // The body portals to <body>, so it is not a DOM descendant of the trigger: entering it
93
+ // has to cancel the close the trigger scheduled when the pointer left, and leaving it
94
+ // has to schedule one. Consumer handlers are composed, not replaced.
95
+ const handleMouseEnter = useCallback((e) => {
96
+ cancelClose();
97
+ onMouseEnter === null || onMouseEnter === void 0 ? void 0 : onMouseEnter(e);
98
+ }, [cancelClose, onMouseEnter]);
99
+ const handleMouseLeave = useCallback((e) => {
100
+ scheduleClose();
101
+ onMouseLeave === null || onMouseLeave === void 0 ? void 0 : onMouseLeave(e);
102
+ }, [scheduleClose, onMouseLeave]);
92
103
  // Detect dark mode from document
93
104
  const isDarkMode = typeof document !== "undefined" &&
94
105
  (document.documentElement.classList.contains("dark") ||
@@ -103,7 +114,7 @@ const ContextMenuSubBody = React__default.forwardRef(({ children, className, ani
103
114
  type: "spring",
104
115
  stiffness: 500,
105
116
  damping: 30,
106
- }, "data-state": isOpen ? "open" : "closed", "data-flikkui-portal": "", ...domProps, children: jsx(SurfaceProvider, { level: surfaceLevel, children: children }) })) }));
117
+ }, "data-state": isOpen ? "open" : "closed", "data-flikkui-portal": "", onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, ...domProps, children: jsx(SurfaceProvider, { level: surfaceLevel, children: children }) })) }));
107
118
  // Always use portal for submenus
108
119
  const portalTarget = isClient ? document.body : null;
109
120
  return portalTarget ? createPortal(submenuContent, portalTarget) : null;