@cube-dev/ui-kit 0.0.0-canary-b2f8ae7 → 0.0.0-canary-26fe35d

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 (573) hide show
  1. package/dist/CHANGELOG.md +8 -0
  2. package/dist/_internal/hooks/use-chained-callback.js +1 -1
  3. package/dist/_internal/hooks/use-debounced-value.js +1 -1
  4. package/dist/_internal/hooks/use-deprecation-warning.js +1 -1
  5. package/dist/_internal/hooks/use-event.js +1 -1
  6. package/dist/_internal/hooks/use-is-first-render.js +1 -1
  7. package/dist/_internal/hooks/use-sync-ref.js +1 -1
  8. package/dist/_internal/hooks/use-timer/timer.js +1 -1
  9. package/dist/_internal/hooks/use-timer/use-timer.js +1 -1
  10. package/dist/_internal/hooks/use-warn.js +1 -1
  11. package/dist/_virtual/_rolldown/runtime.js +1 -1
  12. package/dist/chunks/cacheKey.js +1 -1
  13. package/dist/chunks/definitions.js +1 -1
  14. package/dist/chunks/renderChunk.js +1 -1
  15. package/dist/components/Block.js +1 -1
  16. package/dist/components/CollectionItem.js +1 -1
  17. package/dist/components/GlobalStyles.js +1 -55
  18. package/dist/components/GlobalStyles.js.map +1 -1
  19. package/dist/components/GridProvider.js +1 -1
  20. package/dist/components/HiddenInput.js +1 -1
  21. package/dist/components/Root.js +1 -1
  22. package/dist/components/actions/Action/Action.js +1 -1
  23. package/dist/components/actions/Banner/Banner.js +1 -1
  24. package/dist/components/actions/Button/Button.d.ts +1 -0
  25. package/dist/components/actions/Button/Button.js +1 -1
  26. package/dist/components/actions/ButtonGroup/ButtonGroup.js +1 -1
  27. package/dist/components/actions/CommandMenu/CommandMenu.js +1 -1
  28. package/dist/components/actions/CommandMenu/styled.js +1 -1
  29. package/dist/components/actions/ItemAction/ItemAction.js +1 -1
  30. package/dist/components/actions/ItemActionContext.js +1 -1
  31. package/dist/components/actions/ItemButton/ItemButton.js +1 -1
  32. package/dist/components/actions/Link/Link.js +1 -1
  33. package/dist/components/actions/Menu/Menu.js +1 -1
  34. package/dist/components/actions/Menu/MenuItem.js +1 -1
  35. package/dist/components/actions/Menu/MenuSection.js +1 -1
  36. package/dist/components/actions/Menu/MenuTrigger.js +1 -1
  37. package/dist/components/actions/Menu/SubMenuTrigger.js +1 -1
  38. package/dist/components/actions/Menu/SubmenuTriggerContext.js +1 -1
  39. package/dist/components/actions/Menu/context.js +1 -1
  40. package/dist/components/actions/Menu/styled.js +1 -1
  41. package/dist/components/actions/index.js +1 -1
  42. package/dist/components/actions/use-action.js +1 -1
  43. package/dist/components/actions/use-anchored-menu.js +1 -1
  44. package/dist/components/actions/use-context-menu.js +1 -1
  45. package/dist/components/content/ActiveZone/ActiveZone.js +1 -1
  46. package/dist/components/content/Alert/Alert.js +1 -1
  47. package/dist/components/content/Alert/use-alert.js +1 -1
  48. package/dist/components/content/Avatar/Avatar.js +1 -1
  49. package/dist/components/content/Badge/Badge.js +1 -1
  50. package/dist/components/content/Card/Card.js +1 -1
  51. package/dist/components/content/Content.js +1 -1
  52. package/dist/components/content/CopyPasteBlock/CopyPasteBlock.js +1 -1
  53. package/dist/components/content/CopySnippet/CopySnippet.js +1 -1
  54. package/dist/components/content/Disclosure/Disclosure.js +1 -1
  55. package/dist/components/content/Divider.js +1 -1
  56. package/dist/components/content/Footer.js +1 -1
  57. package/dist/components/content/Header.js +1 -1
  58. package/dist/components/content/HotKeys/HotKeys.js +1 -1
  59. package/dist/components/content/Item/Item.js +1 -1
  60. package/dist/components/content/ItemBadge/ItemBadge.js +1 -1
  61. package/dist/components/content/Layout/GridLayout.js +1 -1
  62. package/dist/components/content/Layout/Layout.js +1 -1
  63. package/dist/components/content/Layout/LayoutBlock.js +1 -1
  64. package/dist/components/content/Layout/LayoutCenter.js +1 -1
  65. package/dist/components/content/Layout/LayoutContainer.js +1 -1
  66. package/dist/components/content/Layout/LayoutContent.js +1 -1
  67. package/dist/components/content/Layout/LayoutContext.js +1 -1
  68. package/dist/components/content/Layout/LayoutFlex.js +1 -1
  69. package/dist/components/content/Layout/LayoutFooter.js +1 -1
  70. package/dist/components/content/Layout/LayoutGrid.js +1 -1
  71. package/dist/components/content/Layout/LayoutHeader.d.ts +2 -0
  72. package/dist/components/content/Layout/LayoutHeader.js +24 -6
  73. package/dist/components/content/Layout/LayoutHeader.js.map +1 -1
  74. package/dist/components/content/Layout/LayoutPane.js +1 -1
  75. package/dist/components/content/Layout/LayoutPanel.js +1 -1
  76. package/dist/components/content/Layout/LayoutPanelHeader.js +1 -1
  77. package/dist/components/content/Layout/LayoutToolbar.js +1 -1
  78. package/dist/components/content/Layout/hooks/useTinyScrollbar.js +1 -1
  79. package/dist/components/content/Layout/index.js +1 -1
  80. package/dist/components/content/Layout/utils.js +1 -1
  81. package/dist/components/content/Paragraph.js +1 -1
  82. package/dist/components/content/Placeholder/Placeholder.js +1 -1
  83. package/dist/components/content/PrismCode/PrismCode.js +1 -1
  84. package/dist/components/content/PrismCode/prismSetup.js +1 -1
  85. package/dist/components/content/PrismDiffCode/PrismDiffCode.js +1 -1
  86. package/dist/components/content/Result/Result.js +1 -1
  87. package/dist/components/content/Skeleton/Skeleton.js +1 -1
  88. package/dist/components/content/Tag/Tag.js +1 -1
  89. package/dist/components/content/Text.js +1 -1
  90. package/dist/components/content/TextItem/TextItem.js +1 -1
  91. package/dist/components/content/Title.js +1 -1
  92. package/dist/components/content/highlightText.js +1 -1
  93. package/dist/components/content/use-auto-tooltip.js +1 -1
  94. package/dist/components/fields/Checkbox/Checkbox.js +1 -1
  95. package/dist/components/fields/Checkbox/CheckboxGroup.js +1 -1
  96. package/dist/components/fields/Checkbox/context.js +1 -1
  97. package/dist/components/fields/ComboBox/ComboBox.js +1 -1
  98. package/dist/components/fields/DatePicker/DateInput.js +1 -1
  99. package/dist/components/fields/DatePicker/DateInputBase.js +1 -1
  100. package/dist/components/fields/DatePicker/DatePicker.js +1 -1
  101. package/dist/components/fields/DatePicker/DatePickerButton.js +1 -1
  102. package/dist/components/fields/DatePicker/DatePickerElement.js +1 -1
  103. package/dist/components/fields/DatePicker/DatePickerInput.js +1 -1
  104. package/dist/components/fields/DatePicker/DatePickerSegment.js +1 -1
  105. package/dist/components/fields/DatePicker/DateRangePicker.js +1 -1
  106. package/dist/components/fields/DatePicker/DateRangeSeparatedPicker.js +1 -1
  107. package/dist/components/fields/DatePicker/TimeInput.js +1 -1
  108. package/dist/components/fields/DatePicker/intl.js +1 -1
  109. package/dist/components/fields/DatePicker/parseDate.js +1 -1
  110. package/dist/components/fields/DatePicker/props.js +1 -1
  111. package/dist/components/fields/DatePicker/utils.js +1 -1
  112. package/dist/components/fields/FileInput/FileInput.js +1 -1
  113. package/dist/components/fields/FilterListBox/FilterListBox.js +1 -1
  114. package/dist/components/fields/FilterPicker/FilterPicker.js +1 -1
  115. package/dist/components/fields/Input/Input.js +1 -1
  116. package/dist/components/fields/ListBox/ListBox.js +1 -1
  117. package/dist/components/fields/NumberInput/NumberInput.js +1 -1
  118. package/dist/components/fields/NumberInput/StepButton.js +1 -1
  119. package/dist/components/fields/PasswordInput/PasswordInput.js +1 -1
  120. package/dist/components/fields/Picker/Picker.js +1 -1
  121. package/dist/components/fields/RadioGroup/Radio.js +1 -1
  122. package/dist/components/fields/RadioGroup/RadioGroup.js +1 -1
  123. package/dist/components/fields/RadioGroup/context.js +1 -1
  124. package/dist/components/fields/SearchInput/SearchInput.js +1 -1
  125. package/dist/components/fields/Select/Select.js +1 -1
  126. package/dist/components/fields/Slider/Gradation.js +1 -1
  127. package/dist/components/fields/Slider/HueSlider.js +1 -1
  128. package/dist/components/fields/Slider/RangeSlider.js +1 -1
  129. package/dist/components/fields/Slider/Slider.js +1 -1
  130. package/dist/components/fields/Slider/SliderBase.js +1 -1
  131. package/dist/components/fields/Slider/SliderThumb.js +1 -1
  132. package/dist/components/fields/Slider/SliderTrack.js +1 -1
  133. package/dist/components/fields/Slider/elements.js +1 -1
  134. package/dist/components/fields/Slider/index.js +1 -1
  135. package/dist/components/fields/Switch/Switch.js +1 -1
  136. package/dist/components/fields/TextArea/TextArea.js +1 -1
  137. package/dist/components/fields/TextInput/TextInput.js +1 -1
  138. package/dist/components/fields/TextInput/TextInputBase.js +1 -1
  139. package/dist/components/fields/TextInputMapper/TextInputMapper.js +1 -1
  140. package/dist/components/form/FieldWrapper/FieldWrapper.js +1 -1
  141. package/dist/components/form/FieldWrapper/extract-field-wrapper-props.js +1 -1
  142. package/dist/components/form/Form/Field.js +1 -1
  143. package/dist/components/form/Form/Form.js +1 -1
  144. package/dist/components/form/Form/ResetButton/ResetButton.js +1 -1
  145. package/dist/components/form/Form/SubmitButton/SubmitButton.js +1 -1
  146. package/dist/components/form/Form/SubmitError.js +1 -1
  147. package/dist/components/form/Form/index.js +1 -1
  148. package/dist/components/form/Form/use-field/use-field-props.js +1 -1
  149. package/dist/components/form/Form/use-field/use-field.js +1 -1
  150. package/dist/components/form/Form/use-form.js +1 -1
  151. package/dist/components/form/Form/validation.js +1 -1
  152. package/dist/components/form/Label.js +1 -1
  153. package/dist/components/form/wrapper.js +1 -1
  154. package/dist/components/helpers/DisplayTransition/DisplayTransition.js +1 -1
  155. package/dist/components/helpers/IconSwitch/IconSwitch.js +1 -1
  156. package/dist/components/layout/Flex.js +1 -1
  157. package/dist/components/layout/Flow.js +1 -1
  158. package/dist/components/layout/Grid.js +1 -1
  159. package/dist/components/layout/Panel.js +1 -1
  160. package/dist/components/layout/Prefix.js +1 -1
  161. package/dist/components/layout/ResizablePanel.js +1 -1
  162. package/dist/components/layout/Space.js +1 -1
  163. package/dist/components/layout/Suffix.js +1 -1
  164. package/dist/components/navigation/Tabs/DraggableTabList.js +1 -1
  165. package/dist/components/navigation/Tabs/EditableTitle.js +1 -1
  166. package/dist/components/navigation/Tabs/TabButton.js +1 -1
  167. package/dist/components/navigation/Tabs/TabDropIndicator.js +1 -1
  168. package/dist/components/navigation/Tabs/TabPanel.js +1 -1
  169. package/dist/components/navigation/Tabs/TabPicker.js +1 -1
  170. package/dist/components/navigation/Tabs/Tabs.js +1 -1
  171. package/dist/components/navigation/Tabs/TabsAction.js +1 -1
  172. package/dist/components/navigation/Tabs/TabsContext.js +1 -1
  173. package/dist/components/navigation/Tabs/styled.js +1 -1
  174. package/dist/components/navigation/Tabs/types.js +1 -1
  175. package/dist/components/navigation/Tabs/use-tab-editing.js +1 -1
  176. package/dist/components/navigation/Tabs/use-tab-indicator.js +1 -1
  177. package/dist/components/organisms/FileTabs/FileTabs.js +1 -1
  178. package/dist/components/organisms/StatsCard/StatsCard.js +1 -1
  179. package/dist/components/other/Calendar/Calendar.js +1 -1
  180. package/dist/components/other/Calendar/CalendarCell.js +1 -1
  181. package/dist/components/other/Calendar/CalendarGrid.js +1 -1
  182. package/dist/components/other/Calendar/RangeCalendar.js +1 -1
  183. package/dist/components/other/CloudLogo/CloudLogo.js +1 -1
  184. package/dist/components/overlays/AlertDialog/AlertDialog.js +1 -1
  185. package/dist/components/overlays/AlertDialog/AlertDialogApiProvider.js +1 -1
  186. package/dist/components/overlays/AlertDialog/AlertDialogZone.js +1 -1
  187. package/dist/components/overlays/Dialog/Dialog.js +1 -1
  188. package/dist/components/overlays/Dialog/DialogContainer.js +1 -1
  189. package/dist/components/overlays/Dialog/DialogForm.js +1 -1
  190. package/dist/components/overlays/Dialog/DialogTrigger.js +1 -1
  191. package/dist/components/overlays/Dialog/context.js +1 -1
  192. package/dist/components/overlays/Dialog/use-dialog-container.js +1 -1
  193. package/dist/components/overlays/Modal/Modal.d.ts +2 -1
  194. package/dist/components/overlays/Modal/Modal.js +1 -1
  195. package/dist/components/overlays/Modal/OpenTransition.js +1 -1
  196. package/dist/components/overlays/Modal/Overlay.d.ts +1 -0
  197. package/dist/components/overlays/Modal/Overlay.js +1 -1
  198. package/dist/components/overlays/Modal/Popover.js +1 -1
  199. package/dist/components/overlays/Modal/Tray.js +1 -1
  200. package/dist/components/overlays/Modal/Underlay.js +1 -1
  201. package/dist/components/overlays/Notifications/Notification.js +1 -1
  202. package/dist/components/overlays/Notifications/NotificationAction.js +10 -4
  203. package/dist/components/overlays/Notifications/NotificationAction.js.map +1 -1
  204. package/dist/components/overlays/Notifications/NotificationCard.d.ts +3 -0
  205. package/dist/components/overlays/Notifications/NotificationCard.js +6 -4
  206. package/dist/components/overlays/Notifications/NotificationCard.js.map +1 -1
  207. package/dist/components/overlays/Notifications/NotificationContext.d.ts +2 -0
  208. package/dist/components/overlays/Notifications/NotificationContext.js +1 -1
  209. package/dist/components/overlays/Notifications/NotificationItem.d.ts +3 -1
  210. package/dist/components/overlays/Notifications/NotificationItem.js +4 -3
  211. package/dist/components/overlays/Notifications/NotificationItem.js.map +1 -1
  212. package/dist/components/overlays/Notifications/OverlayContainer.js +5 -4
  213. package/dist/components/overlays/Notifications/OverlayContainer.js.map +1 -1
  214. package/dist/components/overlays/Notifications/OverlayProvider.js +2 -1
  215. package/dist/components/overlays/Notifications/OverlayProvider.js.map +1 -1
  216. package/dist/components/overlays/Notifications/PersistentNotificationsList.js +1 -1
  217. package/dist/components/overlays/Notifications/dismissed-storage.js +1 -1
  218. package/dist/components/overlays/Notifications/format-relative-time.js +1 -1
  219. package/dist/components/overlays/Notifications/index.js +1 -1
  220. package/dist/components/overlays/Notifications/types.d.ts +2 -0
  221. package/dist/components/overlays/Notifications/use-notification-state.js +20 -2
  222. package/dist/components/overlays/Notifications/use-notification-state.js.map +1 -1
  223. package/dist/components/overlays/Notifications/use-notifications.js +1 -1
  224. package/dist/components/overlays/Notifications/use-overlay-timers.js +1 -1
  225. package/dist/components/overlays/Notifications/use-persistent-notifications.js +1 -1
  226. package/dist/components/overlays/Notifications/use-persistent-state.js +8 -1
  227. package/dist/components/overlays/Notifications/use-persistent-state.js.map +1 -1
  228. package/dist/components/overlays/Notifications/use-toast-state.js +1 -1
  229. package/dist/components/overlays/Toast/ToastItem.js +1 -1
  230. package/dist/components/overlays/Toast/index.js +1 -1
  231. package/dist/components/overlays/Toast/types.d.ts +2 -0
  232. package/dist/components/overlays/Toast/useProgressToast.js +49 -21
  233. package/dist/components/overlays/Toast/useProgressToast.js.map +1 -1
  234. package/dist/components/overlays/Toast/useToast.js +1 -1
  235. package/dist/components/overlays/Tooltip/Tooltip.js +1 -1
  236. package/dist/components/overlays/Tooltip/TooltipProvider.js +1 -1
  237. package/dist/components/overlays/Tooltip/TooltipTrigger.js +1 -1
  238. package/dist/components/overlays/Tooltip/context.js +1 -1
  239. package/dist/components/portal/Portal.js +1 -1
  240. package/dist/components/portal/PortalProvider.d.ts +2 -0
  241. package/dist/components/portal/PortalProvider.js +1 -1
  242. package/dist/components/portal/index.d.ts +1 -0
  243. package/dist/components/portal/usePortal.js +1 -1
  244. package/dist/components/shared/InvalidIcon.js +1 -1
  245. package/dist/components/shared/ValidIcon.js +1 -1
  246. package/dist/components/status/LoadingAnimation/LoadingAnimation.js +1 -1
  247. package/dist/components/status/Spin/Cube.js +1 -1
  248. package/dist/components/status/Spin/InternalSpinner.js +1 -1
  249. package/dist/components/status/Spin/Spin.js +1 -1
  250. package/dist/components/status/Spin/SpinsContainer.js +1 -1
  251. package/dist/config.js +1 -1
  252. package/dist/css-writer.js +1 -1
  253. package/dist/data/item-themes.js +1 -1
  254. package/dist/data/themes.js +1 -1
  255. package/dist/extractor.js +1 -1
  256. package/dist/icons/AdjustmentsHorizontalIcon.js +1 -1
  257. package/dist/icons/AdjustmentsIcon.js +1 -1
  258. package/dist/icons/AiIcon.js +1 -1
  259. package/dist/icons/AreaChartIcon.js +1 -1
  260. package/dist/icons/BackwardIcon.js +1 -1
  261. package/dist/icons/BarChartIcon.js +1 -1
  262. package/dist/icons/BellFilledIcon.js +1 -1
  263. package/dist/icons/BellIcon.js +1 -1
  264. package/dist/icons/BooleanIcon.js +1 -1
  265. package/dist/icons/CalendarEditIcon.js +1 -1
  266. package/dist/icons/CalendarIcon.js +1 -1
  267. package/dist/icons/CaretDownIcon.js +1 -1
  268. package/dist/icons/CaretUpIcon.js +1 -1
  269. package/dist/icons/ChartAreaStackedIcon.js +1 -1
  270. package/dist/icons/ChartAreaStackedPercentageIcon.js +1 -1
  271. package/dist/icons/ChartBarGroupedHorizontalIcon.js +1 -1
  272. package/dist/icons/ChartBarGroupedIcon.js +1 -1
  273. package/dist/icons/ChartBarHorizontalIcon.js +1 -1
  274. package/dist/icons/ChartBarLineIcon.js +1 -1
  275. package/dist/icons/ChartBarStackedHorizontalIcon.js +1 -1
  276. package/dist/icons/ChartBarStackedIcon.js +1 -1
  277. package/dist/icons/ChartBarStackedPercentageHorizontalIcon.js +1 -1
  278. package/dist/icons/ChartBarStackedPercentageIcon.js +1 -1
  279. package/dist/icons/ChartBoxPlot2Icon.js +1 -1
  280. package/dist/icons/ChartBoxPlotIcon.js +1 -1
  281. package/dist/icons/ChartBubbleIcon.js +1 -1
  282. package/dist/icons/ChartDonut2Icon.js +1 -1
  283. package/dist/icons/ChartFunnelIcon.js +1 -1
  284. package/dist/icons/ChartHeatmapIcon.js +1 -1
  285. package/dist/icons/ChartKPIIcon.js +1 -1
  286. package/dist/icons/ChartPie2Icon.js +1 -1
  287. package/dist/icons/ChartScatterIcon.js +1 -1
  288. package/dist/icons/CheckCircleFilledIcon.js +1 -1
  289. package/dist/icons/CheckCircleIcon.js +1 -1
  290. package/dist/icons/CheckIcon.js +1 -1
  291. package/dist/icons/CircleFilledIcon.js +1 -1
  292. package/dist/icons/ClearIcon.js +1 -1
  293. package/dist/icons/CloseCircleFilledIcon.js +1 -1
  294. package/dist/icons/CloseCircleIcon.js +1 -1
  295. package/dist/icons/CloseIcon.js +1 -1
  296. package/dist/icons/CodeIcon.js +1 -1
  297. package/dist/icons/ColumnTotalIcon.js +1 -1
  298. package/dist/icons/CopyIcon.js +1 -1
  299. package/dist/icons/CountIcon.js +1 -1
  300. package/dist/icons/CubeIcon.js +1 -1
  301. package/dist/icons/CubePauseIcon.js +1 -1
  302. package/dist/icons/CubePlayIcon.js +1 -1
  303. package/dist/icons/CurrencyDollarIcon.js +1 -1
  304. package/dist/icons/DangerIcon.js +1 -1
  305. package/dist/icons/DashboardIcon.js +1 -1
  306. package/dist/icons/DatabaseIcon.js +1 -1
  307. package/dist/icons/DecimalDecreaseIcon.js +1 -1
  308. package/dist/icons/DecimalIncreaseIcon.js +1 -1
  309. package/dist/icons/DirectionIcon.js +1 -1
  310. package/dist/icons/DonutIcon.js +1 -1
  311. package/dist/icons/DownIcon.js +1 -1
  312. package/dist/icons/EditIcon.js +1 -1
  313. package/dist/icons/ExclamationCircleFilledIcon.js +1 -1
  314. package/dist/icons/ExclamationCircleIcon.js +1 -1
  315. package/dist/icons/ExclamationIcon.js +1 -1
  316. package/dist/icons/EyeIcon.js +1 -1
  317. package/dist/icons/EyeInvisibleIcon.js +1 -1
  318. package/dist/icons/FilterIcon.js +1 -1
  319. package/dist/icons/FolderFilledIcon.js +1 -1
  320. package/dist/icons/FolderIcon.js +1 -1
  321. package/dist/icons/FolderOpenFilledIcon.js +1 -1
  322. package/dist/icons/FolderOpenIcon.js +1 -1
  323. package/dist/icons/ForwardIcon.js +1 -1
  324. package/dist/icons/HierarchyIcon.js +1 -1
  325. package/dist/icons/HierarchyOpenIcon.js +1 -1
  326. package/dist/icons/Icon.js +1 -1
  327. package/dist/icons/InfoCircleIcon.js +1 -1
  328. package/dist/icons/InfoIcon.js +1 -1
  329. package/dist/icons/KeyIcon.js +1 -1
  330. package/dist/icons/LeftIcon.js +1 -1
  331. package/dist/icons/LineChartIcon.js +1 -1
  332. package/dist/icons/LoadingIcon.js +1 -1
  333. package/dist/icons/LockFilledIcon.js +1 -1
  334. package/dist/icons/LockIcon.js +1 -1
  335. package/dist/icons/MoreIcon.js +1 -1
  336. package/dist/icons/NotAllowedIcon.js +1 -1
  337. package/dist/icons/Number123Icon.js +1 -1
  338. package/dist/icons/NumberIcon.js +1 -1
  339. package/dist/icons/PauseCircleFilledIcon.js +1 -1
  340. package/dist/icons/PauseCircleIcon.js +1 -1
  341. package/dist/icons/PauseIcon.js +1 -1
  342. package/dist/icons/PercentageIcon.js +1 -1
  343. package/dist/icons/PieChartIcon.js +1 -1
  344. package/dist/icons/PlayCircleIcon.js +1 -1
  345. package/dist/icons/PlayIcon.js +1 -1
  346. package/dist/icons/PlusIcon.js +1 -1
  347. package/dist/icons/ProgressBarIcon.js +1 -1
  348. package/dist/icons/ReloadIcon.js +1 -1
  349. package/dist/icons/ReportIcon.js +1 -1
  350. package/dist/icons/ReturnIcon.js +1 -1
  351. package/dist/icons/RightIcon.js +1 -1
  352. package/dist/icons/RowTotalsIcon.js +1 -1
  353. package/dist/icons/SchemeIcon.js +1 -1
  354. package/dist/icons/SearchIcon.js +1 -1
  355. package/dist/icons/SemanticQueryIcon.js +1 -1
  356. package/dist/icons/SettingsIcon.js +1 -1
  357. package/dist/icons/ShieldFilledIcon.js +1 -1
  358. package/dist/icons/ShieldIcon.js +1 -1
  359. package/dist/icons/SlashIcon.js +1 -1
  360. package/dist/icons/SparklesIcon.js +1 -1
  361. package/dist/icons/SqlIcon.js +1 -1
  362. package/dist/icons/StatsIcon.js +1 -1
  363. package/dist/icons/StopIcon.js +1 -1
  364. package/dist/icons/StringIcon.js +1 -1
  365. package/dist/icons/SubtotalsIcon.js +1 -1
  366. package/dist/icons/SwitchIcon.js +1 -1
  367. package/dist/icons/TableIcon.js +1 -1
  368. package/dist/icons/ThumbsDownIcon.js +1 -1
  369. package/dist/icons/ThumbsUpIcon.js +1 -1
  370. package/dist/icons/ThunderboltCrossedIcon.js +1 -1
  371. package/dist/icons/ThunderboltFilledIcon.js +1 -1
  372. package/dist/icons/ThunderboltIcon.js +1 -1
  373. package/dist/icons/TimeIcon.js +1 -1
  374. package/dist/icons/TrashIcon.js +1 -1
  375. package/dist/icons/UnlockIcon.js +1 -1
  376. package/dist/icons/UpIcon.js +1 -1
  377. package/dist/icons/UserGroupIcon.js +1 -1
  378. package/dist/icons/UserIcon.js +1 -1
  379. package/dist/icons/UserLockIcon.js +1 -1
  380. package/dist/icons/ViewIcon.js +1 -1
  381. package/dist/icons/WarningFilledIcon.js +1 -1
  382. package/dist/icons/WarningIcon.js +1 -1
  383. package/dist/icons/wrap-icon.js +1 -1
  384. package/dist/index.js +1 -1
  385. package/dist/injector/injector.js +1 -1
  386. package/dist/injector/sheet-manager.js +1 -1
  387. package/dist/keyframes/index.js +1 -1
  388. package/dist/parser/classify.js +1 -1
  389. package/dist/parser/const.js +1 -1
  390. package/dist/parser/lru.js +1 -1
  391. package/dist/parser/parser.js +1 -1
  392. package/dist/parser/tokenizer.js +1 -1
  393. package/dist/parser/types.js +1 -1
  394. package/dist/pipeline/conditions.js +1 -1
  395. package/dist/pipeline/exclusive.js +1 -1
  396. package/dist/pipeline/index.js +1 -1
  397. package/dist/pipeline/materialize.js +1 -1
  398. package/dist/pipeline/parseStateKey.js +1 -1
  399. package/dist/pipeline/simplify.js +1 -1
  400. package/dist/plugins/okhsl-plugin.js +1 -1
  401. package/dist/properties/index.js +1 -1
  402. package/dist/provider.js +1 -1
  403. package/dist/providers/TrackingProvider.js +1 -1
  404. package/dist/providers/navigationAdapter.default.js +1 -1
  405. package/dist/states/index.js +1 -1
  406. package/dist/styles/align.js +1 -1
  407. package/dist/styles/border.js +1 -1
  408. package/dist/styles/color.js +1 -1
  409. package/dist/styles/createStyle.js +1 -1
  410. package/dist/styles/dimension.js +1 -1
  411. package/dist/styles/display.js +1 -1
  412. package/dist/styles/fade.js +1 -1
  413. package/dist/styles/fill.js +1 -1
  414. package/dist/styles/flow.js +1 -1
  415. package/dist/styles/gap.js +1 -1
  416. package/dist/styles/height.js +1 -1
  417. package/dist/styles/index.js +1 -1
  418. package/dist/styles/inset.js +1 -1
  419. package/dist/styles/justify.js +1 -1
  420. package/dist/styles/margin.js +1 -1
  421. package/dist/styles/outline.js +1 -1
  422. package/dist/styles/padding.js +1 -1
  423. package/dist/styles/predefined.js +1 -1
  424. package/dist/styles/preset.js +1 -1
  425. package/dist/styles/radius.js +1 -1
  426. package/dist/styles/scrollbar.js +1 -1
  427. package/dist/styles/shadow.js +1 -1
  428. package/dist/styles/styledScrollbar.js +1 -1
  429. package/dist/styles/transition.js +1 -1
  430. package/dist/styles/width.js +1 -1
  431. package/dist/tasty/chunks/cacheKey.d.ts +2 -0
  432. package/dist/tasty/chunks/cacheKey.js +1 -1
  433. package/dist/tasty/chunks/definitions.js +1 -1
  434. package/dist/tasty/chunks/index.d.ts +4 -0
  435. package/dist/tasty/chunks/renderChunk.d.ts +3 -0
  436. package/dist/tasty/chunks/renderChunk.js +1 -1
  437. package/dist/tasty/config.js +1 -1
  438. package/dist/tasty/debug.js +1 -1
  439. package/dist/tasty/hooks/index.d.ts +6 -0
  440. package/dist/tasty/hooks/useGlobalStyles.js +1 -1
  441. package/dist/tasty/hooks/useKeyframes.js +1 -1
  442. package/dist/tasty/hooks/useProperty.js +1 -1
  443. package/dist/tasty/hooks/useRawCSS.js +1 -1
  444. package/dist/tasty/hooks/useStyles.js +1 -1
  445. package/dist/tasty/index.d.ts +3 -0
  446. package/dist/tasty/injector/index.js +1 -1
  447. package/dist/tasty/injector/injector.js +1 -1
  448. package/dist/tasty/injector/sheet-manager.js +1 -1
  449. package/dist/tasty/keyframes/index.js +1 -1
  450. package/dist/tasty/parser/classify.js +1 -1
  451. package/dist/tasty/parser/const.js +1 -1
  452. package/dist/tasty/parser/lru.js +1 -1
  453. package/dist/tasty/parser/parser.js +1 -1
  454. package/dist/tasty/parser/tokenizer.js +1 -1
  455. package/dist/tasty/parser/types.js +1 -1
  456. package/dist/tasty/pipeline/conditions.js +1 -1
  457. package/dist/tasty/pipeline/exclusive.d.ts +2 -0
  458. package/dist/tasty/pipeline/exclusive.js +1 -1
  459. package/dist/tasty/pipeline/index.d.ts +2 -0
  460. package/dist/tasty/pipeline/index.js +1 -1
  461. package/dist/tasty/pipeline/materialize.js +1 -1
  462. package/dist/tasty/pipeline/parseStateKey.d.ts +2 -0
  463. package/dist/tasty/pipeline/parseStateKey.js +1 -1
  464. package/dist/tasty/pipeline/simplify.js +1 -1
  465. package/dist/tasty/plugins/index.d.ts +3 -0
  466. package/dist/tasty/plugins/okhsl-plugin.js +1 -1
  467. package/dist/tasty/properties/index.js +1 -1
  468. package/dist/tasty/states/index.d.ts +2 -0
  469. package/dist/tasty/states/index.js +1 -1
  470. package/dist/tasty/static/index.js +1 -1
  471. package/dist/tasty/static/tastyStatic.js +1 -1
  472. package/dist/tasty/static/types.js +1 -1
  473. package/dist/tasty/styles/align.js +1 -1
  474. package/dist/tasty/styles/border.js +1 -1
  475. package/dist/tasty/styles/color.js +1 -1
  476. package/dist/tasty/styles/createStyle.js +1 -1
  477. package/dist/tasty/styles/dimension.js +1 -1
  478. package/dist/tasty/styles/display.js +1 -1
  479. package/dist/tasty/styles/fade.js +1 -1
  480. package/dist/tasty/styles/fill.js +1 -1
  481. package/dist/tasty/styles/flow.js +1 -1
  482. package/dist/tasty/styles/gap.js +1 -1
  483. package/dist/tasty/styles/height.js +1 -1
  484. package/dist/tasty/styles/index.js +1 -1
  485. package/dist/tasty/styles/inset.js +1 -1
  486. package/dist/tasty/styles/justify.js +1 -1
  487. package/dist/tasty/styles/list.js +1 -1
  488. package/dist/tasty/styles/margin.js +1 -1
  489. package/dist/tasty/styles/outline.js +1 -1
  490. package/dist/tasty/styles/padding.js +1 -1
  491. package/dist/tasty/styles/predefined.d.ts +1 -0
  492. package/dist/tasty/styles/predefined.js +1 -1
  493. package/dist/tasty/styles/preset.js +1 -1
  494. package/dist/tasty/styles/radius.js +1 -1
  495. package/dist/tasty/styles/scrollbar.js +1 -1
  496. package/dist/tasty/styles/shadow.js +1 -1
  497. package/dist/tasty/styles/styledScrollbar.js +1 -1
  498. package/dist/tasty/styles/transition.js +1 -1
  499. package/dist/tasty/styles/width.js +1 -1
  500. package/dist/tasty/tasty.d.ts +1 -0
  501. package/dist/tasty/tasty.js +1 -1
  502. package/dist/tasty/utils/cache-wrapper.js +1 -1
  503. package/dist/tasty/utils/case-converter.js +1 -1
  504. package/dist/tasty/utils/colors.js +1 -1
  505. package/dist/tasty/utils/dotize.js +1 -1
  506. package/dist/tasty/utils/filter-base-props.js +1 -1
  507. package/dist/tasty/utils/get-display-name.js +1 -1
  508. package/dist/tasty/utils/hsl-to-rgb.js +1 -1
  509. package/dist/tasty/utils/is-dev-env.js +1 -1
  510. package/dist/tasty/utils/merge-styles.js +1 -1
  511. package/dist/tasty/utils/mod-attrs.js +1 -1
  512. package/dist/tasty/utils/okhsl-to-rgb.js +1 -1
  513. package/dist/tasty/utils/process-tokens.js +1 -1
  514. package/dist/tasty/utils/resolve-recipes.js +1 -1
  515. package/dist/tasty/utils/string.js +1 -1
  516. package/dist/tasty/utils/styles.js +1 -1
  517. package/dist/tasty/utils/typography.js +1 -1
  518. package/dist/tasty/utils/warnings.js +1 -1
  519. package/dist/tasty/zero/babel.js +1 -1
  520. package/dist/tasty/zero/index.js +1 -1
  521. package/dist/tasty/zero/next.js +1 -1
  522. package/dist/tokens/base.js +1 -1
  523. package/dist/tokens/colors.js +1 -1
  524. package/dist/tokens/index.js +1 -1
  525. package/dist/tokens/layout.js +1 -1
  526. package/dist/tokens/shadows.js +1 -1
  527. package/dist/tokens/sizes.js +1 -1
  528. package/dist/tokens/spacing.js +1 -1
  529. package/dist/tokens/typography.js +1 -1
  530. package/dist/utils/ResizeSensor.js +1 -1
  531. package/dist/utils/cache-wrapper.js +1 -1
  532. package/dist/utils/case-converter.js +1 -1
  533. package/dist/utils/hsl-to-rgb.js +1 -1
  534. package/dist/utils/is-dev-env.js +1 -1
  535. package/dist/utils/merge-styles.js +1 -1
  536. package/dist/utils/modules.js +1 -1
  537. package/dist/utils/okhsl-to-rgb.js +1 -1
  538. package/dist/utils/process-tokens.js +3 -1
  539. package/dist/utils/process-tokens.js.map +1 -1
  540. package/dist/utils/promise.js +1 -1
  541. package/dist/utils/raf.js +1 -1
  542. package/dist/utils/random.js +1 -1
  543. package/dist/utils/range.js +1 -1
  544. package/dist/utils/react/RenderCache.js +1 -1
  545. package/dist/utils/react/Slots.js +1 -1
  546. package/dist/utils/react/chain.js +1 -1
  547. package/dist/utils/react/forwardRefWithGenerics.js +1 -1
  548. package/dist/utils/react/interactions.js +1 -1
  549. package/dist/utils/react/isTextOnly.js +1 -1
  550. package/dist/utils/react/mapProps.js +1 -1
  551. package/dist/utils/react/mergeProps.js +1 -1
  552. package/dist/utils/react/nullableValue.js +1 -1
  553. package/dist/utils/react/resolveIcon.js +1 -1
  554. package/dist/utils/react/sharedStore.js +1 -1
  555. package/dist/utils/react/useCombinedRefs.js +1 -1
  556. package/dist/utils/react/useControlledFocusVisible.js +1 -1
  557. package/dist/utils/react/useEventBus.js +1 -1
  558. package/dist/utils/react/useId.js +1 -1
  559. package/dist/utils/react/useIsDarwin.js +1 -1
  560. package/dist/utils/react/useKeySymbols.js +1 -1
  561. package/dist/utils/react/useLayoutEffect.js +1 -1
  562. package/dist/utils/react/useLocalStorage.js +1 -1
  563. package/dist/utils/react/useMergeStyles.js +1 -1
  564. package/dist/utils/react/useQaProps.js +1 -1
  565. package/dist/utils/react/useViewportSize.js +1 -1
  566. package/dist/utils/react/wrapNodeIfPlain.js +1 -1
  567. package/dist/utils/resolve-recipes.js +1 -1
  568. package/dist/utils/string.js +1 -1
  569. package/dist/utils/styles.js +1 -1
  570. package/dist/utils/tree.js +1 -1
  571. package/dist/utils/warnings.js +1 -1
  572. package/dist/version.js +2 -2
  573. package/package.json +1 -1
@@ -31,6 +31,8 @@ interface NotificationCardProps {
31
31
  notificationId?: Key;
32
32
  /** Called when the notification is dismissed */
33
33
  onDismiss?: (id: Key, reason: DismissReason) => void;
34
+ /** Called when a dismissed notification should be restored (async action returned false) */
35
+ onRestore?: (id: Key) => void;
34
36
  /** Suffix content (e.g. timestamp) */
35
37
  suffix?: ReactNode;
36
38
  }
@@ -49,6 +51,7 @@ declare function NotificationCard({
49
51
  elevated,
50
52
  notificationId,
51
53
  onDismiss,
54
+ onRestore,
52
55
  suffix
53
56
  }: NotificationCardProps): react_jsx_runtime0.JSX.Element;
54
57
  //#endregion
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-b2f8ae7 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-26fe35d | Cube Dev Team */
2
2
  import { tasty } from "../../../tasty/tasty.js";
3
3
  import { Block } from "../../Block.js";
4
4
  import { ItemActionProvider } from "../../actions/ItemActionContext.js";
@@ -59,7 +59,7 @@ function AutoDismissButton() {
59
59
  * of `isDismissible`. The `showAutoDismiss` flag only controls the
60
60
  * auto-appended "Dismiss" button.
61
61
  */
62
- function ActionsSection({ actions, theme, showAutoDismiss, hasDismissContext, notificationId, onDismiss }) {
62
+ function ActionsSection({ actions, theme, showAutoDismiss, hasDismissContext, notificationId, onDismiss, onRestore }) {
63
63
  const actionsContent = /* @__PURE__ */ jsxs(Space, {
64
64
  placeSelf: "end",
65
65
  placeContent: "end",
@@ -73,6 +73,7 @@ function ActionsSection({ actions, theme, showAutoDismiss, hasDismissContext, no
73
73
  children: hasDismissContext ? /* @__PURE__ */ jsx(NotificationDismissProvider, {
74
74
  notificationId,
75
75
  onDismiss,
76
+ onRestore,
76
77
  children: wrappedContent
77
78
  }) : wrappedContent
78
79
  });
@@ -81,7 +82,7 @@ function ActionsSection({ actions, theme, showAutoDismiss, hasDismissContext, no
81
82
  * Shared presentational card used by both overlay NotificationItem
82
83
  * and PersistentNotificationListItem.
83
84
  */
84
- function NotificationCard({ qa = "Notification", theme, title, description, icon: providedIcon, actions, isDismissible = true, elevated = true, notificationId, onDismiss, suffix }) {
85
+ function NotificationCard({ qa = "Notification", theme, title, description, icon: providedIcon, actions, isDismissible = true, elevated = true, notificationId, onDismiss, onRestore, suffix }) {
85
86
  const icon = getThemeIcon(theme, providedIcon);
86
87
  const hasDismissContext = notificationId != null && onDismiss != null;
87
88
  const showAutoDismiss = isDismissible && hasDismissContext;
@@ -101,7 +102,8 @@ function NotificationCard({ qa = "Notification", theme, title, description, icon
101
102
  showAutoDismiss,
102
103
  hasDismissContext,
103
104
  notificationId,
104
- onDismiss
105
+ onDismiss,
106
+ onRestore
105
107
  })]
106
108
  }) : void 0,
107
109
  suffix,
@@ -1 +1 @@
1
- {"version":3,"file":"NotificationCard.js","names":["Item"],"sources":["../../../../src/components/overlays/Notifications/NotificationCard.tsx"],"sourcesContent":["import { Key, ReactNode, useContext, useRef } from 'react';\n\nimport { tasty } from '../../../tasty';\nimport { ItemActionProvider } from '../../actions/ItemActionContext';\nimport { Block } from '../../Block';\nimport { Item } from '../../content/Item/Item';\nimport { Flex } from '../../layout/Flex';\nimport { Space } from '../../layout/Space';\nimport { getThemeIcon } from '../Toast/useToast';\n\nimport {\n DismissActionDetectedContext,\n NotificationAction,\n NotificationDismissProvider,\n} from './NotificationAction';\n\nimport type { DismissReason, NotificationType } from './types';\n\n// ─── Styled Components ──────────────────────────────────────────────\n\nconst StyledItem = tasty(Item, {\n styles: {\n width: {\n '': 'max min((100vw - 4x), 50x)',\n flat: '100%',\n },\n shadow: {\n '': '$shadow',\n flat: false,\n },\n radius: {\n '': '1cr',\n flat: '0',\n },\n transition: 'theme, inset',\n\n Description: {\n preset: 't4',\n },\n },\n});\n\n// ─── Dismiss Action Detection ────────────────────────────────────────\n\n/**\n * Provides a ref via context that NotificationAction children write to\n * during render when `isDismiss` is set. The ref is reset each render.\n */\nfunction DismissActionDetector({ children }: { children: ReactNode }) {\n const ref = useRef(false);\n\n // Reset each render so detection is fresh\n ref.current = false;\n\n return (\n <DismissActionDetectedContext.Provider value={ref}>\n {children}\n </DismissActionDetectedContext.Provider>\n );\n}\n\n/**\n * Renders the default \"Dismiss\" button only if no sibling NotificationAction\n * has `isDismiss` set. Reads from DismissActionDetectedContext ref which is\n * populated by actions that rendered before this component (left-to-right order).\n */\nfunction AutoDismissButton() {\n const dismissDetectedRef = useContext(DismissActionDetectedContext);\n\n if (dismissDetectedRef?.current) return null;\n\n return <NotificationAction isDismiss>Dismiss</NotificationAction>;\n}\n\n// ─── ActionsSection ─────────────────────────────────────────────────\n\ninterface ActionsSectionProps {\n actions?: ReactNode;\n theme?: NotificationType;\n /**\n * Whether to show the auto-appended \"Dismiss\" button.\n * Controlled by `isDismissible` on the notification.\n *\n * When false, no default \"Dismiss\" button is rendered, but actions with\n * `closeOnPress` (default `true`) can still close the notification via\n * the dismiss context.\n */\n showAutoDismiss: boolean;\n /** Whether the dismiss context is available (notificationId + onDismiss present) */\n hasDismissContext: boolean;\n notificationId?: Key;\n onDismiss?: (id: Key, reason: DismissReason) => void;\n}\n\n/**\n * Extracted sub-component for the actions area of a notification card.\n *\n * The dismiss provider is always rendered when `hasDismissContext` is true,\n * so any action with `closeOnPress` can close the notification — regardless\n * of `isDismissible`. The `showAutoDismiss` flag only controls the\n * auto-appended \"Dismiss\" button.\n */\nfunction ActionsSection({\n actions,\n theme,\n showAutoDismiss,\n hasDismissContext,\n notificationId,\n onDismiss,\n}: ActionsSectionProps) {\n const actionsContent = (\n <Space placeSelf=\"end\" placeContent=\"end\" flexGrow={1}>\n {actions}\n {showAutoDismiss && <AutoDismissButton />}\n </Space>\n );\n\n const wrappedContent = showAutoDismiss ? (\n <DismissActionDetector>{actionsContent}</DismissActionDetector>\n ) : (\n actionsContent\n );\n\n return (\n <ItemActionProvider type=\"card\" theme={theme}>\n {hasDismissContext ? (\n <NotificationDismissProvider\n notificationId={notificationId!}\n onDismiss={onDismiss!}\n >\n {wrappedContent}\n </NotificationDismissProvider>\n ) : (\n wrappedContent\n )}\n </ItemActionProvider>\n );\n}\n\n// ─── NotificationCard ────────────────────────────────────────────────\n\nexport interface NotificationCardProps {\n qa?: string;\n /** Notification theme */\n theme?: NotificationType;\n /** Primary text */\n title?: ReactNode;\n /** Secondary text */\n description?: ReactNode;\n /** Custom icon override (theme default used if omitted) */\n icon?: ReactNode;\n /** Action buttons rendered below description */\n actions?: ReactNode;\n /**\n * Whether the notification shows the default dismiss UI (auto-appended\n * \"Dismiss\" button and Escape key). Default: true.\n *\n * When false, no default \"Dismiss\" button is rendered and Escape does\n * nothing, but actions with `closeOnPress` (default) can still close\n * the notification.\n */\n isDismissible?: boolean;\n /** When false the card drops its shadow (e.g. inside a list). Default: true. */\n elevated?: boolean;\n /** Notification id */\n notificationId?: Key;\n /** Called when the notification is dismissed */\n onDismiss?: (id: Key, reason: DismissReason) => void;\n /** Suffix content (e.g. timestamp) */\n suffix?: ReactNode;\n}\n\n/**\n * Shared presentational card used by both overlay NotificationItem\n * and PersistentNotificationListItem.\n */\nexport function NotificationCard({\n qa = 'Notification',\n theme,\n title,\n description,\n icon: providedIcon,\n actions,\n isDismissible = true,\n elevated = true,\n notificationId,\n onDismiss,\n suffix,\n}: NotificationCardProps) {\n const icon = getThemeIcon(theme, providedIcon);\n\n const hasDismissContext = notificationId != null && onDismiss != null;\n const showAutoDismiss = isDismissible && hasDismissContext;\n const hasActions = !!(actions || showAutoDismiss);\n\n const descriptionContent: ReactNode =\n description || hasActions ? (\n <Flex flow=\"row wrap\" gap=\"0.5x 1x\" placeItems=\"center stretch\">\n {description && <Block>{description}</Block>}\n {hasActions && (\n <ActionsSection\n actions={actions}\n theme={theme}\n showAutoDismiss={showAutoDismiss}\n hasDismissContext={hasDismissContext}\n notificationId={notificationId}\n onDismiss={onDismiss}\n />\n )}\n </Flex>\n ) : undefined;\n\n return (\n <StyledItem\n qa={qa}\n type=\"card\"\n theme={theme}\n icon={icon}\n description={descriptionContent}\n suffix={suffix}\n mods={{ flat: !elevated }}\n styles={!elevated ? { border: '0' } : undefined}\n >\n {title}\n </StyledItem>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAoBA,MAAM,aAAa,MAAMA,OAAM,EAC7B,QAAQ;CACN,OAAO;EACL,IAAI;EACJ,MAAM;EACP;CACD,QAAQ;EACN,IAAI;EACJ,MAAM;EACP;CACD,QAAQ;EACN,IAAI;EACJ,MAAM;EACP;CACD,YAAY;CAEZ,aAAa,EACX,QAAQ,MACT;CACF,EACF,CAAC;;;;;AAQF,SAAS,sBAAsB,EAAE,YAAqC;CACpE,MAAM,MAAM,OAAO,MAAM;AAGzB,KAAI,UAAU;AAEd,QACE,oBAAC,6BAA6B;EAAS,OAAO;EAC3C;GACqC;;;;;;;AAS5C,SAAS,oBAAoB;AAG3B,KAF2B,WAAW,6BAA6B,EAE3C,QAAS,QAAO;AAExC,QAAO,oBAAC;EAAmB;YAAU;GAA4B;;;;;;;;;;AA+BnE,SAAS,eAAe,EACtB,SACA,OACA,iBACA,mBACA,gBACA,aACsB;CACtB,MAAM,iBACJ,qBAAC;EAAM,WAAU;EAAM,cAAa;EAAM,UAAU;aACjD,SACA,mBAAmB,oBAAC,sBAAoB;GACnC;CAGV,MAAM,iBAAiB,kBACrB,oBAAC,mCAAuB,iBAAuC,GAE/D;AAGF,QACE,oBAAC;EAAmB,MAAK;EAAc;YACpC,oBACC,oBAAC;GACiB;GACL;aAEV;IAC2B,GAE9B;GAEiB;;;;;;AAyCzB,SAAgB,iBAAiB,EAC/B,KAAK,gBACL,OACA,OACA,aACA,MAAM,cACN,SACA,gBAAgB,MAChB,WAAW,MACX,gBACA,WACA,UACwB;CACxB,MAAM,OAAO,aAAa,OAAO,aAAa;CAE9C,MAAM,oBAAoB,kBAAkB,QAAQ,aAAa;CACjE,MAAM,kBAAkB,iBAAiB;CACzC,MAAM,aAAa,CAAC,EAAE,WAAW;AAmBjC,QACE,oBAAC;EACK;EACJ,MAAK;EACE;EACD;EACN,aAtBF,eAAe,aACb,qBAAC;GAAK,MAAK;GAAW,KAAI;GAAU,YAAW;cAC5C,eAAe,oBAAC,mBAAO,cAAoB,EAC3C,cACC,oBAAC;IACU;IACF;IACU;IACE;IACH;IACL;KACX;IAEC,GACL;EASM;EACR,MAAM,EAAE,MAAM,CAAC,UAAU;EACzB,QAAQ,CAAC,WAAW,EAAE,QAAQ,KAAK,GAAG;YAErC;GACU"}
1
+ {"version":3,"file":"NotificationCard.js","names":["Item"],"sources":["../../../../src/components/overlays/Notifications/NotificationCard.tsx"],"sourcesContent":["import { Key, ReactNode, useContext, useRef } from 'react';\n\nimport { tasty } from '../../../tasty';\nimport { ItemActionProvider } from '../../actions/ItemActionContext';\nimport { Block } from '../../Block';\nimport { Item } from '../../content/Item/Item';\nimport { Flex } from '../../layout/Flex';\nimport { Space } from '../../layout/Space';\nimport { getThemeIcon } from '../Toast/useToast';\n\nimport {\n DismissActionDetectedContext,\n NotificationAction,\n NotificationDismissProvider,\n} from './NotificationAction';\n\nimport type { DismissReason, NotificationType } from './types';\n\n// ─── Styled Components ──────────────────────────────────────────────\n\nconst StyledItem = tasty(Item, {\n styles: {\n width: {\n '': 'max min((100vw - 4x), 50x)',\n flat: '100%',\n },\n shadow: {\n '': '$shadow',\n flat: false,\n },\n radius: {\n '': '1cr',\n flat: '0',\n },\n transition: 'theme, inset',\n\n Description: {\n preset: 't4',\n },\n },\n});\n\n// ─── Dismiss Action Detection ────────────────────────────────────────\n\n/**\n * Provides a ref via context that NotificationAction children write to\n * during render when `isDismiss` is set. The ref is reset each render.\n */\nfunction DismissActionDetector({ children }: { children: ReactNode }) {\n const ref = useRef(false);\n\n // Reset each render so detection is fresh\n ref.current = false;\n\n return (\n <DismissActionDetectedContext.Provider value={ref}>\n {children}\n </DismissActionDetectedContext.Provider>\n );\n}\n\n/**\n * Renders the default \"Dismiss\" button only if no sibling NotificationAction\n * has `isDismiss` set. Reads from DismissActionDetectedContext ref which is\n * populated by actions that rendered before this component (left-to-right order).\n */\nfunction AutoDismissButton() {\n const dismissDetectedRef = useContext(DismissActionDetectedContext);\n\n if (dismissDetectedRef?.current) return null;\n\n return <NotificationAction isDismiss>Dismiss</NotificationAction>;\n}\n\n// ─── ActionsSection ─────────────────────────────────────────────────\n\ninterface ActionsSectionProps {\n actions?: ReactNode;\n theme?: NotificationType;\n /**\n * Whether to show the auto-appended \"Dismiss\" button.\n * Controlled by `isDismissible` on the notification.\n *\n * When false, no default \"Dismiss\" button is rendered, but actions with\n * `closeOnPress` (default `true`) can still close the notification via\n * the dismiss context.\n */\n showAutoDismiss: boolean;\n /** Whether the dismiss context is available (notificationId + onDismiss present) */\n hasDismissContext: boolean;\n notificationId?: Key;\n onDismiss?: (id: Key, reason: DismissReason) => void;\n onRestore?: (id: Key) => void;\n}\n\n/**\n * Extracted sub-component for the actions area of a notification card.\n *\n * The dismiss provider is always rendered when `hasDismissContext` is true,\n * so any action with `closeOnPress` can close the notification — regardless\n * of `isDismissible`. The `showAutoDismiss` flag only controls the\n * auto-appended \"Dismiss\" button.\n */\nfunction ActionsSection({\n actions,\n theme,\n showAutoDismiss,\n hasDismissContext,\n notificationId,\n onDismiss,\n onRestore,\n}: ActionsSectionProps) {\n const actionsContent = (\n <Space placeSelf=\"end\" placeContent=\"end\" flexGrow={1}>\n {actions}\n {showAutoDismiss && <AutoDismissButton />}\n </Space>\n );\n\n const wrappedContent = showAutoDismiss ? (\n <DismissActionDetector>{actionsContent}</DismissActionDetector>\n ) : (\n actionsContent\n );\n\n return (\n <ItemActionProvider type=\"card\" theme={theme}>\n {hasDismissContext ? (\n <NotificationDismissProvider\n notificationId={notificationId!}\n onDismiss={onDismiss!}\n onRestore={onRestore}\n >\n {wrappedContent}\n </NotificationDismissProvider>\n ) : (\n wrappedContent\n )}\n </ItemActionProvider>\n );\n}\n\n// ─── NotificationCard ────────────────────────────────────────────────\n\nexport interface NotificationCardProps {\n qa?: string;\n /** Notification theme */\n theme?: NotificationType;\n /** Primary text */\n title?: ReactNode;\n /** Secondary text */\n description?: ReactNode;\n /** Custom icon override (theme default used if omitted) */\n icon?: ReactNode;\n /** Action buttons rendered below description */\n actions?: ReactNode;\n /**\n * Whether the notification shows the default dismiss UI (auto-appended\n * \"Dismiss\" button and Escape key). Default: true.\n *\n * When false, no default \"Dismiss\" button is rendered and Escape does\n * nothing, but actions with `closeOnPress` (default) can still close\n * the notification.\n */\n isDismissible?: boolean;\n /** When false the card drops its shadow (e.g. inside a list). Default: true. */\n elevated?: boolean;\n /** Notification id */\n notificationId?: Key;\n /** Called when the notification is dismissed */\n onDismiss?: (id: Key, reason: DismissReason) => void;\n /** Called when a dismissed notification should be restored (async action returned false) */\n onRestore?: (id: Key) => void;\n /** Suffix content (e.g. timestamp) */\n suffix?: ReactNode;\n}\n\n/**\n * Shared presentational card used by both overlay NotificationItem\n * and PersistentNotificationListItem.\n */\nexport function NotificationCard({\n qa = 'Notification',\n theme,\n title,\n description,\n icon: providedIcon,\n actions,\n isDismissible = true,\n elevated = true,\n notificationId,\n onDismiss,\n onRestore,\n suffix,\n}: NotificationCardProps) {\n const icon = getThemeIcon(theme, providedIcon);\n\n const hasDismissContext = notificationId != null && onDismiss != null;\n const showAutoDismiss = isDismissible && hasDismissContext;\n const hasActions = !!(actions || showAutoDismiss);\n\n const descriptionContent: ReactNode =\n description || hasActions ? (\n <Flex flow=\"row wrap\" gap=\"0.5x 1x\" placeItems=\"center stretch\">\n {description && <Block>{description}</Block>}\n {hasActions && (\n <ActionsSection\n actions={actions}\n theme={theme}\n showAutoDismiss={showAutoDismiss}\n hasDismissContext={hasDismissContext}\n notificationId={notificationId}\n onDismiss={onDismiss}\n onRestore={onRestore}\n />\n )}\n </Flex>\n ) : undefined;\n\n return (\n <StyledItem\n qa={qa}\n type=\"card\"\n theme={theme}\n icon={icon}\n description={descriptionContent}\n suffix={suffix}\n mods={{ flat: !elevated }}\n styles={!elevated ? { border: '0' } : undefined}\n >\n {title}\n </StyledItem>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAoBA,MAAM,aAAa,MAAMA,OAAM,EAC7B,QAAQ;CACN,OAAO;EACL,IAAI;EACJ,MAAM;EACP;CACD,QAAQ;EACN,IAAI;EACJ,MAAM;EACP;CACD,QAAQ;EACN,IAAI;EACJ,MAAM;EACP;CACD,YAAY;CAEZ,aAAa,EACX,QAAQ,MACT;CACF,EACF,CAAC;;;;;AAQF,SAAS,sBAAsB,EAAE,YAAqC;CACpE,MAAM,MAAM,OAAO,MAAM;AAGzB,KAAI,UAAU;AAEd,QACE,oBAAC,6BAA6B;EAAS,OAAO;EAC3C;GACqC;;;;;;;AAS5C,SAAS,oBAAoB;AAG3B,KAF2B,WAAW,6BAA6B,EAE3C,QAAS,QAAO;AAExC,QAAO,oBAAC;EAAmB;YAAU;GAA4B;;;;;;;;;;AAgCnE,SAAS,eAAe,EACtB,SACA,OACA,iBACA,mBACA,gBACA,WACA,aACsB;CACtB,MAAM,iBACJ,qBAAC;EAAM,WAAU;EAAM,cAAa;EAAM,UAAU;aACjD,SACA,mBAAmB,oBAAC,sBAAoB;GACnC;CAGV,MAAM,iBAAiB,kBACrB,oBAAC,mCAAuB,iBAAuC,GAE/D;AAGF,QACE,oBAAC;EAAmB,MAAK;EAAc;YACpC,oBACC,oBAAC;GACiB;GACL;GACA;aAEV;IAC2B,GAE9B;GAEiB;;;;;;AA2CzB,SAAgB,iBAAiB,EAC/B,KAAK,gBACL,OACA,OACA,aACA,MAAM,cACN,SACA,gBAAgB,MAChB,WAAW,MACX,gBACA,WACA,WACA,UACwB;CACxB,MAAM,OAAO,aAAa,OAAO,aAAa;CAE9C,MAAM,oBAAoB,kBAAkB,QAAQ,aAAa;CACjE,MAAM,kBAAkB,iBAAiB;CACzC,MAAM,aAAa,CAAC,EAAE,WAAW;AAoBjC,QACE,oBAAC;EACK;EACJ,MAAK;EACE;EACD;EACN,aAvBF,eAAe,aACb,qBAAC;GAAK,MAAK;GAAW,KAAI;GAAU,YAAW;cAC5C,eAAe,oBAAC,mBAAO,cAAoB,EAC3C,cACC,oBAAC;IACU;IACF;IACU;IACE;IACH;IACL;IACA;KACX;IAEC,GACL;EASM;EACR,MAAM,EAAE,MAAM,CAAC,UAAU;EACzB,QAAQ,CAAC,WAAW,EAAE,QAAQ,KAAK,GAAG;YAErC;GACU"}
@@ -1,5 +1,7 @@
1
1
 
2
+ import "./types.js";
2
3
  import { ToastContextValue } from "../Toast/types.js";
4
+ import "react";
3
5
 
4
6
  //#region src/components/overlays/Notifications/NotificationContext.d.ts
5
7
  declare function useToastContext(): ToastContextValue;
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-b2f8ae7 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-26fe35d | Cube Dev Team */
2
2
  import { createContext, useContext } from "react";
3
3
 
4
4
  //#region src/components/overlays/Notifications/NotificationContext.ts
@@ -7,10 +7,12 @@ import * as react_jsx_runtime0 from "react/jsx-runtime";
7
7
  interface NotificationItemProps {
8
8
  notification: InternalNotification;
9
9
  onDismiss: (id: Key, reason: DismissReason) => void;
10
+ onRestore?: (id: Key) => void;
10
11
  }
11
12
  declare function NotificationItem({
12
13
  notification,
13
- onDismiss
14
+ onDismiss,
15
+ onRestore
14
16
  }: NotificationItemProps): react_jsx_runtime0.JSX.Element;
15
17
  //#endregion
16
18
  export { NotificationItem, NotificationItemProps };
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-b2f8ae7 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-26fe35d | Cube Dev Team */
2
2
  import { tasty } from "../../../tasty/tasty.js";
3
3
  import { useEvent } from "../../../_internal/hooks/use-event.js";
4
4
  import { NotificationCard } from "./NotificationCard.js";
@@ -34,7 +34,7 @@ const NotificationItemWrapper = tasty({
34
34
  "aria-relevant": "additions text",
35
35
  styles: { outline: { "": "none" } }
36
36
  });
37
- function NotificationItem({ notification, onDismiss }) {
37
+ function NotificationItem({ notification, onDismiss, onRestore }) {
38
38
  const { theme, title, description, icon, actions, isDismissible = true, id, internalId } = notification;
39
39
  const notificationId = id ?? internalId;
40
40
  const handleKeyDown = useEvent((e) => {
@@ -56,7 +56,8 @@ function NotificationItem({ notification, onDismiss }) {
56
56
  actions,
57
57
  isDismissible,
58
58
  notificationId,
59
- onDismiss
59
+ onDismiss,
60
+ onRestore
60
61
  })
61
62
  });
62
63
  }
@@ -1 +1 @@
1
- {"version":3,"file":"NotificationItem.js","names":[],"sources":["../../../../src/components/overlays/Notifications/NotificationItem.tsx"],"sourcesContent":["import { Key, KeyboardEvent } from 'react';\n\nimport { useEvent } from '../../../_internal';\nimport { tasty } from '../../../tasty';\n\nimport { NotificationCard } from './NotificationCard';\n\nimport type {\n DismissReason,\n InternalNotification,\n NotificationType,\n} from './types';\n\n// ─── ARIA Helpers ────────────────────────────────────────────────────\n\nfunction getAriaRole(theme?: NotificationType): 'alert' | 'status' {\n if (theme === 'danger' || theme === 'warning') {\n return 'alert';\n }\n\n return 'status';\n}\n\nfunction getAriaLive(theme?: NotificationType): 'assertive' | 'polite' {\n if (theme === 'danger' || theme === 'warning') {\n return 'assertive';\n }\n\n return 'polite';\n}\n\n// ─── Styled Wrapper ──────────────────────────────────────────────────\n\n/**\n * Wrapper element for overlay notification items.\n *\n * Accessibility attributes are set as static defaults:\n * - `tabIndex={0}`: Makes the notification focusable via keyboard, allowing\n * users to Tab to it and press Escape to dismiss.\n * - `aria-atomic=\"true\"`: Ensures screen readers announce the entire notification\n * when content changes (not just the diff).\n * - `aria-relevant=\"additions text\"`: Announces when new content is added or\n * text changes, but not when elements are removed (e.g., during exit animation).\n *\n * The `role` and `aria-live` are set dynamically per-instance based on theme\n * (see `getAriaRole` and `getAriaLive` above).\n */\nconst NotificationItemWrapper = tasty({\n as: 'div',\n tabIndex: 0,\n 'aria-atomic': 'true',\n 'aria-relevant': 'additions text',\n styles: {\n outline: {\n '': 'none',\n },\n },\n});\n\n// ─── NotificationItem Component ─────────────────────────────────────\n\nexport interface NotificationItemProps {\n notification: InternalNotification;\n onDismiss: (id: Key, reason: DismissReason) => void;\n}\n\nexport function NotificationItem({\n notification,\n onDismiss,\n}: NotificationItemProps) {\n const {\n theme,\n title,\n description,\n icon,\n actions,\n isDismissible = true,\n id,\n internalId,\n } = notification;\n\n const notificationId = id ?? internalId;\n\n const handleKeyDown = useEvent((e: KeyboardEvent) => {\n if (e.key === 'Escape' && isDismissible) {\n e.stopPropagation();\n onDismiss(notificationId, 'close');\n }\n });\n\n return (\n <NotificationItemWrapper\n role={getAriaRole(theme)}\n aria-live={getAriaLive(theme)}\n onKeyDown={handleKeyDown}\n >\n <NotificationCard\n qa=\"Notification\"\n theme={theme}\n title={title}\n description={description}\n icon={icon}\n actions={actions}\n isDismissible={isDismissible}\n notificationId={notificationId}\n onDismiss={onDismiss}\n />\n </NotificationItemWrapper>\n );\n}\n"],"mappings":";;;;;;;AAeA,SAAS,YAAY,OAA8C;AACjE,KAAI,UAAU,YAAY,UAAU,UAClC,QAAO;AAGT,QAAO;;AAGT,SAAS,YAAY,OAAkD;AACrE,KAAI,UAAU,YAAY,UAAU,UAClC,QAAO;AAGT,QAAO;;;;;;;;;;;;;;;;AAmBT,MAAM,0BAA0B,MAAM;CACpC,IAAI;CACJ,UAAU;CACV,eAAe;CACf,iBAAiB;CACjB,QAAQ,EACN,SAAS,EACP,IAAI,QACL,EACF;CACF,CAAC;AASF,SAAgB,iBAAiB,EAC/B,cACA,aACwB;CACxB,MAAM,EACJ,OACA,OACA,aACA,MACA,SACA,gBAAgB,MAChB,IACA,eACE;CAEJ,MAAM,iBAAiB,MAAM;CAE7B,MAAM,gBAAgB,UAAU,MAAqB;AACnD,MAAI,EAAE,QAAQ,YAAY,eAAe;AACvC,KAAE,iBAAiB;AACnB,aAAU,gBAAgB,QAAQ;;GAEpC;AAEF,QACE,oBAAC;EACC,MAAM,YAAY,MAAM;EACxB,aAAW,YAAY,MAAM;EAC7B,WAAW;YAEX,oBAAC;GACC,IAAG;GACI;GACA;GACM;GACP;GACG;GACM;GACC;GACL;IACX;GACsB"}
1
+ {"version":3,"file":"NotificationItem.js","names":[],"sources":["../../../../src/components/overlays/Notifications/NotificationItem.tsx"],"sourcesContent":["import { Key, KeyboardEvent } from 'react';\n\nimport { useEvent } from '../../../_internal';\nimport { tasty } from '../../../tasty';\n\nimport { NotificationCard } from './NotificationCard';\n\nimport type {\n DismissReason,\n InternalNotification,\n NotificationType,\n} from './types';\n\n// ─── ARIA Helpers ────────────────────────────────────────────────────\n\nfunction getAriaRole(theme?: NotificationType): 'alert' | 'status' {\n if (theme === 'danger' || theme === 'warning') {\n return 'alert';\n }\n\n return 'status';\n}\n\nfunction getAriaLive(theme?: NotificationType): 'assertive' | 'polite' {\n if (theme === 'danger' || theme === 'warning') {\n return 'assertive';\n }\n\n return 'polite';\n}\n\n// ─── Styled Wrapper ──────────────────────────────────────────────────\n\n/**\n * Wrapper element for overlay notification items.\n *\n * Accessibility attributes are set as static defaults:\n * - `tabIndex={0}`: Makes the notification focusable via keyboard, allowing\n * users to Tab to it and press Escape to dismiss.\n * - `aria-atomic=\"true\"`: Ensures screen readers announce the entire notification\n * when content changes (not just the diff).\n * - `aria-relevant=\"additions text\"`: Announces when new content is added or\n * text changes, but not when elements are removed (e.g., during exit animation).\n *\n * The `role` and `aria-live` are set dynamically per-instance based on theme\n * (see `getAriaRole` and `getAriaLive` above).\n */\nconst NotificationItemWrapper = tasty({\n as: 'div',\n tabIndex: 0,\n 'aria-atomic': 'true',\n 'aria-relevant': 'additions text',\n styles: {\n outline: {\n '': 'none',\n },\n },\n});\n\n// ─── NotificationItem Component ─────────────────────────────────────\n\nexport interface NotificationItemProps {\n notification: InternalNotification;\n onDismiss: (id: Key, reason: DismissReason) => void;\n onRestore?: (id: Key) => void;\n}\n\nexport function NotificationItem({\n notification,\n onDismiss,\n onRestore,\n}: NotificationItemProps) {\n const {\n theme,\n title,\n description,\n icon,\n actions,\n isDismissible = true,\n id,\n internalId,\n } = notification;\n\n const notificationId = id ?? internalId;\n\n const handleKeyDown = useEvent((e: KeyboardEvent) => {\n if (e.key === 'Escape' && isDismissible) {\n e.stopPropagation();\n onDismiss(notificationId, 'close');\n }\n });\n\n return (\n <NotificationItemWrapper\n role={getAriaRole(theme)}\n aria-live={getAriaLive(theme)}\n onKeyDown={handleKeyDown}\n >\n <NotificationCard\n qa=\"Notification\"\n theme={theme}\n title={title}\n description={description}\n icon={icon}\n actions={actions}\n isDismissible={isDismissible}\n notificationId={notificationId}\n onDismiss={onDismiss}\n onRestore={onRestore}\n />\n </NotificationItemWrapper>\n );\n}\n"],"mappings":";;;;;;;AAeA,SAAS,YAAY,OAA8C;AACjE,KAAI,UAAU,YAAY,UAAU,UAClC,QAAO;AAGT,QAAO;;AAGT,SAAS,YAAY,OAAkD;AACrE,KAAI,UAAU,YAAY,UAAU,UAClC,QAAO;AAGT,QAAO;;;;;;;;;;;;;;;;AAmBT,MAAM,0BAA0B,MAAM;CACpC,IAAI;CACJ,UAAU;CACV,eAAe;CACf,iBAAiB;CACjB,QAAQ,EACN,SAAS,EACP,IAAI,QACL,EACF;CACF,CAAC;AAUF,SAAgB,iBAAiB,EAC/B,cACA,WACA,aACwB;CACxB,MAAM,EACJ,OACA,OACA,aACA,MACA,SACA,gBAAgB,MAChB,IACA,eACE;CAEJ,MAAM,iBAAiB,MAAM;CAE7B,MAAM,gBAAgB,UAAU,MAAqB;AACnD,MAAI,EAAE,QAAQ,YAAY,eAAe;AACvC,KAAE,iBAAiB;AACnB,aAAU,gBAAgB,QAAQ;;GAEpC;AAEF,QACE,oBAAC;EACC,MAAM,YAAY,MAAM;EACxB,aAAW,YAAY,MAAM;EAC7B,WAAW;YAEX,oBAAC;GACC,IAAG;GACI;GACA;GACM;GACP;GACG;GACM;GACC;GACL;GACA;IACX;GACsB"}
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-b2f8ae7 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-26fe35d | Cube Dev Team */
2
2
  import { tasty } from "../../../tasty/tasty.js";
3
3
  import { useLayoutEffect as useLayoutEffect$1 } from "../../../utils/react/useLayoutEffect.js";
4
4
  import { useEvent } from "../../../_internal/hooks/use-event.js";
@@ -19,7 +19,7 @@ const OverlayContainerElement = tasty({ styles: {
19
19
  top: "2x",
20
20
  left: "50%",
21
21
  transform: "translateX(-50%)",
22
- zIndex: 1e4,
22
+ zIndex: 100,
23
23
  padding: "1x",
24
24
  height: "0",
25
25
  pointerEvents: "none"
@@ -208,7 +208,7 @@ function useCollapseState(canCollapse, allItems, itemRefs, onPauseChange) {
208
208
  containerRef
209
209
  };
210
210
  }
211
- function OverlayContainer({ toasts, notifications, onToastExitComplete, onNotificationExitComplete, onNotificationDismiss, onPauseChange }) {
211
+ function OverlayContainer({ toasts, notifications, onToastExitComplete, onNotificationExitComplete, onNotificationDismiss, onNotificationRestore, onPauseChange }) {
212
212
  const allItems = useMemo(() => {
213
213
  const items = [...toasts.map((t) => ({
214
214
  kind: "toast",
@@ -295,7 +295,8 @@ function OverlayContainer({ toasts, notifications, onToastExitComplete, onNotifi
295
295
  actions: item.data.actions
296
296
  }) : /* @__PURE__ */ jsx(NotificationItem, {
297
297
  notification: item.data,
298
- onDismiss: handleNotificationDismiss
298
+ onDismiss: handleNotificationDismiss,
299
+ onRestore: onNotificationRestore
299
300
  })
300
301
  })
301
302
  }, itemId);
@@ -1 +1 @@
1
- {"version":3,"file":"OverlayContainer.js","names":[],"sources":["../../../../src/components/overlays/Notifications/OverlayContainer.tsx"],"sourcesContent":["import {\n FocusEvent,\n Key,\n RefObject,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport { useEvent } from '../../../_internal';\nimport { tasty } from '../../../tasty';\nimport { useLayoutEffect } from '../../../utils/react/useLayoutEffect';\nimport { DisplayTransition } from '../../helpers/DisplayTransition/DisplayTransition';\nimport { Portal } from '../../portal';\nimport { ToastItem } from '../Toast/ToastItem';\n\nimport { NotificationItem } from './NotificationItem';\n\nimport type { InternalToast } from '../Toast/types';\nimport type { DismissReason, InternalNotification } from './types';\n\n// ─── Constants ───────────────────────────────────────────────────────\n\nconst COLLAPSE_VISIBLE_HEIGHT = 10;\nconst CONTAINER_OFFSET = 16;\nconst ITEM_GAP = 8;\nconst DEFAULT_ITEM_HEIGHT = 56;\n\n// ─── Styled Elements ─────────────────────────────────────────────────\n\nconst OverlayContainerElement = tasty({\n styles: {\n position: 'fixed',\n top: '2x',\n left: '50%',\n transform: 'translateX(-50%)',\n zIndex: 10000,\n padding: '1x',\n height: '0',\n pointerEvents: 'none',\n },\n});\n\nconst OverlayItemWrapper = tasty({\n styles: {\n position: 'absolute',\n top: '0',\n left: '50%',\n transform: {\n '': 'translateX(-50%) translateY(-50%)',\n 'isMeasured & isShown': 'translateX(-50%) translateY(0)',\n },\n width: 'max-content 50x',\n pointerEvents: 'auto',\n transition: {\n '': 'opacity $transition ease-in, transform $transition ease-in',\n isMeasured:\n 'top $transition ease-in, opacity $transition ease-in, transform $transition ease-in',\n },\n opacity: {\n '': 0,\n isShown: 1,\n },\n },\n});\n\n// ─── Unified Item Type ───────────────────────────────────────────────\n\ntype OverlayItem =\n | { kind: 'toast'; data: InternalToast }\n | { kind: 'notification'; data: InternalNotification };\n\nfunction getItemId(item: OverlayItem): string {\n return item.data.internalId;\n}\n\nfunction isItemExiting(item: OverlayItem): boolean {\n return item.data.isExiting === true;\n}\n\nfunction getItemCreatedAt(item: OverlayItem): number {\n return item.data.createdAt;\n}\n\n// ─── useItemPositions Hook ───────────────────────────────────────────\n\ninterface ItemPositionsResult {\n heights: Record<string, number>;\n /** Set of item IDs that have been measured AND painted at their correct position. */\n settledIds: Set<string>;\n positions: Map<string, number>;\n lastPositionsRef: ReturnType<typeof useRef<Map<string, number>>>;\n itemRefs: ReturnType<typeof useRef<Map<string, HTMLDivElement>>>;\n createRefCallback: (\n itemId: string,\n displayRef: (el: HTMLElement | null) => void,\n ) => (el: HTMLDivElement | null) => void;\n}\n\n/**\n * Manages height measurement, position calculation, and ref tracking\n * for overlay items. Extracted from OverlayContainer for readability.\n */\nfunction useItemPositions(visibleItems: OverlayItem[]): ItemPositionsResult {\n const [heights, setHeights] = useState<Record<string, number>>({});\n const itemRefs = useRef<Map<string, HTMLDivElement>>(new Map());\n const lastPositionsRef = useRef<Map<string, number>>(new Map());\n\n // Items that have been measured AND painted at their correct position.\n // Lags one frame behind `heights` so the browser paints the item at\n // its final `top` before the CSS `top` transition is enabled.\n const [settledIds, setSettledIds] = useState<Set<string>>(new Set());\n const rafRef = useRef<number | null>(null);\n\n // Measure heights using layout effect to avoid visible layout shifts.\n // Runs every render but bails early if nothing changed.\n useLayoutEffect(() => {\n const newHeights: Record<string, number> = {};\n let hasChanges = false;\n\n itemRefs.current.forEach((el, id) => {\n const height = el.offsetHeight || DEFAULT_ITEM_HEIGHT;\n newHeights[id] = height;\n\n if (heights[id] !== height) {\n hasChanges = true;\n }\n });\n\n for (const id of Object.keys(heights)) {\n if (!itemRefs.current.has(id)) {\n hasChanges = true;\n }\n }\n\n if (hasChanges) {\n setHeights(newHeights);\n }\n });\n\n // After heights change, schedule settledIds update for the next frame.\n // This ensures the item is painted at its correct position (with no top\n // transition) before we enable the transition.\n useEffect(() => {\n const heightKeys = Object.keys(heights);\n const newIds = heightKeys.filter((id) => !settledIds.has(id));\n const hasStaleIds =\n settledIds.size > 0 && [...settledIds].some((id) => !(id in heights));\n\n if (newIds.length === 0 && !hasStaleIds) return;\n\n if (rafRef.current != null) {\n cancelAnimationFrame(rafRef.current);\n }\n\n // For pruning-only updates (no new items), apply synchronously since\n // there's no need to wait for a paint frame.\n if (newIds.length === 0 && hasStaleIds) {\n setSettledIds((prev) => new Set(heightKeys.filter((id) => prev.has(id))));\n return;\n }\n\n rafRef.current = requestAnimationFrame(() => {\n rafRef.current = null;\n setSettledIds((prev) => {\n const next = new Set<string>();\n\n // Only keep IDs that still exist in heights (prune removed items)\n for (const id of heightKeys) {\n if (prev.has(id)) {\n next.add(id);\n }\n }\n\n for (const id of newIds) {\n next.add(id);\n }\n\n return next;\n });\n });\n\n return () => {\n if (rafRef.current != null) {\n cancelAnimationFrame(rafRef.current);\n rafRef.current = null;\n }\n };\n }, [heights]);\n\n const createRefCallback = useCallback(\n (itemId: string, displayRef: (el: HTMLElement | null) => void) =>\n (el: HTMLDivElement | null) => {\n displayRef(el);\n\n if (el) {\n itemRefs.current.set(itemId, el);\n } else {\n itemRefs.current.delete(itemId);\n }\n },\n [],\n );\n\n const positions = useMemo(() => {\n const posMap = new Map<string, number>();\n let currentTop = 0;\n\n for (const item of visibleItems) {\n const id = getItemId(item);\n posMap.set(id, currentTop);\n const height = heights[id] ?? DEFAULT_ITEM_HEIGHT;\n currentTop += height + ITEM_GAP;\n }\n\n return posMap;\n }, [visibleItems, heights]);\n\n useEffect(() => {\n positions.forEach((pos, id) => {\n lastPositionsRef.current.set(id, pos);\n });\n }, [positions]);\n\n return {\n heights,\n settledIds,\n positions,\n lastPositionsRef,\n itemRefs,\n createRefCallback,\n };\n}\n\n// ─── useCollapseState Hook ───────────────────────────────────────────\n\ninterface CollapseStateResult {\n isCollapsed: boolean;\n handleMouseEnter: () => void;\n handleMouseLeave: () => void;\n handleFocus: () => void;\n handleBlur: (e: FocusEvent) => void;\n containerRef: RefObject<HTMLDivElement | null>;\n}\n\n/**\n * Manages collapse/expand behavior and pause state for the overlay container.\n * Extracted from OverlayContainer for readability.\n */\nfunction useCollapseState(\n canCollapse: boolean,\n allItems: OverlayItem[],\n itemRefs: ReturnType<typeof useRef<Map<string, HTMLDivElement>>>,\n onPauseChange: (paused: boolean) => void,\n): CollapseStateResult {\n const [isCollapsed, setIsCollapsed] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n const boundsRef = useRef<DOMRect | null>(null);\n\n const updateBounds = useCallback(() => {\n const refs = itemRefs.current;\n\n if (!refs || refs.size === 0) {\n boundsRef.current = null;\n return;\n }\n\n let minX = Infinity,\n minY = Infinity,\n maxX = -Infinity,\n maxY = -Infinity;\n\n refs.forEach((el) => {\n const rect = el.getBoundingClientRect();\n minX = Math.min(minX, rect.left);\n minY = Math.min(minY, rect.top);\n maxX = Math.max(maxX, rect.right);\n maxY = Math.max(maxY, rect.bottom);\n });\n\n if (typeof DOMRect !== 'undefined') {\n boundsRef.current = new DOMRect(minX, minY, maxX - minX, maxY - minY);\n } else {\n boundsRef.current = {\n x: minX,\n y: minY,\n width: maxX - minX,\n height: maxY - minY,\n top: minY,\n right: maxX,\n bottom: maxY,\n left: minX,\n toJSON: () => ({}),\n } as DOMRect;\n }\n }, [itemRefs]);\n\n // Track mouse for collapse — expand when mouse leaves bounds\n useEffect(() => {\n if (!isCollapsed) return;\n\n const handleMouseMove = (e: MouseEvent) => {\n const bounds = boundsRef.current;\n\n if (!bounds) {\n setIsCollapsed(false);\n onPauseChange(false);\n return;\n }\n\n const padding = 20;\n const isInBounds =\n e.clientX >= bounds.left - padding &&\n e.clientX <= bounds.right + padding &&\n e.clientY >= bounds.top - padding &&\n e.clientY <= bounds.bottom + padding;\n\n if (!isInBounds) {\n setIsCollapsed(false);\n onPauseChange(false);\n }\n };\n\n window.addEventListener('mousemove', handleMouseMove);\n return () => window.removeEventListener('mousemove', handleMouseMove);\n }, [isCollapsed, onPauseChange]);\n\n // Update bounds when items change\n useEffect(() => {\n updateBounds();\n }, [allItems, updateBounds]);\n\n const handleMouseEnter = useCallback(() => {\n updateBounds();\n onPauseChange(true);\n\n if (canCollapse) {\n setIsCollapsed(true);\n }\n }, [updateBounds, canCollapse, onPauseChange]);\n\n const handleMouseLeave = useCallback(() => {\n if (!isCollapsed) {\n onPauseChange(false);\n }\n }, [isCollapsed, onPauseChange]);\n\n const handleFocus = useCallback(() => {\n onPauseChange(true);\n }, [onPauseChange]);\n\n const handleBlur = useCallback(\n (e: FocusEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(e.relatedTarget as Node)\n ) {\n onPauseChange(false);\n }\n },\n [onPauseChange],\n );\n\n return {\n isCollapsed,\n handleMouseEnter,\n handleMouseLeave,\n handleFocus,\n handleBlur,\n containerRef,\n };\n}\n\n// ─── Overlay Container ───────────────────────────────────────────────\n//\n// INTENTIONAL: Position calculations are done manually (absolute positioning + JS\n// height tracking) rather than relying on CSS flexbox/grid layout. This is\n// deliberate — the container mixes enter/exit animations, collapse behavior, and\n// heterogeneous item sizes (toasts vs notifications) which require per-item\n// position control. CSS-only solutions (e.g., flex column with gap) break when\n// items exit asynchronously or when collapse transforms need to be computed per-item.\n\nexport interface OverlayContainerProps {\n toasts: InternalToast[];\n notifications: InternalNotification[];\n onToastExitComplete: (internalId: string) => void;\n onNotificationExitComplete: (internalId: string) => void;\n onNotificationDismiss: (id: Key, reason: DismissReason) => void;\n onPauseChange: (paused: boolean) => void;\n}\n\nexport function OverlayContainer({\n toasts,\n notifications,\n onToastExitComplete,\n onNotificationExitComplete,\n onNotificationDismiss,\n onPauseChange,\n}: OverlayContainerProps) {\n // Merge toasts and notifications into a single ordered list\n const allItems: OverlayItem[] = useMemo(() => {\n const items: OverlayItem[] = [\n ...toasts.map((t): OverlayItem => ({ kind: 'toast', data: t })),\n ...notifications.map(\n (n): OverlayItem => ({ kind: 'notification', data: n }),\n ),\n ];\n\n // Sort by createdAt ascending (oldest first = bottom of stack, newest last = top)\n items.sort((a, b) => getItemCreatedAt(a) - getItemCreatedAt(b));\n\n return items;\n }, [toasts, notifications]);\n\n const visibleItems = useMemo(\n () => allItems.filter((item) => !isItemExiting(item)),\n [allItems],\n );\n const hasNotifications = notifications.some((n) => !n.isExiting);\n const hasActionableToasts = toasts.some((t) => !t.isExiting && t.actions);\n const canCollapse = !hasNotifications && !hasActionableToasts;\n\n const {\n heights,\n settledIds,\n positions,\n lastPositionsRef,\n itemRefs,\n createRefCallback,\n } = useItemPositions(visibleItems);\n\n const {\n isCollapsed,\n handleMouseEnter,\n handleMouseLeave,\n handleFocus,\n handleBlur,\n containerRef,\n } = useCollapseState(canCollapse, allItems, itemRefs, onPauseChange);\n\n // ─── Callbacks ─────────────────────────────────────────────────────\n\n // When the user dismisses a notification they were hovering, the element\n // is removed from the DOM so mouseLeave never fires. Explicitly unpause\n // so remaining notifications' timers resume.\n const handleNotificationDismiss = useEvent(\n (id: Key, reason: DismissReason) => {\n onNotificationDismiss(id, reason);\n onPauseChange(false);\n },\n );\n\n const handleExitComplete = useEvent((item: OverlayItem) => {\n const id = getItemId(item);\n lastPositionsRef.current?.delete(id);\n\n if (item.kind === 'toast') {\n onToastExitComplete(item.data.internalId);\n } else {\n onNotificationExitComplete(item.data.internalId);\n }\n });\n\n // useCallback (not useEvent) because this is called during render.\n // useEvent defers the ref update to useLayoutEffect, so during render\n // it would still read the previous closure's positions/heights.\n const getItemStyle = useCallback(\n (item: OverlayItem, index: number, total: number) => {\n const id = getItemId(item);\n const baseTop =\n positions.get(id) ?? lastPositionsRef.current?.get(id) ?? 0;\n const height = heights[id] ?? DEFAULT_ITEM_HEIGHT;\n\n if (!isCollapsed || !canCollapse) {\n return { top: `${baseTop}px` };\n }\n\n const isNewest = index === total - 1;\n const collapsedTop = COLLAPSE_VISIBLE_HEIGHT - CONTAINER_OFFSET - height;\n\n return {\n top: `${collapsedTop}px`,\n zIndex: index,\n opacity: isNewest ? 1 : 0,\n pointerEvents: 'none' as const,\n };\n },\n [isCollapsed, canCollapse, positions, heights, lastPositionsRef],\n );\n\n // Build a visibleIndex lookup map to avoid O(n²) findIndex inside render loop\n const visibleIndexMap = useMemo(() => {\n const map = new Map<string, number>();\n\n visibleItems.forEach((item, index) => {\n map.set(getItemId(item), index);\n });\n\n return map;\n }, [visibleItems]);\n\n if (allItems.length === 0) return null;\n\n return (\n <Portal>\n <OverlayContainerElement\n ref={containerRef}\n onFocus={handleFocus}\n onBlur={handleBlur}\n >\n {allItems.map((item) => {\n const itemId = getItemId(item);\n const visibleIndex = visibleIndexMap.get(itemId) ?? 0;\n const isExiting = isItemExiting(item);\n\n return (\n <DisplayTransition\n key={itemId}\n animateOnMount\n isShown={!isExiting}\n onRest={(transition) => {\n if (transition === 'exit') {\n handleExitComplete(item);\n }\n }}\n >\n {({ isShown, ref }) => (\n <OverlayItemWrapper\n ref={createRefCallback(itemId, ref)}\n mods={{ isShown, isMeasured: settledIds.has(itemId) }}\n style={getItemStyle(item, visibleIndex, visibleItems.length)}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n {item.kind === 'toast' ? (\n <ToastItem\n {...item.data.itemProps}\n title={item.data.title}\n description={item.data.description}\n theme={item.data.theme}\n icon={item.data.icon}\n isLoading={item.data.isLoading}\n actions={item.data.actions}\n />\n ) : (\n <NotificationItem\n notification={item.data}\n onDismiss={handleNotificationDismiss}\n />\n )}\n </OverlayItemWrapper>\n )}\n </DisplayTransition>\n );\n })}\n </OverlayContainerElement>\n </Portal>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"OverlayContainer.js","names":[],"sources":["../../../../src/components/overlays/Notifications/OverlayContainer.tsx"],"sourcesContent":["import {\n FocusEvent,\n Key,\n RefObject,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport { useEvent } from '../../../_internal';\nimport { tasty } from '../../../tasty';\nimport { useLayoutEffect } from '../../../utils/react/useLayoutEffect';\nimport { DisplayTransition } from '../../helpers/DisplayTransition/DisplayTransition';\nimport { Portal } from '../../portal';\nimport { ToastItem } from '../Toast/ToastItem';\n\nimport { NotificationItem } from './NotificationItem';\n\nimport type { InternalToast } from '../Toast/types';\nimport type { DismissReason, InternalNotification } from './types';\n\n// ─── Constants ───────────────────────────────────────────────────────\n\nconst COLLAPSE_VISIBLE_HEIGHT = 10;\nconst CONTAINER_OFFSET = 16;\nconst ITEM_GAP = 8;\nconst DEFAULT_ITEM_HEIGHT = 56;\n\n// ─── Styled Elements ─────────────────────────────────────────────────\n\nconst OverlayContainerElement = tasty({\n styles: {\n position: 'fixed',\n top: '2x',\n left: '50%',\n transform: 'translateX(-50%)',\n zIndex: 100,\n padding: '1x',\n height: '0',\n pointerEvents: 'none',\n },\n});\n\nconst OverlayItemWrapper = tasty({\n styles: {\n position: 'absolute',\n top: '0',\n left: '50%',\n transform: {\n '': 'translateX(-50%) translateY(-50%)',\n 'isMeasured & isShown': 'translateX(-50%) translateY(0)',\n },\n width: 'max-content 50x',\n pointerEvents: 'auto',\n transition: {\n '': 'opacity $transition ease-in, transform $transition ease-in',\n isMeasured:\n 'top $transition ease-in, opacity $transition ease-in, transform $transition ease-in',\n },\n opacity: {\n '': 0,\n isShown: 1,\n },\n },\n});\n\n// ─── Unified Item Type ───────────────────────────────────────────────\n\ntype OverlayItem =\n | { kind: 'toast'; data: InternalToast }\n | { kind: 'notification'; data: InternalNotification };\n\nfunction getItemId(item: OverlayItem): string {\n return item.data.internalId;\n}\n\nfunction isItemExiting(item: OverlayItem): boolean {\n return item.data.isExiting === true;\n}\n\nfunction getItemCreatedAt(item: OverlayItem): number {\n return item.data.createdAt;\n}\n\n// ─── useItemPositions Hook ───────────────────────────────────────────\n\ninterface ItemPositionsResult {\n heights: Record<string, number>;\n /** Set of item IDs that have been measured AND painted at their correct position. */\n settledIds: Set<string>;\n positions: Map<string, number>;\n lastPositionsRef: ReturnType<typeof useRef<Map<string, number>>>;\n itemRefs: ReturnType<typeof useRef<Map<string, HTMLDivElement>>>;\n createRefCallback: (\n itemId: string,\n displayRef: (el: HTMLElement | null) => void,\n ) => (el: HTMLDivElement | null) => void;\n}\n\n/**\n * Manages height measurement, position calculation, and ref tracking\n * for overlay items. Extracted from OverlayContainer for readability.\n */\nfunction useItemPositions(visibleItems: OverlayItem[]): ItemPositionsResult {\n const [heights, setHeights] = useState<Record<string, number>>({});\n const itemRefs = useRef<Map<string, HTMLDivElement>>(new Map());\n const lastPositionsRef = useRef<Map<string, number>>(new Map());\n\n // Items that have been measured AND painted at their correct position.\n // Lags one frame behind `heights` so the browser paints the item at\n // its final `top` before the CSS `top` transition is enabled.\n const [settledIds, setSettledIds] = useState<Set<string>>(new Set());\n const rafRef = useRef<number | null>(null);\n\n // Measure heights using layout effect to avoid visible layout shifts.\n // Runs every render but bails early if nothing changed.\n useLayoutEffect(() => {\n const newHeights: Record<string, number> = {};\n let hasChanges = false;\n\n itemRefs.current.forEach((el, id) => {\n const height = el.offsetHeight || DEFAULT_ITEM_HEIGHT;\n newHeights[id] = height;\n\n if (heights[id] !== height) {\n hasChanges = true;\n }\n });\n\n for (const id of Object.keys(heights)) {\n if (!itemRefs.current.has(id)) {\n hasChanges = true;\n }\n }\n\n if (hasChanges) {\n setHeights(newHeights);\n }\n });\n\n // After heights change, schedule settledIds update for the next frame.\n // This ensures the item is painted at its correct position (with no top\n // transition) before we enable the transition.\n useEffect(() => {\n const heightKeys = Object.keys(heights);\n const newIds = heightKeys.filter((id) => !settledIds.has(id));\n const hasStaleIds =\n settledIds.size > 0 && [...settledIds].some((id) => !(id in heights));\n\n if (newIds.length === 0 && !hasStaleIds) return;\n\n if (rafRef.current != null) {\n cancelAnimationFrame(rafRef.current);\n }\n\n // For pruning-only updates (no new items), apply synchronously since\n // there's no need to wait for a paint frame.\n if (newIds.length === 0 && hasStaleIds) {\n setSettledIds((prev) => new Set(heightKeys.filter((id) => prev.has(id))));\n return;\n }\n\n rafRef.current = requestAnimationFrame(() => {\n rafRef.current = null;\n setSettledIds((prev) => {\n const next = new Set<string>();\n\n // Only keep IDs that still exist in heights (prune removed items)\n for (const id of heightKeys) {\n if (prev.has(id)) {\n next.add(id);\n }\n }\n\n for (const id of newIds) {\n next.add(id);\n }\n\n return next;\n });\n });\n\n return () => {\n if (rafRef.current != null) {\n cancelAnimationFrame(rafRef.current);\n rafRef.current = null;\n }\n };\n }, [heights]);\n\n const createRefCallback = useCallback(\n (itemId: string, displayRef: (el: HTMLElement | null) => void) =>\n (el: HTMLDivElement | null) => {\n displayRef(el);\n\n if (el) {\n itemRefs.current.set(itemId, el);\n } else {\n itemRefs.current.delete(itemId);\n }\n },\n [],\n );\n\n const positions = useMemo(() => {\n const posMap = new Map<string, number>();\n let currentTop = 0;\n\n for (const item of visibleItems) {\n const id = getItemId(item);\n posMap.set(id, currentTop);\n const height = heights[id] ?? DEFAULT_ITEM_HEIGHT;\n currentTop += height + ITEM_GAP;\n }\n\n return posMap;\n }, [visibleItems, heights]);\n\n useEffect(() => {\n positions.forEach((pos, id) => {\n lastPositionsRef.current.set(id, pos);\n });\n }, [positions]);\n\n return {\n heights,\n settledIds,\n positions,\n lastPositionsRef,\n itemRefs,\n createRefCallback,\n };\n}\n\n// ─── useCollapseState Hook ───────────────────────────────────────────\n\ninterface CollapseStateResult {\n isCollapsed: boolean;\n handleMouseEnter: () => void;\n handleMouseLeave: () => void;\n handleFocus: () => void;\n handleBlur: (e: FocusEvent) => void;\n containerRef: RefObject<HTMLDivElement | null>;\n}\n\n/**\n * Manages collapse/expand behavior and pause state for the overlay container.\n * Extracted from OverlayContainer for readability.\n */\nfunction useCollapseState(\n canCollapse: boolean,\n allItems: OverlayItem[],\n itemRefs: ReturnType<typeof useRef<Map<string, HTMLDivElement>>>,\n onPauseChange: (paused: boolean) => void,\n): CollapseStateResult {\n const [isCollapsed, setIsCollapsed] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n const boundsRef = useRef<DOMRect | null>(null);\n\n const updateBounds = useCallback(() => {\n const refs = itemRefs.current;\n\n if (!refs || refs.size === 0) {\n boundsRef.current = null;\n return;\n }\n\n let minX = Infinity,\n minY = Infinity,\n maxX = -Infinity,\n maxY = -Infinity;\n\n refs.forEach((el) => {\n const rect = el.getBoundingClientRect();\n minX = Math.min(minX, rect.left);\n minY = Math.min(minY, rect.top);\n maxX = Math.max(maxX, rect.right);\n maxY = Math.max(maxY, rect.bottom);\n });\n\n if (typeof DOMRect !== 'undefined') {\n boundsRef.current = new DOMRect(minX, minY, maxX - minX, maxY - minY);\n } else {\n boundsRef.current = {\n x: minX,\n y: minY,\n width: maxX - minX,\n height: maxY - minY,\n top: minY,\n right: maxX,\n bottom: maxY,\n left: minX,\n toJSON: () => ({}),\n } as DOMRect;\n }\n }, [itemRefs]);\n\n // Track mouse for collapse — expand when mouse leaves bounds\n useEffect(() => {\n if (!isCollapsed) return;\n\n const handleMouseMove = (e: MouseEvent) => {\n const bounds = boundsRef.current;\n\n if (!bounds) {\n setIsCollapsed(false);\n onPauseChange(false);\n return;\n }\n\n const padding = 20;\n const isInBounds =\n e.clientX >= bounds.left - padding &&\n e.clientX <= bounds.right + padding &&\n e.clientY >= bounds.top - padding &&\n e.clientY <= bounds.bottom + padding;\n\n if (!isInBounds) {\n setIsCollapsed(false);\n onPauseChange(false);\n }\n };\n\n window.addEventListener('mousemove', handleMouseMove);\n return () => window.removeEventListener('mousemove', handleMouseMove);\n }, [isCollapsed, onPauseChange]);\n\n // Update bounds when items change\n useEffect(() => {\n updateBounds();\n }, [allItems, updateBounds]);\n\n const handleMouseEnter = useCallback(() => {\n updateBounds();\n onPauseChange(true);\n\n if (canCollapse) {\n setIsCollapsed(true);\n }\n }, [updateBounds, canCollapse, onPauseChange]);\n\n const handleMouseLeave = useCallback(() => {\n if (!isCollapsed) {\n onPauseChange(false);\n }\n }, [isCollapsed, onPauseChange]);\n\n const handleFocus = useCallback(() => {\n onPauseChange(true);\n }, [onPauseChange]);\n\n const handleBlur = useCallback(\n (e: FocusEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(e.relatedTarget as Node)\n ) {\n onPauseChange(false);\n }\n },\n [onPauseChange],\n );\n\n return {\n isCollapsed,\n handleMouseEnter,\n handleMouseLeave,\n handleFocus,\n handleBlur,\n containerRef,\n };\n}\n\n// ─── Overlay Container ───────────────────────────────────────────────\n//\n// INTENTIONAL: Position calculations are done manually (absolute positioning + JS\n// height tracking) rather than relying on CSS flexbox/grid layout. This is\n// deliberate — the container mixes enter/exit animations, collapse behavior, and\n// heterogeneous item sizes (toasts vs notifications) which require per-item\n// position control. CSS-only solutions (e.g., flex column with gap) break when\n// items exit asynchronously or when collapse transforms need to be computed per-item.\n\nexport interface OverlayContainerProps {\n toasts: InternalToast[];\n notifications: InternalNotification[];\n onToastExitComplete: (internalId: string) => void;\n onNotificationExitComplete: (internalId: string) => void;\n onNotificationDismiss: (id: Key, reason: DismissReason) => void;\n onNotificationRestore: (id: Key) => void;\n onPauseChange: (paused: boolean) => void;\n}\n\nexport function OverlayContainer({\n toasts,\n notifications,\n onToastExitComplete,\n onNotificationExitComplete,\n onNotificationDismiss,\n onNotificationRestore,\n onPauseChange,\n}: OverlayContainerProps) {\n // Merge toasts and notifications into a single ordered list\n const allItems: OverlayItem[] = useMemo(() => {\n const items: OverlayItem[] = [\n ...toasts.map((t): OverlayItem => ({ kind: 'toast', data: t })),\n ...notifications.map(\n (n): OverlayItem => ({ kind: 'notification', data: n }),\n ),\n ];\n\n // Sort by createdAt ascending (oldest first = bottom of stack, newest last = top)\n items.sort((a, b) => getItemCreatedAt(a) - getItemCreatedAt(b));\n\n return items;\n }, [toasts, notifications]);\n\n const visibleItems = useMemo(\n () => allItems.filter((item) => !isItemExiting(item)),\n [allItems],\n );\n const hasNotifications = notifications.some((n) => !n.isExiting);\n const hasActionableToasts = toasts.some((t) => !t.isExiting && t.actions);\n const canCollapse = !hasNotifications && !hasActionableToasts;\n\n const {\n heights,\n settledIds,\n positions,\n lastPositionsRef,\n itemRefs,\n createRefCallback,\n } = useItemPositions(visibleItems);\n\n const {\n isCollapsed,\n handleMouseEnter,\n handleMouseLeave,\n handleFocus,\n handleBlur,\n containerRef,\n } = useCollapseState(canCollapse, allItems, itemRefs, onPauseChange);\n\n // ─── Callbacks ─────────────────────────────────────────────────────\n\n // When the user dismisses a notification they were hovering, the element\n // is removed from the DOM so mouseLeave never fires. Explicitly unpause\n // so remaining notifications' timers resume.\n const handleNotificationDismiss = useEvent(\n (id: Key, reason: DismissReason) => {\n onNotificationDismiss(id, reason);\n onPauseChange(false);\n },\n );\n\n const handleExitComplete = useEvent((item: OverlayItem) => {\n const id = getItemId(item);\n lastPositionsRef.current?.delete(id);\n\n if (item.kind === 'toast') {\n onToastExitComplete(item.data.internalId);\n } else {\n onNotificationExitComplete(item.data.internalId);\n }\n });\n\n // useCallback (not useEvent) because this is called during render.\n // useEvent defers the ref update to useLayoutEffect, so during render\n // it would still read the previous closure's positions/heights.\n const getItemStyle = useCallback(\n (item: OverlayItem, index: number, total: number) => {\n const id = getItemId(item);\n const baseTop =\n positions.get(id) ?? lastPositionsRef.current?.get(id) ?? 0;\n const height = heights[id] ?? DEFAULT_ITEM_HEIGHT;\n\n if (!isCollapsed || !canCollapse) {\n return { top: `${baseTop}px` };\n }\n\n const isNewest = index === total - 1;\n const collapsedTop = COLLAPSE_VISIBLE_HEIGHT - CONTAINER_OFFSET - height;\n\n return {\n top: `${collapsedTop}px`,\n zIndex: index,\n opacity: isNewest ? 1 : 0,\n pointerEvents: 'none' as const,\n };\n },\n [isCollapsed, canCollapse, positions, heights, lastPositionsRef],\n );\n\n // Build a visibleIndex lookup map to avoid O(n²) findIndex inside render loop\n const visibleIndexMap = useMemo(() => {\n const map = new Map<string, number>();\n\n visibleItems.forEach((item, index) => {\n map.set(getItemId(item), index);\n });\n\n return map;\n }, [visibleItems]);\n\n if (allItems.length === 0) return null;\n\n return (\n <Portal>\n <OverlayContainerElement\n ref={containerRef}\n onFocus={handleFocus}\n onBlur={handleBlur}\n >\n {allItems.map((item) => {\n const itemId = getItemId(item);\n const visibleIndex = visibleIndexMap.get(itemId) ?? 0;\n const isExiting = isItemExiting(item);\n\n return (\n <DisplayTransition\n key={itemId}\n animateOnMount\n isShown={!isExiting}\n onRest={(transition) => {\n if (transition === 'exit') {\n handleExitComplete(item);\n }\n }}\n >\n {({ isShown, ref }) => (\n <OverlayItemWrapper\n ref={createRefCallback(itemId, ref)}\n mods={{ isShown, isMeasured: settledIds.has(itemId) }}\n style={getItemStyle(item, visibleIndex, visibleItems.length)}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n {item.kind === 'toast' ? (\n <ToastItem\n {...item.data.itemProps}\n title={item.data.title}\n description={item.data.description}\n theme={item.data.theme}\n icon={item.data.icon}\n isLoading={item.data.isLoading}\n actions={item.data.actions}\n />\n ) : (\n <NotificationItem\n notification={item.data}\n onDismiss={handleNotificationDismiss}\n onRestore={onNotificationRestore}\n />\n )}\n </OverlayItemWrapper>\n )}\n </DisplayTransition>\n );\n })}\n </OverlayContainerElement>\n </Portal>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAyBA,MAAM,0BAA0B;AAChC,MAAM,mBAAmB;AACzB,MAAM,WAAW;AACjB,MAAM,sBAAsB;AAI5B,MAAM,0BAA0B,MAAM,EACpC,QAAQ;CACN,UAAU;CACV,KAAK;CACL,MAAM;CACN,WAAW;CACX,QAAQ;CACR,SAAS;CACT,QAAQ;CACR,eAAe;CAChB,EACF,CAAC;AAEF,MAAM,qBAAqB,MAAM,EAC/B,QAAQ;CACN,UAAU;CACV,KAAK;CACL,MAAM;CACN,WAAW;EACT,IAAI;EACJ,wBAAwB;EACzB;CACD,OAAO;CACP,eAAe;CACf,YAAY;EACV,IAAI;EACJ,YACE;EACH;CACD,SAAS;EACP,IAAI;EACJ,SAAS;EACV;CACF,EACF,CAAC;AAQF,SAAS,UAAU,MAA2B;AAC5C,QAAO,KAAK,KAAK;;AAGnB,SAAS,cAAc,MAA4B;AACjD,QAAO,KAAK,KAAK,cAAc;;AAGjC,SAAS,iBAAiB,MAA2B;AACnD,QAAO,KAAK,KAAK;;;;;;AAsBnB,SAAS,iBAAiB,cAAkD;CAC1E,MAAM,CAAC,SAAS,cAAc,SAAiC,EAAE,CAAC;CAClE,MAAM,WAAW,uBAAoC,IAAI,KAAK,CAAC;CAC/D,MAAM,mBAAmB,uBAA4B,IAAI,KAAK,CAAC;CAK/D,MAAM,CAAC,YAAY,iBAAiB,yBAAsB,IAAI,KAAK,CAAC;CACpE,MAAM,SAAS,OAAsB,KAAK;AAI1C,yBAAsB;EACpB,MAAM,aAAqC,EAAE;EAC7C,IAAI,aAAa;AAEjB,WAAS,QAAQ,SAAS,IAAI,OAAO;GACnC,MAAM,SAAS,GAAG,gBAAgB;AAClC,cAAW,MAAM;AAEjB,OAAI,QAAQ,QAAQ,OAClB,cAAa;IAEf;AAEF,OAAK,MAAM,MAAM,OAAO,KAAK,QAAQ,CACnC,KAAI,CAAC,SAAS,QAAQ,IAAI,GAAG,CAC3B,cAAa;AAIjB,MAAI,WACF,YAAW,WAAW;GAExB;AAKF,iBAAgB;EACd,MAAM,aAAa,OAAO,KAAK,QAAQ;EACvC,MAAM,SAAS,WAAW,QAAQ,OAAO,CAAC,WAAW,IAAI,GAAG,CAAC;EAC7D,MAAM,cACJ,WAAW,OAAO,KAAK,CAAC,GAAG,WAAW,CAAC,MAAM,OAAO,EAAE,MAAM,SAAS;AAEvE,MAAI,OAAO,WAAW,KAAK,CAAC,YAAa;AAEzC,MAAI,OAAO,WAAW,KACpB,sBAAqB,OAAO,QAAQ;AAKtC,MAAI,OAAO,WAAW,KAAK,aAAa;AACtC,kBAAe,SAAS,IAAI,IAAI,WAAW,QAAQ,OAAO,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC;AACzE;;AAGF,SAAO,UAAU,4BAA4B;AAC3C,UAAO,UAAU;AACjB,kBAAe,SAAS;IACtB,MAAM,uBAAO,IAAI,KAAa;AAG9B,SAAK,MAAM,MAAM,WACf,KAAI,KAAK,IAAI,GAAG,CACd,MAAK,IAAI,GAAG;AAIhB,SAAK,MAAM,MAAM,OACf,MAAK,IAAI,GAAG;AAGd,WAAO;KACP;IACF;AAEF,eAAa;AACX,OAAI,OAAO,WAAW,MAAM;AAC1B,yBAAqB,OAAO,QAAQ;AACpC,WAAO,UAAU;;;IAGpB,CAAC,QAAQ,CAAC;CAEb,MAAM,oBAAoB,aACvB,QAAgB,gBACd,OAA8B;AAC7B,aAAW,GAAG;AAEd,MAAI,GACF,UAAS,QAAQ,IAAI,QAAQ,GAAG;MAEhC,UAAS,QAAQ,OAAO,OAAO;IAGrC,EAAE,CACH;CAED,MAAM,YAAY,cAAc;EAC9B,MAAM,yBAAS,IAAI,KAAqB;EACxC,IAAI,aAAa;AAEjB,OAAK,MAAM,QAAQ,cAAc;GAC/B,MAAM,KAAK,UAAU,KAAK;AAC1B,UAAO,IAAI,IAAI,WAAW;GAC1B,MAAM,SAAS,QAAQ,OAAO;AAC9B,iBAAc,SAAS;;AAGzB,SAAO;IACN,CAAC,cAAc,QAAQ,CAAC;AAE3B,iBAAgB;AACd,YAAU,SAAS,KAAK,OAAO;AAC7B,oBAAiB,QAAQ,IAAI,IAAI,IAAI;IACrC;IACD,CAAC,UAAU,CAAC;AAEf,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACD;;;;;;AAkBH,SAAS,iBACP,aACA,UACA,UACA,eACqB;CACrB,MAAM,CAAC,aAAa,kBAAkB,SAAS,MAAM;CACrD,MAAM,eAAe,OAAuB,KAAK;CACjD,MAAM,YAAY,OAAuB,KAAK;CAE9C,MAAM,eAAe,kBAAkB;EACrC,MAAM,OAAO,SAAS;AAEtB,MAAI,CAAC,QAAQ,KAAK,SAAS,GAAG;AAC5B,aAAU,UAAU;AACpB;;EAGF,IAAI,OAAO,UACT,OAAO,UACP,OAAO,WACP,OAAO;AAET,OAAK,SAAS,OAAO;GACnB,MAAM,OAAO,GAAG,uBAAuB;AACvC,UAAO,KAAK,IAAI,MAAM,KAAK,KAAK;AAChC,UAAO,KAAK,IAAI,MAAM,KAAK,IAAI;AAC/B,UAAO,KAAK,IAAI,MAAM,KAAK,MAAM;AACjC,UAAO,KAAK,IAAI,MAAM,KAAK,OAAO;IAClC;AAEF,MAAI,OAAO,YAAY,YACrB,WAAU,UAAU,IAAI,QAAQ,MAAM,MAAM,OAAO,MAAM,OAAO,KAAK;MAErE,WAAU,UAAU;GAClB,GAAG;GACH,GAAG;GACH,OAAO,OAAO;GACd,QAAQ,OAAO;GACf,KAAK;GACL,OAAO;GACP,QAAQ;GACR,MAAM;GACN,eAAe,EAAE;GAClB;IAEF,CAAC,SAAS,CAAC;AAGd,iBAAgB;AACd,MAAI,CAAC,YAAa;EAElB,MAAM,mBAAmB,MAAkB;GACzC,MAAM,SAAS,UAAU;AAEzB,OAAI,CAAC,QAAQ;AACX,mBAAe,MAAM;AACrB,kBAAc,MAAM;AACpB;;GAGF,MAAM,UAAU;AAOhB,OAAI,EALF,EAAE,WAAW,OAAO,OAAO,WAC3B,EAAE,WAAW,OAAO,QAAQ,WAC5B,EAAE,WAAW,OAAO,MAAM,WAC1B,EAAE,WAAW,OAAO,SAAS,UAEd;AACf,mBAAe,MAAM;AACrB,kBAAc,MAAM;;;AAIxB,SAAO,iBAAiB,aAAa,gBAAgB;AACrD,eAAa,OAAO,oBAAoB,aAAa,gBAAgB;IACpE,CAAC,aAAa,cAAc,CAAC;AAGhC,iBAAgB;AACd,gBAAc;IACb,CAAC,UAAU,aAAa,CAAC;AAiC5B,QAAO;EACL;EACA,kBAjCuB,kBAAkB;AACzC,iBAAc;AACd,iBAAc,KAAK;AAEnB,OAAI,YACF,gBAAe,KAAK;KAErB;GAAC;GAAc;GAAa;GAAc,CAAC;EA2B5C,kBAzBuB,kBAAkB;AACzC,OAAI,CAAC,YACH,eAAc,MAAM;KAErB,CAAC,aAAa,cAAc,CAAC;EAsB9B,aApBkB,kBAAkB;AACpC,iBAAc,KAAK;KAClB,CAAC,cAAc,CAAC;EAmBjB,YAjBiB,aAChB,MAAkB;AACjB,OACE,aAAa,WACb,CAAC,aAAa,QAAQ,SAAS,EAAE,cAAsB,CAEvD,eAAc,MAAM;KAGxB,CAAC,cAAc,CAChB;EAQC;EACD;;AAsBH,SAAgB,iBAAiB,EAC/B,QACA,eACA,qBACA,4BACA,uBACA,uBACA,iBACwB;CAExB,MAAM,WAA0B,cAAc;EAC5C,MAAM,QAAuB,CAC3B,GAAG,OAAO,KAAK,OAAoB;GAAE,MAAM;GAAS,MAAM;GAAG,EAAE,EAC/D,GAAG,cAAc,KACd,OAAoB;GAAE,MAAM;GAAgB,MAAM;GAAG,EACvD,CACF;AAGD,QAAM,MAAM,GAAG,MAAM,iBAAiB,EAAE,GAAG,iBAAiB,EAAE,CAAC;AAE/D,SAAO;IACN,CAAC,QAAQ,cAAc,CAAC;CAE3B,MAAM,eAAe,cACb,SAAS,QAAQ,SAAS,CAAC,cAAc,KAAK,CAAC,EACrD,CAAC,SAAS,CACX;CACD,MAAM,mBAAmB,cAAc,MAAM,MAAM,CAAC,EAAE,UAAU;CAChE,MAAM,sBAAsB,OAAO,MAAM,MAAM,CAAC,EAAE,aAAa,EAAE,QAAQ;CACzE,MAAM,cAAc,CAAC,oBAAoB,CAAC;CAE1C,MAAM,EACJ,SACA,YACA,WACA,kBACA,UACA,sBACE,iBAAiB,aAAa;CAElC,MAAM,EACJ,aACA,kBACA,kBACA,aACA,YACA,iBACE,iBAAiB,aAAa,UAAU,UAAU,cAAc;CAOpE,MAAM,4BAA4B,UAC/B,IAAS,WAA0B;AAClC,wBAAsB,IAAI,OAAO;AACjC,gBAAc,MAAM;GAEvB;CAED,MAAM,qBAAqB,UAAU,SAAsB;EACzD,MAAM,KAAK,UAAU,KAAK;AAC1B,mBAAiB,SAAS,OAAO,GAAG;AAEpC,MAAI,KAAK,SAAS,QAChB,qBAAoB,KAAK,KAAK,WAAW;MAEzC,4BAA2B,KAAK,KAAK,WAAW;GAElD;CAKF,MAAM,eAAe,aAClB,MAAmB,OAAe,UAAkB;EACnD,MAAM,KAAK,UAAU,KAAK;EAC1B,MAAM,UACJ,UAAU,IAAI,GAAG,IAAI,iBAAiB,SAAS,IAAI,GAAG,IAAI;EAC5D,MAAM,SAAS,QAAQ,OAAO;AAE9B,MAAI,CAAC,eAAe,CAAC,YACnB,QAAO,EAAE,KAAK,GAAG,QAAQ,KAAK;EAGhC,MAAM,WAAW,UAAU,QAAQ;AAGnC,SAAO;GACL,KAAK,GAHc,0BAA0B,mBAAmB,OAG3C;GACrB,QAAQ;GACR,SAAS,WAAW,IAAI;GACxB,eAAe;GAChB;IAEH;EAAC;EAAa;EAAa;EAAW;EAAS;EAAiB,CACjE;CAGD,MAAM,kBAAkB,cAAc;EACpC,MAAM,sBAAM,IAAI,KAAqB;AAErC,eAAa,SAAS,MAAM,UAAU;AACpC,OAAI,IAAI,UAAU,KAAK,EAAE,MAAM;IAC/B;AAEF,SAAO;IACN,CAAC,aAAa,CAAC;AAElB,KAAI,SAAS,WAAW,EAAG,QAAO;AAElC,QACE,oBAAC,oBACC,oBAAC;EACC,KAAK;EACL,SAAS;EACT,QAAQ;YAEP,SAAS,KAAK,SAAS;GACtB,MAAM,SAAS,UAAU,KAAK;GAC9B,MAAM,eAAe,gBAAgB,IAAI,OAAO,IAAI;AAGpD,UACE,oBAAC;IAEC;IACA,SAAS,CANK,cAAc,KAAK;IAOjC,SAAS,eAAe;AACtB,SAAI,eAAe,OACjB,oBAAmB,KAAK;;eAI1B,EAAE,SAAS,UACX,oBAAC;KACC,KAAK,kBAAkB,QAAQ,IAAI;KACnC,MAAM;MAAE;MAAS,YAAY,WAAW,IAAI,OAAO;MAAE;KACrD,OAAO,aAAa,MAAM,cAAc,aAAa,OAAO;KAC5D,cAAc;KACd,cAAc;eAEb,KAAK,SAAS,UACb,oBAAC;MACC,GAAI,KAAK,KAAK;MACd,OAAO,KAAK,KAAK;MACjB,aAAa,KAAK,KAAK;MACvB,OAAO,KAAK,KAAK;MACjB,MAAM,KAAK,KAAK;MAChB,WAAW,KAAK,KAAK;MACrB,SAAS,KAAK,KAAK;OACnB,GAEF,oBAAC;MACC,cAAc,KAAK;MACnB,WAAW;MACX,WAAW;OACX;MAEe;MAlClB,OAoCa;IAEtB;GACsB,GACnB"}
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-b2f8ae7 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-26fe35d | Cube Dev Team */
2
2
  import { NotificationContext, PersistentNotificationsContext, ToastContext, useNotificationContext, useToastContext } from "./NotificationContext.js";
3
3
  import { OverlayContainer } from "./OverlayContainer.js";
4
4
  import { useNotificationState } from "./use-notification-state.js";
@@ -56,6 +56,7 @@ function OverlayProvider({ children, maxPersistentNotifications = DEFAULT_MAX_PE
56
56
  onToastExitComplete: toast.finalizeToastRemoval,
57
57
  onNotificationExitComplete: notification.finalizeNotificationRemoval,
58
58
  onNotificationDismiss: notification.removeNotification,
59
+ onNotificationRestore: notification.restoreNotification,
59
60
  onPauseChange: timers.handlePauseChange
60
61
  })]
61
62
  })
@@ -1 +1 @@
1
- {"version":3,"file":"OverlayProvider.js","names":[],"sources":["../../../../src/components/overlays/Notifications/OverlayProvider.tsx"],"sourcesContent":["import { useMemo, useRef } from 'react';\n\nimport {\n NotificationContext,\n PersistentNotificationsContext,\n ToastContext,\n} from './NotificationContext';\nimport { OverlayContainer } from './OverlayContainer';\nimport { useNotificationState } from './use-notification-state';\nimport { useOverlayTimers } from './use-overlay-timers';\nimport { usePersistentState } from './use-persistent-state';\nimport { useToastState } from './use-toast-state';\n\nimport type { ToastContextValue } from '../Toast/types';\nimport type {\n InternalNotificationContextValue,\n OverlayProviderProps,\n PersistentNotificationsContextValue,\n} from './types';\nimport type { OverlayTimers } from './use-overlay-timers';\n\n// ─── Re-export context hooks for consumers ───────────────────────────\n\nexport { useToastContext, useNotificationContext } from './NotificationContext';\n\n// ─── Constants ───────────────────────────────────────────────────────\n\nconst DEFAULT_MAX_PERSISTENT = 200;\n\n// ─── OverlayProvider ─────────────────────────────────────────────────\n\nexport function OverlayProvider({\n children,\n maxPersistentNotifications = DEFAULT_MAX_PERSISTENT,\n}: OverlayProviderProps) {\n // Shared ref that breaks the circular dependency between state hooks and timers.\n // State hooks need timer methods (start/clear), timer hooks need remove methods.\n // All consumers access the ref only inside useEvent/callbacks (never during\n // render), so it is guaranteed to be populated before first use.\n const timersRef = useRef<OverlayTimers>(null!);\n\n // 1. Persistent state (no dependencies on other hooks)\n const persistent = usePersistentState(maxPersistentNotifications);\n\n // 2. Toast state — accesses timers through the shared ref\n const toast = useToastState(timersRef);\n\n // 3. Notification state — accesses timers through the shared ref\n const notification = useNotificationState(timersRef, persistent);\n\n // 4. Create timers and populate the ref\n const timers = useOverlayTimers({\n toastsRef: toast.toastsRef,\n notificationsRef: notification.notificationsRef,\n removeToast: toast.removeToast,\n removeNotification: notification.removeNotification,\n });\n\n timersRef.current = timers;\n\n // ─── Context Values ───────────────────────────────────────────────\n\n // Only include actually-changing values in deps. All useEvent-based\n // callbacks are referentially stable and omitted.\n const toastContextValue = useMemo<ToastContextValue>(\n () => ({\n addToast: toast.addToast,\n removeToast: toast.removeToast,\n updateToast: toast.updateToast,\n toasts: toast.toasts,\n }),\n [toast.toasts],\n );\n\n const notificationContextValue = useMemo<InternalNotificationContextValue>(\n () => ({\n addNotification: notification.addNotification,\n removeNotification: notification.removeNotification,\n updateNotification: notification.updateNotification,\n notifications: notification.notifications,\n addPersistentItem: persistent.addPersistentItem,\n removePersistentItem: persistent.removePersistentItem,\n removePersistentItemsByOwner: persistent.removePersistentItemsByOwner,\n removeByOwner: notification.removeByOwner,\n }),\n [notification.notifications],\n );\n\n const persistentContextValue = useMemo<PersistentNotificationsContextValue>(\n () => ({\n persistentItems: persistent.persistentItems,\n removePersistentItem: persistent.removePersistentItem,\n clearPersistentItems: persistent.clearPersistentItems,\n markAllAsRead: persistent.markAllAsRead,\n }),\n [persistent.persistentItems],\n );\n\n return (\n <ToastContext.Provider value={toastContextValue}>\n <NotificationContext.Provider value={notificationContextValue}>\n <PersistentNotificationsContext.Provider value={persistentContextValue}>\n {children}\n <OverlayContainer\n toasts={toast.toasts}\n notifications={notification.notifications}\n onToastExitComplete={toast.finalizeToastRemoval}\n onNotificationExitComplete={\n notification.finalizeNotificationRemoval\n }\n onNotificationDismiss={notification.removeNotification}\n onPauseChange={timers.handlePauseChange}\n />\n </PersistentNotificationsContext.Provider>\n </NotificationContext.Provider>\n </ToastContext.Provider>\n );\n}\n"],"mappings":";;;;;;;;;;;AA2BA,MAAM,yBAAyB;AAI/B,SAAgB,gBAAgB,EAC9B,UACA,6BAA6B,0BACN;CAKvB,MAAM,YAAY,OAAsB,KAAM;CAG9C,MAAM,aAAa,mBAAmB,2BAA2B;CAGjE,MAAM,QAAQ,cAAc,UAAU;CAGtC,MAAM,eAAe,qBAAqB,WAAW,WAAW;CAGhE,MAAM,SAAS,iBAAiB;EAC9B,WAAW,MAAM;EACjB,kBAAkB,aAAa;EAC/B,aAAa,MAAM;EACnB,oBAAoB,aAAa;EAClC,CAAC;AAEF,WAAU,UAAU;CAMpB,MAAM,oBAAoB,eACjB;EACL,UAAU,MAAM;EAChB,aAAa,MAAM;EACnB,aAAa,MAAM;EACnB,QAAQ,MAAM;EACf,GACD,CAAC,MAAM,OAAO,CACf;CAED,MAAM,2BAA2B,eACxB;EACL,iBAAiB,aAAa;EAC9B,oBAAoB,aAAa;EACjC,oBAAoB,aAAa;EACjC,eAAe,aAAa;EAC5B,mBAAmB,WAAW;EAC9B,sBAAsB,WAAW;EACjC,8BAA8B,WAAW;EACzC,eAAe,aAAa;EAC7B,GACD,CAAC,aAAa,cAAc,CAC7B;CAED,MAAM,yBAAyB,eACtB;EACL,iBAAiB,WAAW;EAC5B,sBAAsB,WAAW;EACjC,sBAAsB,WAAW;EACjC,eAAe,WAAW;EAC3B,GACD,CAAC,WAAW,gBAAgB,CAC7B;AAED,QACE,oBAAC,aAAa;EAAS,OAAO;YAC5B,oBAAC,oBAAoB;GAAS,OAAO;aACnC,qBAAC,+BAA+B;IAAS,OAAO;eAC7C,UACD,oBAAC;KACC,QAAQ,MAAM;KACd,eAAe,aAAa;KAC5B,qBAAqB,MAAM;KAC3B,4BACE,aAAa;KAEf,uBAAuB,aAAa;KACpC,eAAe,OAAO;MACtB;KACsC;IACb;GACT"}
1
+ {"version":3,"file":"OverlayProvider.js","names":[],"sources":["../../../../src/components/overlays/Notifications/OverlayProvider.tsx"],"sourcesContent":["import { useMemo, useRef } from 'react';\n\nimport {\n NotificationContext,\n PersistentNotificationsContext,\n ToastContext,\n} from './NotificationContext';\nimport { OverlayContainer } from './OverlayContainer';\nimport { useNotificationState } from './use-notification-state';\nimport { useOverlayTimers } from './use-overlay-timers';\nimport { usePersistentState } from './use-persistent-state';\nimport { useToastState } from './use-toast-state';\n\nimport type { ToastContextValue } from '../Toast/types';\nimport type {\n InternalNotificationContextValue,\n OverlayProviderProps,\n PersistentNotificationsContextValue,\n} from './types';\nimport type { OverlayTimers } from './use-overlay-timers';\n\n// ─── Re-export context hooks for consumers ───────────────────────────\n\nexport { useToastContext, useNotificationContext } from './NotificationContext';\n\n// ─── Constants ───────────────────────────────────────────────────────\n\nconst DEFAULT_MAX_PERSISTENT = 200;\n\n// ─── OverlayProvider ─────────────────────────────────────────────────\n\nexport function OverlayProvider({\n children,\n maxPersistentNotifications = DEFAULT_MAX_PERSISTENT,\n}: OverlayProviderProps) {\n // Shared ref that breaks the circular dependency between state hooks and timers.\n // State hooks need timer methods (start/clear), timer hooks need remove methods.\n // All consumers access the ref only inside useEvent/callbacks (never during\n // render), so it is guaranteed to be populated before first use.\n const timersRef = useRef<OverlayTimers>(null!);\n\n // 1. Persistent state (no dependencies on other hooks)\n const persistent = usePersistentState(maxPersistentNotifications);\n\n // 2. Toast state — accesses timers through the shared ref\n const toast = useToastState(timersRef);\n\n // 3. Notification state — accesses timers through the shared ref\n const notification = useNotificationState(timersRef, persistent);\n\n // 4. Create timers and populate the ref\n const timers = useOverlayTimers({\n toastsRef: toast.toastsRef,\n notificationsRef: notification.notificationsRef,\n removeToast: toast.removeToast,\n removeNotification: notification.removeNotification,\n });\n\n timersRef.current = timers;\n\n // ─── Context Values ───────────────────────────────────────────────\n\n // Only include actually-changing values in deps. All useEvent-based\n // callbacks are referentially stable and omitted.\n const toastContextValue = useMemo<ToastContextValue>(\n () => ({\n addToast: toast.addToast,\n removeToast: toast.removeToast,\n updateToast: toast.updateToast,\n toasts: toast.toasts,\n }),\n [toast.toasts],\n );\n\n const notificationContextValue = useMemo<InternalNotificationContextValue>(\n () => ({\n addNotification: notification.addNotification,\n removeNotification: notification.removeNotification,\n updateNotification: notification.updateNotification,\n notifications: notification.notifications,\n addPersistentItem: persistent.addPersistentItem,\n removePersistentItem: persistent.removePersistentItem,\n removePersistentItemsByOwner: persistent.removePersistentItemsByOwner,\n removeByOwner: notification.removeByOwner,\n }),\n [notification.notifications],\n );\n\n const persistentContextValue = useMemo<PersistentNotificationsContextValue>(\n () => ({\n persistentItems: persistent.persistentItems,\n removePersistentItem: persistent.removePersistentItem,\n clearPersistentItems: persistent.clearPersistentItems,\n markAllAsRead: persistent.markAllAsRead,\n }),\n [persistent.persistentItems],\n );\n\n return (\n <ToastContext.Provider value={toastContextValue}>\n <NotificationContext.Provider value={notificationContextValue}>\n <PersistentNotificationsContext.Provider value={persistentContextValue}>\n {children}\n <OverlayContainer\n toasts={toast.toasts}\n notifications={notification.notifications}\n onToastExitComplete={toast.finalizeToastRemoval}\n onNotificationExitComplete={\n notification.finalizeNotificationRemoval\n }\n onNotificationDismiss={notification.removeNotification}\n onNotificationRestore={notification.restoreNotification}\n onPauseChange={timers.handlePauseChange}\n />\n </PersistentNotificationsContext.Provider>\n </NotificationContext.Provider>\n </ToastContext.Provider>\n );\n}\n"],"mappings":";;;;;;;;;;;AA2BA,MAAM,yBAAyB;AAI/B,SAAgB,gBAAgB,EAC9B,UACA,6BAA6B,0BACN;CAKvB,MAAM,YAAY,OAAsB,KAAM;CAG9C,MAAM,aAAa,mBAAmB,2BAA2B;CAGjE,MAAM,QAAQ,cAAc,UAAU;CAGtC,MAAM,eAAe,qBAAqB,WAAW,WAAW;CAGhE,MAAM,SAAS,iBAAiB;EAC9B,WAAW,MAAM;EACjB,kBAAkB,aAAa;EAC/B,aAAa,MAAM;EACnB,oBAAoB,aAAa;EAClC,CAAC;AAEF,WAAU,UAAU;CAMpB,MAAM,oBAAoB,eACjB;EACL,UAAU,MAAM;EAChB,aAAa,MAAM;EACnB,aAAa,MAAM;EACnB,QAAQ,MAAM;EACf,GACD,CAAC,MAAM,OAAO,CACf;CAED,MAAM,2BAA2B,eACxB;EACL,iBAAiB,aAAa;EAC9B,oBAAoB,aAAa;EACjC,oBAAoB,aAAa;EACjC,eAAe,aAAa;EAC5B,mBAAmB,WAAW;EAC9B,sBAAsB,WAAW;EACjC,8BAA8B,WAAW;EACzC,eAAe,aAAa;EAC7B,GACD,CAAC,aAAa,cAAc,CAC7B;CAED,MAAM,yBAAyB,eACtB;EACL,iBAAiB,WAAW;EAC5B,sBAAsB,WAAW;EACjC,sBAAsB,WAAW;EACjC,eAAe,WAAW;EAC3B,GACD,CAAC,WAAW,gBAAgB,CAC7B;AAED,QACE,oBAAC,aAAa;EAAS,OAAO;YAC5B,oBAAC,oBAAoB;GAAS,OAAO;aACnC,qBAAC,+BAA+B;IAAS,OAAO;eAC7C,UACD,oBAAC;KACC,QAAQ,MAAM;KACd,eAAe,aAAa;KAC5B,qBAAqB,MAAM;KAC3B,4BACE,aAAa;KAEf,uBAAuB,aAAa;KACpC,uBAAuB,aAAa;KACpC,eAAe,OAAO;MACtB;KACsC;IACb;GACT"}
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-b2f8ae7 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-26fe35d | Cube Dev Team */
2
2
  import { tasty } from "../../../tasty/tasty.js";
3
3
  import { useEvent } from "../../../_internal/hooks/use-event.js";
4
4
  import { _Text } from "../../content/Text.js";
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-b2f8ae7 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-26fe35d | Cube Dev Team */
2
2
  //#region src/components/overlays/Notifications/dismissed-storage.ts
3
3
  const STORAGE_KEY = "cube-ui-dismissed-notifications";
4
4
  const TTL_MS = 864e5;
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-b2f8ae7 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-26fe35d | Cube Dev Team */
2
2
  //#region src/components/overlays/Notifications/format-relative-time.ts
3
3
  /**
4
4
  * Lightweight relative time formatter.
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-b2f8ae7 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-26fe35d | Cube Dev Team */
2
2
  import { useToastContext } from "./NotificationContext.js";
3
3
  import { NotificationAction } from "./NotificationAction.js";
4
4
  import { NotificationCard } from "./NotificationCard.js";
@@ -101,6 +101,8 @@ interface InternalNotification extends OverlayNotificationOptions {
101
101
  createdAt: number;
102
102
  updatedAt: number;
103
103
  isExiting?: boolean;
104
+ /** Reason for the most recent dismiss, used to undo persistent side effects on restore. */
105
+ lastDismissReason?: DismissReason;
104
106
  ownerId?: string;
105
107
  }
106
108
  interface PersistentNotificationItem {
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-b2f8ae7 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-26fe35d | Cube Dev Team */
2
2
  import { useEvent } from "../../../_internal/hooks/use-event.js";
3
3
  import { useRef, useState } from "react";
4
4
 
@@ -74,7 +74,24 @@ function useNotificationState(timersRef, persistent) {
74
74
  }
75
75
  setNotifications((prev) => prev.map((n) => matchesNotificationId(n, id) ? {
76
76
  ...n,
77
- isExiting: true
77
+ isExiting: true,
78
+ lastDismissReason: reason
79
+ } : n));
80
+ });
81
+ const restoreNotification = useEvent((id) => {
82
+ const notif = findNotification(notificationsRef.current, id);
83
+ if (!notif || !notif.isExiting) return;
84
+ if (notif.persistent && notif.lastDismissReason) {
85
+ const persistentId = notif.id ?? notif.internalId;
86
+ if (notif.lastDismissReason === "close" || notif.lastDismissReason === "timeout") persistent.removePersistentItemSilently(persistentId);
87
+ else if (notif.lastDismissReason === "action") persistent.undoFullyDismissedId(persistentId);
88
+ }
89
+ const duration = getDuration(notif);
90
+ if (duration != null && duration > 0) timersRef.current?.startNotificationTimer(notif.internalId, notif.id ?? notif.internalId, duration);
91
+ setNotifications((prev) => prev.map((n) => matchesNotificationId(n, id) ? {
92
+ ...n,
93
+ isExiting: false,
94
+ lastDismissReason: void 0
78
95
  } : n));
79
96
  });
80
97
  const finalizeNotificationRemoval = useEvent((internalId) => {
@@ -152,6 +169,7 @@ function useNotificationState(timersRef, persistent) {
152
169
  return id;
153
170
  }),
154
171
  removeNotification,
172
+ restoreNotification,
155
173
  updateNotification: useEvent((id, options) => {
156
174
  setNotifications((prev) => prev.map((n) => matchesNotificationId(n, id) ? {
157
175
  ...n,
@@ -1 +1 @@
1
- {"version":3,"file":"use-notification-state.js","names":[],"sources":["../../../../src/components/overlays/Notifications/use-notification-state.ts"],"sourcesContent":["import { Key, useRef, useState } from 'react';\n\nimport { useEvent } from '../../../_internal';\n\nimport type {\n DismissReason,\n InternalNotification,\n OverlayNotificationOptions,\n PersistentNotificationItem,\n} from './types';\nimport type { OverlayTimers } from './use-overlay-timers';\n\n// ─── Constants ───────────────────────────────────────────────────────\n\nconst DEFAULT_NOTIFICATION_DURATION = 3000;\nconst DEFAULT_PERSISTENT_NOTIFICATION_DURATION = 5000;\nconst MAX_NOTIFICATIONS = 5;\n\n// ─── Types ───────────────────────────────────────────────────────────\n\nexport interface PersistentCallbacks {\n addPersistentItem: (item: PersistentNotificationItem) => void;\n removePersistentItem: (id: Key) => void;\n hasDismissedPersistentId: (id: Key) => boolean;\n isFullyDismissedId: (id: Key) => boolean;\n saveDismissedPersistentId: (id: Key) => void;\n}\n\nexport interface NotificationState {\n notifications: InternalNotification[];\n notificationsRef: ReturnType<typeof useRef<InternalNotification[]>>;\n addNotification: (\n options: OverlayNotificationOptions,\n ownerId?: string,\n ) => Key;\n removeNotification: (id: Key, reason?: DismissReason) => void;\n updateNotification: (\n id: Key,\n options: Partial<OverlayNotificationOptions>,\n ) => void;\n finalizeNotificationRemoval: (internalId: string) => void;\n removeByOwner: (ownerId: string) => void;\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────\n\nfunction getDuration(\n notif: OverlayNotificationOptions & { persistent?: boolean },\n): number | null {\n if (notif.duration === null) return null;\n if (notif.duration !== undefined) return notif.duration;\n return notif.persistent\n ? DEFAULT_PERSISTENT_NOTIFICATION_DURATION\n : DEFAULT_NOTIFICATION_DURATION;\n}\n\nfunction matchesNotificationId(item: InternalNotification, id: Key): boolean {\n return item.id === id || item.internalId === String(id);\n}\n\nfunction findNotification(\n list: InternalNotification[],\n id: Key,\n): InternalNotification | undefined {\n return list.find((n) => matchesNotificationId(n, id));\n}\n\n// ─── Hook ────────────────────────────────────────────────────────────\n\n/**\n * @param timersRef - Ref to the shared OverlayTimers instance. Accessed only\n * inside callbacks (never during render), so it is guaranteed to be populated.\n */\nexport function useNotificationState(\n timersRef: ReturnType<typeof useRef<OverlayTimers>>,\n persistent: PersistentCallbacks,\n): NotificationState {\n const [notifications, setNotifications] = useState<InternalNotification[]>(\n [],\n );\n const notificationsRef = useRef(notifications);\n notificationsRef.current = notifications;\n\n const idCounter = useRef(0);\n\n // ─── Evict Helper ──────────────────────────────────────────────\n\n /**\n * Evict the oldest active notification to make room for a new one.\n * Clears its timer and moves it to the persistent list if applicable.\n * Must be called OUTSIDE setState updaters (StrictMode-safe).\n */\n const evictOldest = useEvent((): string | null => {\n const active = notificationsRef.current.filter((n) => !n.isExiting);\n\n if (active.length === 0) return null;\n\n // Oldest by createdAt (active list preserves insertion order)\n const oldest = active[0];\n\n timersRef.current?.clearNotificationTimer(oldest.internalId);\n\n // Eviction counts as a timeout dismissal — move to persistent list if applicable\n if (oldest.persistent) {\n persistent.addPersistentItem({\n id: oldest.id ?? oldest.internalId,\n theme: oldest.theme,\n title: oldest.title,\n description: oldest.description,\n icon: oldest.icon,\n actions: oldest.actions,\n createdAt: oldest.createdAt,\n updatedAt: oldest.updatedAt,\n isRead: false,\n ownerId: oldest.ownerId,\n });\n }\n\n return oldest.internalId;\n });\n\n // ─── Remove ─────────────────────────────────────────────────────\n\n const removeNotification = useEvent(\n (id: Key, reason: DismissReason = 'api') => {\n // Read from ref (synchronous) to perform side effects OUTSIDE the updater.\n // This prevents double-fire in StrictMode and avoids calling setState\n // (addPersistentItem) inside another setState updater.\n const notif = findNotification(notificationsRef.current, id);\n\n if (!notif || notif.isExiting) return;\n\n timersRef.current?.clearNotificationTimer(notif.internalId);\n\n if (notif.persistent) {\n if (reason === 'close' || reason === 'timeout') {\n // Dismiss button, Escape, or auto-dismiss timeout — move to persistent list.\n // If the same id is triggered again, it skips the overlay and updates the\n // persistent list directly.\n persistent.addPersistentItem({\n id: notif.id ?? notif.internalId,\n theme: notif.theme,\n title: notif.title,\n description: notif.description,\n icon: notif.icon,\n actions: notif.actions,\n createdAt: notif.createdAt,\n updatedAt: notif.updatedAt,\n isRead: true,\n ownerId: notif.ownerId,\n });\n } else if (reason === 'action') {\n // User clicked a regular action (not dismiss) — fully dismiss the\n // notification so it never reappears (overlay or persistent list).\n persistent.saveDismissedPersistentId(notif.id ?? notif.internalId);\n persistent.removePersistentItem(notif.id ?? notif.internalId);\n }\n // reason === 'api' — programmatic cleanup (e.g. component unmount).\n // No persistence, no full-dismiss tracking.\n }\n\n setNotifications((prev) =>\n prev.map((n) =>\n matchesNotificationId(n, id) ? { ...n, isExiting: true } : n,\n ),\n );\n },\n );\n\n // ─── Finalize ──────────────────────────────────────────────────\n\n const finalizeNotificationRemoval = useEvent((internalId: string) => {\n setNotifications((prev) => prev.filter((n) => n.internalId !== internalId));\n });\n\n // ─── Add ────────────────────────────────────────────────────────\n\n const addNotification = useEvent(\n (options: OverlayNotificationOptions, ownerId?: string): Key => {\n idCounter.current += 1;\n const internalId = `notif-${idCounter.current}-${Date.now()}`;\n const now = Date.now();\n const id = options.id ?? internalId;\n\n // If the user explicitly removed this notification from the persistent\n // list, completely ignore it — no overlay, no persistent storage.\n if (options.id != null && persistent.isFullyDismissedId(options.id)) {\n return id;\n }\n\n // If this persistent id was previously dismissed to the persistent list,\n // skip the overlay and update the persistent item directly.\n if (\n options.persistent &&\n options.id != null &&\n persistent.hasDismissedPersistentId(options.id)\n ) {\n persistent.addPersistentItem({\n id,\n theme: options.theme,\n title: options.title,\n description: options.description,\n icon: options.icon,\n actions: options.actions,\n createdAt: now,\n updatedAt: now,\n isRead: false,\n ownerId,\n });\n\n return id;\n }\n\n // Check for existing notification with same id via the ref (synchronous read).\n const existingNotif =\n options.id != null\n ? notificationsRef.current.find(\n (n) => n.id === options.id && !n.isExiting,\n )\n : undefined;\n\n if (existingNotif) {\n // In-place update of an existing notification\n const returnId = existingNotif.id ?? existingNotif.internalId;\n\n const prevTitle = existingNotif.title;\n const prevDescription = existingNotif.description;\n\n // Timer reset on string title/description change\n const titleChanged =\n typeof options.title === 'string' &&\n typeof prevTitle === 'string' &&\n options.title !== prevTitle;\n const descriptionChanged =\n typeof options.description === 'string' &&\n typeof prevDescription === 'string' &&\n options.description !== prevDescription;\n\n if (titleChanged || descriptionChanged) {\n const duration = getDuration(options);\n\n if (duration != null && duration > 0) {\n timersRef.current?.startNotificationTimer(\n existingNotif.internalId,\n existingNotif.id ?? existingNotif.internalId,\n duration,\n );\n }\n }\n\n setNotifications((prev) =>\n prev.map((n) => {\n if (n.internalId === existingNotif.internalId) {\n return {\n ...n,\n ...options,\n internalId: n.internalId,\n createdAt: n.createdAt,\n updatedAt: now,\n ownerId: ownerId ?? n.ownerId,\n };\n }\n return n;\n }),\n );\n\n return returnId;\n }\n\n // New notification — always show immediately, evicting the oldest if at cap.\n // Read from ref (synchronous) to perform side effects OUTSIDE the updater.\n const activeCount = notificationsRef.current.filter(\n (n) => !n.isExiting,\n ).length;\n\n const newNotification: InternalNotification = {\n ...options,\n id,\n internalId,\n createdAt: now,\n updatedAt: now,\n ownerId,\n };\n\n // Evict oldest if at cap (side effects outside updater)\n let evictedInternalId: string | null = null;\n\n if (activeCount >= MAX_NOTIFICATIONS) {\n evictedInternalId = evictOldest();\n }\n\n // Start timer for the new notification\n const duration = getDuration(options);\n\n if (duration != null && duration > 0) {\n timersRef.current?.startNotificationTimer(internalId, id, duration);\n }\n\n setNotifications((prev) => {\n let next = prev;\n\n if (evictedInternalId) {\n next = next.map((n) =>\n n.internalId === evictedInternalId ? { ...n, isExiting: true } : n,\n );\n }\n\n return [...next, newNotification];\n });\n\n return id;\n },\n );\n\n // ─── Update ─────────────────────────────────────────────────────\n\n const updateNotification = useEvent(\n (id: Key, options: Partial<OverlayNotificationOptions>) => {\n setNotifications((prev) =>\n prev.map((n) =>\n matchesNotificationId(n, id)\n ? { ...n, ...options, updatedAt: Date.now() }\n : n,\n ),\n );\n },\n );\n\n // ─── Owner Cleanup ──────────────────────────────────────────────\n\n const removeByOwner = useEvent((ownerId: string) => {\n // Clear timers outside the updater (StrictMode-safe).\n const owned = notificationsRef.current.filter(\n (n) => n.ownerId === ownerId && !n.isExiting,\n );\n\n for (const n of owned) {\n timersRef.current?.clearNotificationTimer(n.internalId);\n }\n\n setNotifications((prev) =>\n prev.map((n) => {\n if (n.ownerId === ownerId && !n.isExiting) {\n return { ...n, isExiting: true };\n }\n return n;\n }),\n );\n });\n\n return {\n notifications,\n notificationsRef,\n addNotification,\n removeNotification,\n updateNotification,\n finalizeNotificationRemoval,\n removeByOwner,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-notification-state.js","names":[],"sources":["../../../../src/components/overlays/Notifications/use-notification-state.ts"],"sourcesContent":["import { Key, useRef, useState } from 'react';\n\nimport { useEvent } from '../../../_internal';\n\nimport type {\n DismissReason,\n InternalNotification,\n OverlayNotificationOptions,\n PersistentNotificationItem,\n} from './types';\nimport type { OverlayTimers } from './use-overlay-timers';\n\n// ─── Constants ───────────────────────────────────────────────────────\n\nconst DEFAULT_NOTIFICATION_DURATION = 3000;\nconst DEFAULT_PERSISTENT_NOTIFICATION_DURATION = 5000;\nconst MAX_NOTIFICATIONS = 5;\n\n// ─── Types ───────────────────────────────────────────────────────────\n\nexport interface PersistentCallbacks {\n addPersistentItem: (item: PersistentNotificationItem) => void;\n removePersistentItem: (id: Key) => void;\n removePersistentItemSilently: (id: Key) => void;\n hasDismissedPersistentId: (id: Key) => boolean;\n isFullyDismissedId: (id: Key) => boolean;\n saveDismissedPersistentId: (id: Key) => void;\n undoFullyDismissedId: (id: Key) => void;\n}\n\nexport interface NotificationState {\n notifications: InternalNotification[];\n notificationsRef: ReturnType<typeof useRef<InternalNotification[]>>;\n addNotification: (\n options: OverlayNotificationOptions,\n ownerId?: string,\n ) => Key;\n removeNotification: (id: Key, reason?: DismissReason) => void;\n restoreNotification: (id: Key) => void;\n updateNotification: (\n id: Key,\n options: Partial<OverlayNotificationOptions>,\n ) => void;\n finalizeNotificationRemoval: (internalId: string) => void;\n removeByOwner: (ownerId: string) => void;\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────\n\nfunction getDuration(\n notif: OverlayNotificationOptions & { persistent?: boolean },\n): number | null {\n if (notif.duration === null) return null;\n if (notif.duration !== undefined) return notif.duration;\n return notif.persistent\n ? DEFAULT_PERSISTENT_NOTIFICATION_DURATION\n : DEFAULT_NOTIFICATION_DURATION;\n}\n\nfunction matchesNotificationId(item: InternalNotification, id: Key): boolean {\n return item.id === id || item.internalId === String(id);\n}\n\nfunction findNotification(\n list: InternalNotification[],\n id: Key,\n): InternalNotification | undefined {\n return list.find((n) => matchesNotificationId(n, id));\n}\n\n// ─── Hook ────────────────────────────────────────────────────────────\n\n/**\n * @param timersRef - Ref to the shared OverlayTimers instance. Accessed only\n * inside callbacks (never during render), so it is guaranteed to be populated.\n */\nexport function useNotificationState(\n timersRef: ReturnType<typeof useRef<OverlayTimers>>,\n persistent: PersistentCallbacks,\n): NotificationState {\n const [notifications, setNotifications] = useState<InternalNotification[]>(\n [],\n );\n const notificationsRef = useRef(notifications);\n notificationsRef.current = notifications;\n\n const idCounter = useRef(0);\n\n // ─── Evict Helper ──────────────────────────────────────────────\n\n /**\n * Evict the oldest active notification to make room for a new one.\n * Clears its timer and moves it to the persistent list if applicable.\n * Must be called OUTSIDE setState updaters (StrictMode-safe).\n */\n const evictOldest = useEvent((): string | null => {\n const active = notificationsRef.current.filter((n) => !n.isExiting);\n\n if (active.length === 0) return null;\n\n // Oldest by createdAt (active list preserves insertion order)\n const oldest = active[0];\n\n timersRef.current?.clearNotificationTimer(oldest.internalId);\n\n // Eviction counts as a timeout dismissal — move to persistent list if applicable\n if (oldest.persistent) {\n persistent.addPersistentItem({\n id: oldest.id ?? oldest.internalId,\n theme: oldest.theme,\n title: oldest.title,\n description: oldest.description,\n icon: oldest.icon,\n actions: oldest.actions,\n createdAt: oldest.createdAt,\n updatedAt: oldest.updatedAt,\n isRead: false,\n ownerId: oldest.ownerId,\n });\n }\n\n return oldest.internalId;\n });\n\n // ─── Remove ─────────────────────────────────────────────────────\n\n const removeNotification = useEvent(\n (id: Key, reason: DismissReason = 'api') => {\n // Read from ref (synchronous) to perform side effects OUTSIDE the updater.\n // This prevents double-fire in StrictMode and avoids calling setState\n // (addPersistentItem) inside another setState updater.\n const notif = findNotification(notificationsRef.current, id);\n\n if (!notif || notif.isExiting) return;\n\n timersRef.current?.clearNotificationTimer(notif.internalId);\n\n if (notif.persistent) {\n if (reason === 'close' || reason === 'timeout') {\n // Dismiss button, Escape, or auto-dismiss timeout — move to persistent list.\n // If the same id is triggered again, it skips the overlay and updates the\n // persistent list directly.\n persistent.addPersistentItem({\n id: notif.id ?? notif.internalId,\n theme: notif.theme,\n title: notif.title,\n description: notif.description,\n icon: notif.icon,\n actions: notif.actions,\n createdAt: notif.createdAt,\n updatedAt: notif.updatedAt,\n isRead: true,\n ownerId: notif.ownerId,\n });\n } else if (reason === 'action') {\n // User clicked a regular action (not dismiss) — fully dismiss the\n // notification so it never reappears (overlay or persistent list).\n persistent.saveDismissedPersistentId(notif.id ?? notif.internalId);\n persistent.removePersistentItem(notif.id ?? notif.internalId);\n }\n // reason === 'api' — programmatic cleanup (e.g. component unmount).\n // No persistence, no full-dismiss tracking.\n }\n\n setNotifications((prev) =>\n prev.map((n) =>\n matchesNotificationId(n, id)\n ? { ...n, isExiting: true, lastDismissReason: reason }\n : n,\n ),\n );\n },\n );\n\n // ─── Restore ──────────────────────────────────────────────────\n\n const restoreNotification = useEvent((id: Key) => {\n const notif = findNotification(notificationsRef.current, id);\n\n if (!notif || !notif.isExiting) return;\n\n // Undo persistent side effects based on how the notification was dismissed.\n if (notif.persistent && notif.lastDismissReason) {\n const persistentId = notif.id ?? notif.internalId;\n\n if (\n notif.lastDismissReason === 'close' ||\n notif.lastDismissReason === 'timeout'\n ) {\n persistent.removePersistentItemSilently(persistentId);\n } else if (notif.lastDismissReason === 'action') {\n persistent.undoFullyDismissedId(persistentId);\n }\n }\n\n // Restart the auto-dismiss timer.\n const duration = getDuration(notif);\n\n if (duration != null && duration > 0) {\n timersRef.current?.startNotificationTimer(\n notif.internalId,\n notif.id ?? notif.internalId,\n duration,\n );\n }\n\n setNotifications((prev) =>\n prev.map((n) =>\n matchesNotificationId(n, id)\n ? { ...n, isExiting: false, lastDismissReason: undefined }\n : n,\n ),\n );\n });\n\n // ─── Finalize ──────────────────────────────────────────────────\n\n const finalizeNotificationRemoval = useEvent((internalId: string) => {\n setNotifications((prev) => prev.filter((n) => n.internalId !== internalId));\n });\n\n // ─── Add ────────────────────────────────────────────────────────\n\n const addNotification = useEvent(\n (options: OverlayNotificationOptions, ownerId?: string): Key => {\n idCounter.current += 1;\n const internalId = `notif-${idCounter.current}-${Date.now()}`;\n const now = Date.now();\n const id = options.id ?? internalId;\n\n // If the user explicitly removed this notification from the persistent\n // list, completely ignore it — no overlay, no persistent storage.\n if (options.id != null && persistent.isFullyDismissedId(options.id)) {\n return id;\n }\n\n // If this persistent id was previously dismissed to the persistent list,\n // skip the overlay and update the persistent item directly.\n if (\n options.persistent &&\n options.id != null &&\n persistent.hasDismissedPersistentId(options.id)\n ) {\n persistent.addPersistentItem({\n id,\n theme: options.theme,\n title: options.title,\n description: options.description,\n icon: options.icon,\n actions: options.actions,\n createdAt: now,\n updatedAt: now,\n isRead: false,\n ownerId,\n });\n\n return id;\n }\n\n // Check for existing notification with same id via the ref (synchronous read).\n const existingNotif =\n options.id != null\n ? notificationsRef.current.find(\n (n) => n.id === options.id && !n.isExiting,\n )\n : undefined;\n\n if (existingNotif) {\n // In-place update of an existing notification\n const returnId = existingNotif.id ?? existingNotif.internalId;\n\n const prevTitle = existingNotif.title;\n const prevDescription = existingNotif.description;\n\n // Timer reset on string title/description change\n const titleChanged =\n typeof options.title === 'string' &&\n typeof prevTitle === 'string' &&\n options.title !== prevTitle;\n const descriptionChanged =\n typeof options.description === 'string' &&\n typeof prevDescription === 'string' &&\n options.description !== prevDescription;\n\n if (titleChanged || descriptionChanged) {\n const duration = getDuration(options);\n\n if (duration != null && duration > 0) {\n timersRef.current?.startNotificationTimer(\n existingNotif.internalId,\n existingNotif.id ?? existingNotif.internalId,\n duration,\n );\n }\n }\n\n setNotifications((prev) =>\n prev.map((n) => {\n if (n.internalId === existingNotif.internalId) {\n return {\n ...n,\n ...options,\n internalId: n.internalId,\n createdAt: n.createdAt,\n updatedAt: now,\n ownerId: ownerId ?? n.ownerId,\n };\n }\n return n;\n }),\n );\n\n return returnId;\n }\n\n // New notification — always show immediately, evicting the oldest if at cap.\n // Read from ref (synchronous) to perform side effects OUTSIDE the updater.\n const activeCount = notificationsRef.current.filter(\n (n) => !n.isExiting,\n ).length;\n\n const newNotification: InternalNotification = {\n ...options,\n id,\n internalId,\n createdAt: now,\n updatedAt: now,\n ownerId,\n };\n\n // Evict oldest if at cap (side effects outside updater)\n let evictedInternalId: string | null = null;\n\n if (activeCount >= MAX_NOTIFICATIONS) {\n evictedInternalId = evictOldest();\n }\n\n // Start timer for the new notification\n const duration = getDuration(options);\n\n if (duration != null && duration > 0) {\n timersRef.current?.startNotificationTimer(internalId, id, duration);\n }\n\n setNotifications((prev) => {\n let next = prev;\n\n if (evictedInternalId) {\n next = next.map((n) =>\n n.internalId === evictedInternalId ? { ...n, isExiting: true } : n,\n );\n }\n\n return [...next, newNotification];\n });\n\n return id;\n },\n );\n\n // ─── Update ─────────────────────────────────────────────────────\n\n const updateNotification = useEvent(\n (id: Key, options: Partial<OverlayNotificationOptions>) => {\n setNotifications((prev) =>\n prev.map((n) =>\n matchesNotificationId(n, id)\n ? { ...n, ...options, updatedAt: Date.now() }\n : n,\n ),\n );\n },\n );\n\n // ─── Owner Cleanup ──────────────────────────────────────────────\n\n const removeByOwner = useEvent((ownerId: string) => {\n // Clear timers outside the updater (StrictMode-safe).\n const owned = notificationsRef.current.filter(\n (n) => n.ownerId === ownerId && !n.isExiting,\n );\n\n for (const n of owned) {\n timersRef.current?.clearNotificationTimer(n.internalId);\n }\n\n setNotifications((prev) =>\n prev.map((n) => {\n if (n.ownerId === ownerId && !n.isExiting) {\n return { ...n, isExiting: true };\n }\n return n;\n }),\n );\n });\n\n return {\n notifications,\n notificationsRef,\n addNotification,\n removeNotification,\n restoreNotification,\n updateNotification,\n finalizeNotificationRemoval,\n removeByOwner,\n };\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-b2f8ae7 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-26fe35d | Cube Dev Team */
2
2
  import { useEvent } from "../../../_internal/hooks/use-event.js";
3
3
  import { useWarn } from "../../../_internal/hooks/use-warn.js";
4
4
  import { useNotificationContext } from "./NotificationContext.js";
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-b2f8ae7 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-26fe35d | Cube Dev Team */
2
2
  import { useEvent } from "../../../_internal/hooks/use-event.js";
3
3
  import { useEffect, useRef } from "react";
4
4
 
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-b2f8ae7 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-26fe35d | Cube Dev Team */
2
2
  import { usePersistentNotificationsContext } from "./NotificationContext.js";
3
3
  import { useMemo } from "react";
4
4
 
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-b2f8ae7 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-26fe35d | Cube Dev Team */
2
2
  import { useEvent } from "../../../_internal/hooks/use-event.js";
3
3
  import { cleanupAndGetValidIds, saveDismissedId } from "./dismissed-storage.js";
4
4
  import { useRef, useState } from "react";
@@ -62,6 +62,13 @@ function usePersistentState(maxItems) {
62
62
  saveDismissedPersistentId: useEvent((id) => {
63
63
  dismissedPersistentIdsRef.current.add(String(id));
64
64
  saveDismissedId(id);
65
+ }),
66
+ undoFullyDismissedId: useEvent((id) => {
67
+ fullyDismissedIdsRef.current.delete(String(id));
68
+ }),
69
+ removePersistentItemSilently: useEvent((id) => {
70
+ dismissedPersistentIdsRef.current.delete(String(id));
71
+ setPersistentItems((prev) => prev.filter((i) => i.id !== id));
65
72
  })
66
73
  };
67
74
  }