@cube-dev/ui-kit 0.206.3 → 0.208.0
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.
- package/dist/CHANGELOG.md +18 -0
- package/dist/_internal/hooks/use-debounced-value.js +1 -1
- package/dist/_internal/hooks/use-deprecation-warning.js +1 -1
- package/dist/_internal/hooks/use-event.js +1 -1
- package/dist/_internal/hooks/use-is-first-render.js +1 -1
- package/dist/_internal/hooks/use-sync-ref.js +1 -1
- package/dist/_internal/hooks/use-sync-ref.js.map +1 -1
- package/dist/_internal/hooks/use-timer/timer.js +1 -1
- package/dist/_internal/hooks/use-timer/use-timer.js +1 -1
- package/dist/_internal/hooks/use-warn.js +1 -1
- package/dist/components/Block.js +1 -1
- package/dist/components/CollectionItem.d.ts +0 -2
- package/dist/components/CollectionItem.js +1 -1
- package/dist/components/CollectionItem.js.map +1 -1
- package/dist/components/GlobalStyles.js +1 -1
- package/dist/components/GlobalStyles.js.map +1 -1
- package/dist/components/GridProvider.js +1 -1
- package/dist/components/GridProvider.js.map +1 -1
- package/dist/components/HiddenInput.js +1 -1
- package/dist/components/Root.js +3 -3
- package/dist/components/Root.js.map +1 -1
- package/dist/components/actions/Action/Action.js +1 -1
- package/dist/components/actions/Banner/Banner.js +1 -1
- package/dist/components/actions/Banner/Banner.js.map +1 -1
- package/dist/components/actions/Button/Button.d.ts +10 -1
- package/dist/components/actions/Button/Button.js +13 -8
- package/dist/components/actions/Button/Button.js.map +1 -1
- package/dist/components/actions/Button/index.d.ts +16 -1
- package/dist/components/actions/Button/index.js +13 -0
- package/dist/components/actions/Button/index.js.map +1 -0
- package/dist/components/actions/ButtonGroup/ButtonGroup.js +1 -1
- package/dist/components/actions/ButtonGroup/ButtonGroup.js.map +1 -1
- package/dist/components/actions/ButtonSplit/ButtonSplit.js +1 -1
- package/dist/components/actions/ButtonSplit/ButtonSplit.js.map +1 -1
- package/dist/components/actions/ButtonSplit/context.js +1 -1
- package/dist/components/actions/CommandMenu/CommandMenu.d.ts +1 -1
- package/dist/components/actions/CommandMenu/CommandMenu.js +1 -1
- package/dist/components/actions/CommandMenu/CommandMenu.js.map +1 -1
- package/dist/components/actions/CommandMenu/styled.js +1 -1
- package/dist/components/actions/ItemAction/ItemAction.js +2 -2
- package/dist/components/actions/ItemAction/ItemAction.js.map +1 -1
- package/dist/components/actions/ItemActionContext.js +1 -1
- package/dist/components/actions/ItemActionsWrapper.js +1 -1
- package/dist/components/actions/ItemButton/ItemButton.d.ts +0 -2
- package/dist/components/actions/ItemButton/ItemButton.js +2 -2
- package/dist/components/actions/ItemButton/ItemButton.js.map +1 -1
- package/dist/components/actions/Link/Link.js +1 -1
- package/dist/components/actions/Menu/Menu.d.ts +1 -1
- package/dist/components/actions/Menu/Menu.js +1 -1
- package/dist/components/actions/Menu/Menu.js.map +1 -1
- package/dist/components/actions/Menu/MenuCollectionItem.js +1 -1
- package/dist/components/actions/Menu/MenuItem.js +2 -2
- package/dist/components/actions/Menu/MenuItem.js.map +1 -1
- package/dist/components/actions/Menu/MenuSection.js +1 -1
- package/dist/components/actions/Menu/MenuTrigger.js +3 -3
- package/dist/components/actions/Menu/MenuTrigger.js.map +1 -1
- package/dist/components/actions/Menu/SubMenuTrigger.js +2 -2
- package/dist/components/actions/Menu/SubMenuTrigger.js.map +1 -1
- package/dist/components/actions/Menu/SubmenuTriggerContext.js +1 -1
- package/dist/components/actions/Menu/context.js +1 -1
- package/dist/components/actions/Menu/index.d.ts +1 -1
- package/dist/components/actions/Menu/styled.js +1 -1
- package/dist/components/actions/actions-run.js +1 -1
- package/dist/components/actions/index.d.ts +6 -18
- package/dist/components/actions/use-action.js +2 -2
- package/dist/components/actions/use-action.js.map +1 -1
- package/dist/components/actions/use-anchored-menu.d.ts +0 -1
- package/dist/components/actions/use-anchored-menu.js +2 -2
- package/dist/components/actions/use-anchored-menu.js.map +1 -1
- package/dist/components/actions/use-context-menu.d.ts +0 -1
- package/dist/components/actions/use-context-menu.js +2 -2
- package/dist/components/actions/use-context-menu.js.map +1 -1
- package/dist/components/content/ActiveZone/ActiveZone.js +1 -1
- package/dist/components/content/ActiveZone/ActiveZone.js.map +1 -1
- package/dist/components/content/Alert/Alert.js +1 -1
- package/dist/components/content/Alert/use-alert.js +1 -1
- package/dist/components/content/Alert/use-alert.js.map +1 -1
- package/dist/components/content/Avatar/Avatar.js +1 -1
- package/dist/components/content/Badge/Badge.d.ts +0 -1
- package/dist/components/content/Badge/Badge.js +1 -1
- package/dist/components/content/Badge/Badge.js.map +1 -1
- package/dist/components/content/Card/Card.js +1 -1
- package/dist/components/content/Content.js +1 -1
- package/dist/components/content/Content.js.map +1 -1
- package/dist/components/content/CopyPasteBlock/CopyPasteBlock.js +3 -3
- package/dist/components/content/CopyPasteBlock/CopyPasteBlock.js.map +1 -1
- package/dist/components/content/CopySnippet/CopySnippet.d.ts +2 -18
- package/dist/components/content/CopySnippet/CopySnippet.js +2 -2
- package/dist/components/content/CopySnippet/CopySnippet.js.map +1 -1
- package/dist/components/content/Disclosure/Disclosure.d.ts +0 -1
- package/dist/components/content/Disclosure/Disclosure.js +2 -2
- package/dist/components/content/Disclosure/Disclosure.js.map +1 -1
- package/dist/components/content/Divider/Divider.js +1 -1
- package/dist/components/content/Divider/Divider.js.map +1 -1
- package/dist/components/content/Footer.js +1 -1
- package/dist/components/content/Footer.js.map +1 -1
- package/dist/components/content/Header.js +1 -1
- package/dist/components/content/Header.js.map +1 -1
- package/dist/components/content/HotKeys/HotKeys.js +1 -1
- package/dist/components/content/HotKeys/HotKeys.js.map +1 -1
- package/dist/components/content/InfoBadge/InfoBadge.js +1 -1
- package/dist/components/content/InfoBadge/InfoBadge.js.map +1 -1
- package/dist/components/content/InlineInput/InlineInput.js +1 -1
- package/dist/components/content/InlineInput/InlineInput.js.map +1 -1
- package/dist/components/content/Item/Item.d.ts +1 -2
- package/dist/components/content/Item/Item.js +4 -4
- package/dist/components/content/Item/Item.js.map +1 -1
- package/dist/components/content/Item/ItemWithNativeLinks.js +2 -2
- package/dist/components/content/Item/index.d.ts +1 -1
- package/dist/components/content/ItemBadge/ItemBadge.js +1 -1
- package/dist/components/content/ItemBadge/index.d.ts +1 -2
- package/dist/components/content/ItemCard/ItemCard.js +1 -1
- package/dist/components/content/Layout/GridLayout.js +1 -1
- package/dist/components/content/Layout/Layout.js +1 -1
- package/dist/components/content/Layout/Layout.js.map +1 -1
- package/dist/components/content/Layout/LayoutBlock.js +1 -1
- package/dist/components/content/Layout/LayoutCenter.js +1 -1
- package/dist/components/content/Layout/LayoutContainer.js +1 -1
- package/dist/components/content/Layout/LayoutContainer.js.map +1 -1
- package/dist/components/content/Layout/LayoutContent.js +1 -1
- package/dist/components/content/Layout/LayoutContent.js.map +1 -1
- package/dist/components/content/Layout/LayoutContext.js +1 -1
- package/dist/components/content/Layout/LayoutContext.js.map +1 -1
- package/dist/components/content/Layout/LayoutFlex.js +1 -1
- package/dist/components/content/Layout/LayoutFooter.js +1 -1
- package/dist/components/content/Layout/LayoutGrid.js +1 -1
- package/dist/components/content/Layout/LayoutHeader.js +1 -1
- package/dist/components/content/Layout/LayoutHeader.js.map +1 -1
- package/dist/components/content/Layout/LayoutPane.js +2 -2
- package/dist/components/content/Layout/LayoutPane.js.map +1 -1
- package/dist/components/content/Layout/LayoutPanel.js +3 -3
- package/dist/components/content/Layout/LayoutPanel.js.map +1 -1
- package/dist/components/content/Layout/LayoutPanelHeader.js +1 -1
- package/dist/components/content/Layout/LayoutPanelHeader.js.map +1 -1
- package/dist/components/content/Layout/LayoutPanelTransition.js +1 -1
- package/dist/components/content/Layout/LayoutToolbar.js +1 -1
- package/dist/components/content/Layout/hooks/useTinyScrollbar.js +1 -1
- package/dist/components/content/Layout/index.js +1 -1
- package/dist/components/content/Layout/utils.js +1 -1
- package/dist/components/content/Paragraph.js +1 -1
- package/dist/components/content/Placeholder/Placeholder.js +1 -1
- package/dist/components/content/Placeholder/Placeholder.js.map +1 -1
- package/dist/components/content/PrismCode/PrismCode.js +1 -1
- package/dist/components/content/PrismCode/prismSetup.js +1 -1
- package/dist/components/content/PrismDiffCode/PrismDiffCode.js +1 -1
- package/dist/components/content/Result/Result.js +2 -2
- package/dist/components/content/Result/Result.js.map +1 -1
- package/dist/components/content/Skeleton/Skeleton.js +1 -1
- package/dist/components/content/Skeleton/Skeleton.js.map +1 -1
- package/dist/components/content/Tag/Tag.d.ts +0 -1
- package/dist/components/content/Tag/Tag.js +1 -1
- package/dist/components/content/Tag/Tag.js.map +1 -1
- package/dist/components/content/Text.js +1 -1
- package/dist/components/content/TextItem/TextItem.js +1 -1
- package/dist/components/content/Title.js +1 -1
- package/dist/components/content/Title.js.map +1 -1
- package/dist/components/content/Tree/Tree.js +1 -1
- package/dist/components/content/Tree/Tree.js.map +1 -1
- package/dist/components/content/Tree/TreeNode.js +5 -5
- package/dist/components/content/Tree/TreeNode.js.map +1 -1
- package/dist/components/content/Tree/checked-keys.js +1 -1
- package/dist/components/content/Tree/rowId.js +1 -1
- package/dist/components/content/Tree/styled.js +1 -1
- package/dist/components/content/Tree/styled.js.map +1 -1
- package/dist/components/content/Tree/tree-index.js +1 -1
- package/dist/components/content/Tree/types.d.ts +1 -1
- package/dist/components/content/Tree/use-checkbox-tree.js +1 -1
- package/dist/components/content/Tree/use-checkbox-tree.js.map +1 -1
- package/dist/components/content/Tree/use-load-data.js +1 -1
- package/dist/components/content/Tree/use-load-data.js.map +1 -1
- package/dist/components/content/highlightText.js +1 -1
- package/dist/components/content/use-auto-tooltip.js +1 -1
- package/dist/components/data/DataTable/DataTable.js +1 -1
- package/dist/components/data/DataTable/DataTable.js.map +1 -1
- package/dist/components/data/ItemTable/ItemTable.js +1 -1
- package/dist/components/data/ItemTable/ItemTable.js.map +1 -1
- package/dist/components/data/ItemTable/ItemTableBulkBar.js +2 -2
- package/dist/components/data/ItemTable/ItemTableBulkBar.js.map +1 -1
- package/dist/components/data/ItemTable/ItemTableDragPreview.js +1 -1
- package/dist/components/data/ItemTable/ItemTableDragPreview.js.map +1 -1
- package/dist/components/data/ItemTable/ItemTableFooter.js +1 -1
- package/dist/components/data/ItemTable/ItemTableFooter.js.map +1 -1
- package/dist/components/data/ItemTable/ItemTableToolbar.js +2 -2
- package/dist/components/data/ItemTable/ItemTableToolbar.js.map +1 -1
- package/dist/components/data/ItemTable/item-table-sections.js +1 -1
- package/dist/components/data/ItemTable/use-item-table-column-widths.js +1 -1
- package/dist/components/data/ItemTable/use-item-table-drag-drop.js +1 -1
- package/dist/components/data/ItemTable/use-item-table-pagination.js +1 -1
- package/dist/components/data/ItemTable/use-item-table-selection.js +1 -1
- package/dist/components/data/ItemTable/use-item-table-sort.js +1 -1
- package/dist/components/data/ItemTable/use-item-table-tree-model.js +1 -1
- package/dist/components/data/TableBase/ColumnResizer.js +1 -1
- package/dist/components/data/TableBase/ColumnResizer.js.map +1 -1
- package/dist/components/data/TableBase/RowCollection.js +1 -1
- package/dist/components/data/TableBase/TableHeaderCell.js +1 -1
- package/dist/components/data/TableBase/TableHeaderCell.js.map +1 -1
- package/dist/components/data/TableBase/TableRow.js +1 -1
- package/dist/components/data/TableBase/TableRow.js.map +1 -1
- package/dist/components/data/TableBase/TableRowLink.js +1 -1
- package/dist/components/data/TableBase/TableView.js +6 -6
- package/dist/components/data/TableBase/TableView.js.map +1 -1
- package/dist/components/data/TableBase/TreeGridTable.js +1 -1
- package/dist/components/data/TableBase/column-header.js +1 -1
- package/dist/components/data/TableBase/column-menu.js +1 -1
- package/dist/components/data/TableBase/column-menu.js.map +1 -1
- package/dist/components/data/TableBase/column-styles.js +1 -1
- package/dist/components/data/TableBase/column-tint.js +1 -1
- package/dist/components/data/TableBase/row-menu.js +1 -1
- package/dist/components/data/TableBase/styled.js +1 -1
- package/dist/components/data/TableBase/styled.js.map +1 -1
- package/dist/components/data/TableBase/table-body-sections.js +1 -1
- package/dist/components/data/TableBase/table-tree.js +1 -1
- package/dist/components/data/TableBase/types.js +1 -1
- package/dist/components/data/TableBase/use-cell-selection.js +0 -0
- package/dist/components/data/TableBase/use-cell-selection.js.map +1 -1
- package/dist/components/data/TableBase/use-column-menu.js +2 -2
- package/dist/components/data/TableBase/use-column-order.js +1 -1
- package/dist/components/data/TableBase/use-column-order.js.map +1 -1
- package/dist/components/data/TableBase/use-column-window.js +1 -1
- package/dist/components/data/TableBase/use-container-width.js +1 -1
- package/dist/components/data/TableBase/use-row-move-animation.js +1 -1
- package/dist/components/data/TableBase/use-scrollability.js +1 -1
- package/dist/components/data/TableBase/use-table-columns.js +1 -1
- package/dist/components/data/TableBase/use-table-search.js +1 -1
- package/dist/components/data/TableBase/use-table-selection.js +1 -1
- package/dist/components/data/TableBase/use-table-selection.js.map +1 -1
- package/dist/components/data/TableBase/use-table-sort.js +1 -1
- package/dist/components/data/TableBase/use-table-sort.js.map +1 -1
- package/dist/components/data/TableBase/use-table-sorts.js +1 -1
- package/dist/components/data/TableBase/use-table-sorts.js.map +1 -1
- package/dist/components/data/TableBase/use-table-storage.js +1 -1
- package/dist/components/data/TableBase/use-table-tooltip-refresh.js +1 -1
- package/dist/components/data/TableBase/use-table-tree-state.js +1 -1
- package/dist/components/data/TableBase/use-table-tree-state.js.map +1 -1
- package/dist/components/fields/Checkbox/Checkbox.d.ts +0 -1
- package/dist/components/fields/Checkbox/Checkbox.js +3 -3
- package/dist/components/fields/Checkbox/Checkbox.js.map +1 -1
- package/dist/components/fields/Checkbox/CheckboxGroup.d.ts +0 -1
- package/dist/components/fields/Checkbox/CheckboxGroup.js +3 -3
- package/dist/components/fields/Checkbox/CheckboxGroup.js.map +1 -1
- package/dist/components/fields/Checkbox/context.js +1 -1
- package/dist/components/fields/ColorInput/ColorInput.d.ts +0 -1
- package/dist/components/fields/ColorInput/ColorInput.js +1 -1
- package/dist/components/fields/ColorInput/ColorInput.js.map +1 -1
- package/dist/components/fields/ColorPicker/ColorPicker.d.ts +0 -3
- package/dist/components/fields/ColorPicker/ColorPicker.js +3 -3
- package/dist/components/fields/ColorPicker/ColorPicker.js.map +1 -1
- package/dist/components/fields/ColorSwatch/ColorSwatch.js +1 -1
- package/dist/components/fields/ColorSwatchGroup/ColorSwatchGroup.d.ts +0 -1
- package/dist/components/fields/ColorSwatchGroup/ColorSwatchGroup.js +2 -2
- package/dist/components/fields/ColorSwatchGroup/ColorSwatchGroup.js.map +1 -1
- package/dist/components/fields/ComboBox/ComboBox.d.ts +0 -1
- package/dist/components/fields/ComboBox/ComboBox.js +6 -6
- package/dist/components/fields/ComboBox/ComboBox.js.map +1 -1
- package/dist/components/fields/ComboBox/comboBoxOptions.js +1 -1
- package/dist/components/fields/CommandTextArea/CommandTextArea.d.ts +1 -2
- package/dist/components/fields/CommandTextArea/CommandTextArea.js +2 -2
- package/dist/components/fields/CommandTextArea/CommandTextArea.js.map +1 -1
- package/dist/components/fields/CommandTextArea/caretPosition.js +1 -1
- package/dist/components/fields/CommandTextArea/useCaretAnchor.js +1 -1
- package/dist/components/fields/DatePicker/CalendarPopover.js +1 -1
- package/dist/components/fields/DatePicker/DateInput.d.ts +0 -1
- package/dist/components/fields/DatePicker/DateInput.js +2 -2
- package/dist/components/fields/DatePicker/DateInput.js.map +1 -1
- package/dist/components/fields/DatePicker/DateInputBase.js +1 -1
- package/dist/components/fields/DatePicker/DateInputBase.js.map +1 -1
- package/dist/components/fields/DatePicker/DatePicker.d.ts +0 -1
- package/dist/components/fields/DatePicker/DatePicker.js +2 -2
- package/dist/components/fields/DatePicker/DatePicker.js.map +1 -1
- package/dist/components/fields/DatePicker/DatePickerButton.js +1 -1
- package/dist/components/fields/DatePicker/DatePickerButton.js.map +1 -1
- package/dist/components/fields/DatePicker/DatePickerElement.js +1 -1
- package/dist/components/fields/DatePicker/DatePickerInput.js +1 -1
- package/dist/components/fields/DatePicker/DatePickerInput.js.map +1 -1
- package/dist/components/fields/DatePicker/DatePickerSegment.js +1 -1
- package/dist/components/fields/DatePicker/DateRangePicker.d.ts +0 -1
- package/dist/components/fields/DatePicker/DateRangePicker.js +2 -2
- package/dist/components/fields/DatePicker/DateRangePicker.js.map +1 -1
- package/dist/components/fields/DatePicker/DateRangeSeparatedPicker.d.ts +0 -1
- package/dist/components/fields/DatePicker/DateRangeSeparatedPicker.js +2 -2
- package/dist/components/fields/DatePicker/DateRangeSeparatedPicker.js.map +1 -1
- package/dist/components/fields/DatePicker/MonthPicker.js +1 -1
- package/dist/components/fields/DatePicker/PeriodPicker.d.ts +0 -1
- package/dist/components/fields/DatePicker/PeriodPicker.js +2 -2
- package/dist/components/fields/DatePicker/PeriodPicker.js.map +1 -1
- package/dist/components/fields/DatePicker/QuarterPicker.js +1 -1
- package/dist/components/fields/DatePicker/TimeInput.d.ts +0 -1
- package/dist/components/fields/DatePicker/TimeInput.js +2 -2
- package/dist/components/fields/DatePicker/TimeInput.js.map +1 -1
- package/dist/components/fields/DatePicker/WeekPicker.js +1 -1
- package/dist/components/fields/DatePicker/YearPicker.js +1 -1
- package/dist/components/fields/DatePicker/parseDate.js +1 -1
- package/dist/components/fields/DatePicker/period.js +1 -1
- package/dist/components/fields/DatePicker/props.js +1 -1
- package/dist/components/fields/DatePicker/utils.js +1 -1
- package/dist/components/fields/FileInput/FileInput.d.ts +0 -1
- package/dist/components/fields/FileInput/FileInput.js +3 -3
- package/dist/components/fields/FileInput/FileInput.js.map +1 -1
- package/dist/components/fields/FilterListBox/FilterListBox.js +3 -3
- package/dist/components/fields/FilterListBox/FilterListBox.js.map +1 -1
- package/dist/components/fields/FilterListBox/styled.js +1 -1
- package/dist/components/fields/FilterPicker/FilterPicker.d.ts +0 -3
- package/dist/components/fields/FilterPicker/FilterPicker.js +8 -8
- package/dist/components/fields/FilterPicker/FilterPicker.js.map +1 -1
- package/dist/components/fields/FilterPicker/FilterTree.js +2 -2
- package/dist/components/fields/FilterPicker/FilterTree.js.map +1 -1
- package/dist/components/fields/Input/Input.d.ts +0 -1
- package/dist/components/fields/Input/Input.js +1 -1
- package/dist/components/fields/Input/Input.js.map +1 -1
- package/dist/components/fields/ListBox/DraggableListBox.js +1 -1
- package/dist/components/fields/ListBox/ListBox.js +4 -4
- package/dist/components/fields/ListBox/ListBox.js.map +1 -1
- package/dist/components/fields/ListBox/optionId.js +1 -1
- package/dist/components/fields/ListBoxPopover/ListBoxPopover.js +2 -2
- package/dist/components/fields/ListBoxPopover/ListBoxPopover.js.map +1 -1
- package/dist/components/fields/ListBoxPopover/listNavigation.js +1 -1
- package/dist/components/fields/ListBoxPopover/useCompositeFocus.js +1 -1
- package/dist/components/fields/ListBoxPopover/useCompositeFocus.js.map +1 -1
- package/dist/components/fields/NumberInput/NumberInput.js +1 -1
- package/dist/components/fields/NumberInput/NumberInput.js.map +1 -1
- package/dist/components/fields/NumberInput/StepButton.js +1 -1
- package/dist/components/fields/PasswordInput/PasswordInput.js +2 -2
- package/dist/components/fields/PasswordInput/PasswordInput.js.map +1 -1
- package/dist/components/fields/Picker/Picker.d.ts +0 -2
- package/dist/components/fields/Picker/Picker.js +8 -8
- package/dist/components/fields/Picker/Picker.js.map +1 -1
- package/dist/components/fields/RadioGroup/Radio.d.ts +0 -1
- package/dist/components/fields/RadioGroup/Radio.js +2 -2
- package/dist/components/fields/RadioGroup/Radio.js.map +1 -1
- package/dist/components/fields/RadioGroup/RadioGroup.d.ts +0 -1
- package/dist/components/fields/RadioGroup/RadioGroup.js +3 -3
- package/dist/components/fields/RadioGroup/RadioGroup.js.map +1 -1
- package/dist/components/fields/RadioGroup/context.js +1 -1
- package/dist/components/fields/SearchComboBox/SearchComboBox.d.ts +0 -1
- package/dist/components/fields/SearchComboBox/SearchComboBox.js +6 -6
- package/dist/components/fields/SearchComboBox/SearchComboBox.js.map +1 -1
- package/dist/components/fields/SearchInput/SearchInput.js +2 -2
- package/dist/components/fields/SearchInput/SearchInput.js.map +1 -1
- package/dist/components/fields/Select/Select.d.ts +1 -2
- package/dist/components/fields/Select/Select.js +7 -7
- package/dist/components/fields/Select/Select.js.map +1 -1
- package/dist/components/fields/Slider/Gradation.js +1 -1
- package/dist/components/fields/Slider/HueSlider.js +1 -1
- package/dist/components/fields/Slider/RangeSlider.js +1 -1
- package/dist/components/fields/Slider/Slider.js +1 -1
- package/dist/components/fields/Slider/Slider.js.map +1 -1
- package/dist/components/fields/Slider/SliderBase.js +2 -2
- package/dist/components/fields/Slider/SliderBase.js.map +1 -1
- package/dist/components/fields/Slider/SliderThumb.js +1 -1
- package/dist/components/fields/Slider/SliderThumb.js.map +1 -1
- package/dist/components/fields/Slider/SliderTrack.js +1 -1
- package/dist/components/fields/Slider/SliderTrack.js.map +1 -1
- package/dist/components/fields/Slider/elements.js +1 -1
- package/dist/components/fields/Slider/index.js +2 -2
- package/dist/components/fields/Slider/types.d.ts +0 -1
- package/dist/components/fields/Switch/Switch.d.ts +0 -1
- package/dist/components/fields/Switch/Switch.js +3 -3
- package/dist/components/fields/Switch/Switch.js.map +1 -1
- package/dist/components/fields/TagInput/TagInput.js +5 -5
- package/dist/components/fields/TagInput/TagInput.js.map +1 -1
- package/dist/components/fields/TagInput/TagList.js +1 -1
- package/dist/components/fields/TagInput/TagList.js.map +1 -1
- package/dist/components/fields/TagInput/useActiveOption.js +1 -1
- package/dist/components/fields/TagInput/useTagError.js +1 -1
- package/dist/components/fields/TextArea/TextArea.js +2 -2
- package/dist/components/fields/TextArea/TextArea.js.map +1 -1
- package/dist/components/fields/TextInput/TextInput.js +2 -2
- package/dist/components/fields/TextInput/TextInput.js.map +1 -1
- package/dist/components/fields/TextInput/TextInputBase.d.ts +0 -1
- package/dist/components/fields/TextInput/TextInputBase.js +3 -3
- package/dist/components/fields/TextInput/TextInputBase.js.map +1 -1
- package/dist/components/fields/TextInput/displayed-validation.js +1 -1
- package/dist/components/fields/TextInput/useAutoSizeTextArea.js +1 -1
- package/dist/components/fields/TextInput/useAutoSizeTextArea.js.map +1 -1
- package/dist/components/fields/TextInputMapper/TextInputMapper.d.ts +0 -1
- package/dist/components/fields/TextInputMapper/TextInputMapper.js +3 -3
- package/dist/components/fields/TextInputMapper/TextInputMapper.js.map +1 -1
- package/dist/components/fields/TriggerActions.js +1 -1
- package/dist/components/fields/color/ColorPanel.js +1 -1
- package/dist/components/fields/color/ColorPanel.js.map +1 -1
- package/dist/components/fields/color/channels.js +1 -1
- package/dist/components/fields/color/color.js +1 -1
- package/dist/components/fields/color/context.js +1 -1
- package/dist/components/fields/index.d.ts +2 -2
- package/dist/components/fields/option-origin-press.js +1 -1
- package/dist/components/form/FieldWrapper/FieldWrapper.js +2 -2
- package/dist/components/form/FieldWrapper/FieldWrapper.js.map +1 -1
- package/dist/components/form/FieldWrapper/field-description.js +1 -1
- package/dist/components/form/FieldWrapper/types.d.ts +0 -1
- package/dist/components/form/Form/Field.d.ts +0 -1
- package/dist/components/form/Form/Field.js +3 -3
- package/dist/components/form/Form/Field.js.map +1 -1
- package/dist/components/form/Form/Form.d.ts +1 -26
- package/dist/components/form/Form/Form.js +7 -116
- package/dist/components/form/Form/Form.js.map +1 -1
- package/dist/components/form/Form/FormContext.d.ts +30 -0
- package/dist/components/form/Form/FormContext.js +79 -0
- package/dist/components/form/Form/FormContext.js.map +1 -0
- package/dist/components/form/Form/FormElement.js +49 -0
- package/dist/components/form/Form/FormElement.js.map +1 -0
- package/dist/components/form/Form/ModernFormRoot.js +3 -2
- package/dist/components/form/Form/ModernFormRoot.js.map +1 -1
- package/dist/components/form/Form/ResetButton/ResetButton.js +2 -2
- package/dist/components/form/Form/ResetButton/ResetButton.js.map +1 -1
- package/dist/components/form/Form/SubmitButton/SubmitButton.js +2 -2
- package/dist/components/form/Form/SubmitButton/SubmitButton.js.map +1 -1
- package/dist/components/form/Form/SubmitError.d.ts +0 -1
- package/dist/components/form/Form/SubmitError.js +3 -3
- package/dist/components/form/Form/SubmitError.js.map +1 -1
- package/dist/components/form/Form/backend.js +1 -1
- package/dist/components/form/Form/index.d.ts +2 -1
- package/dist/components/form/Form/index.js +6 -5
- package/dist/components/form/Form/index.js.map +1 -1
- package/dist/components/form/Form/modern/actions.js +1 -1
- package/dist/components/form/Form/modern/context.js +1 -1
- package/dist/components/form/Form/modern/controller.js +1 -1
- package/dist/components/form/Form/modern/field-binding.js +1 -1
- package/dist/components/form/Form/modern/field.js +1 -1
- package/dist/components/form/Form/modern/react.js +1 -1
- package/dist/components/form/Form/modern/store.js +1 -1
- package/dist/components/form/Form/modern/validation.js +1 -1
- package/dist/components/form/Form/modern/values.js +1 -1
- package/dist/components/form/Form/reset-unbound-controls.js +1 -1
- package/dist/components/form/Form/use-field/types.d.ts +0 -1
- package/dist/components/form/Form/use-field/use-field-binding.js +2 -2
- package/dist/components/form/Form/use-field/use-field-props.js +4 -4
- package/dist/components/form/Form/use-field/use-field-props.js.map +1 -1
- package/dist/components/form/Form/use-field/use-field.d.ts +0 -1
- package/dist/components/form/Form/use-field/use-field.js +2 -2
- package/dist/components/form/Form/use-field/use-field.js.map +1 -1
- package/dist/components/form/Form/use-form.js +1 -1
- package/dist/components/form/Form/validation.js +1 -1
- package/dist/components/form/Label.d.ts +0 -1
- package/dist/components/form/Label.js +1 -1
- package/dist/components/form/Label.js.map +1 -1
- package/dist/components/form/field-chrome.js +1 -1
- package/dist/components/form/field-layout.js +1 -1
- package/dist/components/form/field-layout.js.map +1 -1
- package/dist/components/form/index.d.ts +2 -1
- package/dist/components/form/legacy-tooltip.js +1 -1
- package/dist/components/form/validation/ValidationIndicator.d.ts +0 -1
- package/dist/components/form/validation/ValidationIndicator.js +1 -1
- package/dist/components/form/validation/ValidationIndicator.js.map +1 -1
- package/dist/components/form/validation/resolve-validation-props.d.ts +0 -1
- package/dist/components/form/validation/resolve-validation-props.js +1 -1
- package/dist/components/form/validation/resolve-validation-props.js.map +1 -1
- package/dist/components/form/validation/use-validation-props.js +1 -1
- package/dist/components/form/validation/use-validation-props.js.map +1 -1
- package/dist/components/form/wrapper.d.ts +0 -1
- package/dist/components/form/wrapper.js +1 -1
- package/dist/components/form/wrapper.js.map +1 -1
- package/dist/components/helpers/DisplayTransition/DisplayTransition.js +1 -1
- package/dist/components/helpers/IconSwitch/IconSwitch.js +1 -1
- package/dist/components/layout/Flex.js +1 -1
- package/dist/components/layout/Flow.js +1 -1
- package/dist/components/layout/Grid.js +1 -1
- package/dist/components/layout/Panel.js +1 -1
- package/dist/components/layout/Prefix.js +1 -1
- package/dist/components/layout/Prefix.js.map +1 -1
- package/dist/components/layout/ResizablePanel.js +2 -2
- package/dist/components/layout/Space.js +1 -1
- package/dist/components/layout/Suffix.js +1 -1
- package/dist/components/layout/Suffix.js.map +1 -1
- package/dist/components/navigation/Pagination/Pagination.js +3 -3
- package/dist/components/navigation/Pagination/Pagination.js.map +1 -1
- package/dist/components/navigation/Pagination/use-pagination.js +1 -1
- package/dist/components/navigation/Pagination/use-pagination.js.map +1 -1
- package/dist/components/navigation/Tabs/BoardDragActiveProvider.js +1 -1
- package/dist/components/navigation/Tabs/DraggableTabList.js +1 -1
- package/dist/components/navigation/Tabs/TabButton.js +4 -4
- package/dist/components/navigation/Tabs/TabButton.js.map +1 -1
- package/dist/components/navigation/Tabs/TabDropIndicator.js +1 -1
- package/dist/components/navigation/Tabs/TabPanel.js +1 -1
- package/dist/components/navigation/Tabs/TabPicker.js +1 -1
- package/dist/components/navigation/Tabs/TabPicker.js.map +1 -1
- package/dist/components/navigation/Tabs/Tabs.js +2 -2
- package/dist/components/navigation/Tabs/Tabs.js.map +1 -1
- package/dist/components/navigation/Tabs/TabsAction.js +1 -1
- package/dist/components/navigation/Tabs/TabsContext.js +1 -1
- package/dist/components/navigation/Tabs/popover-placement.js +1 -1
- package/dist/components/navigation/Tabs/segmented-styles.js +1 -1
- package/dist/components/navigation/Tabs/styled.js +1 -1
- package/dist/components/navigation/Tabs/styled.js.map +1 -1
- package/dist/components/navigation/Tabs/types.d.ts +2 -2
- package/dist/components/navigation/Tabs/types.js +1 -1
- package/dist/components/navigation/Tabs/use-tab-editing.js +1 -1
- package/dist/components/navigation/Tabs/use-tab-indicator.js +1 -1
- package/dist/components/organisms/StatsCard/StatsCard.js +1 -1
- package/dist/components/other/Calendar/Calendar.js +1 -1
- package/dist/components/other/Calendar/CalendarCell.js +1 -1
- package/dist/components/other/Calendar/CalendarGrid.js +1 -1
- package/dist/components/other/Calendar/CalendarHeader.js +2 -2
- package/dist/components/other/Calendar/CalendarHeader.js.map +1 -1
- package/dist/components/other/Calendar/CalendarPanel.js +1 -1
- package/dist/components/other/Calendar/CalendarPanel.js.map +1 -1
- package/dist/components/other/Calendar/PeriodCalendar.js +1 -1
- package/dist/components/other/Calendar/PeriodCalendar.js.map +1 -1
- package/dist/components/other/Calendar/PeriodGrid.js +1 -1
- package/dist/components/other/Calendar/RangeCalendar.js +1 -1
- package/dist/components/other/Calendar/styled.js +1 -1
- package/dist/components/other/CubeLogo/CubeLogo.js +1 -1
- package/dist/components/other/NoDataIcon/NoDataIcon.js +1 -1
- package/dist/components/overlays/AlertDialog/AlertDialog.js +2 -2
- package/dist/components/overlays/AlertDialog/AlertDialog.js.map +1 -1
- package/dist/components/overlays/AlertDialog/AlertDialogApiProvider.js +1 -1
- package/dist/components/overlays/AlertDialog/AlertDialogZone.js +1 -1
- package/dist/components/overlays/AlertDialog/AlertDialogZone.js.map +1 -1
- package/dist/components/overlays/AlertDialog/types.d.ts +0 -1
- package/dist/components/overlays/Dialog/Dialog.js +2 -2
- package/dist/components/overlays/Dialog/Dialog.js.map +1 -1
- package/dist/components/overlays/Dialog/DialogContainer.js +1 -1
- package/dist/components/overlays/Dialog/DialogForm.js +2 -2
- package/dist/components/overlays/Dialog/DialogForm.js.map +1 -1
- package/dist/components/overlays/Dialog/DialogTrigger.d.ts +0 -1
- package/dist/components/overlays/Dialog/DialogTrigger.js +5 -5
- package/dist/components/overlays/Dialog/DialogTrigger.js.map +1 -1
- package/dist/components/overlays/Dialog/ModernDialogForm.js +2 -2
- package/dist/components/overlays/Dialog/ModernDialogForm.js.map +1 -1
- package/dist/components/overlays/Dialog/context.js +1 -1
- package/dist/components/overlays/Dialog/default-button-text.js +1 -1
- package/dist/components/overlays/Dialog/use-content-overflow.js +1 -1
- package/dist/components/overlays/Dialog/use-dialog-container.js +1 -1
- package/dist/components/overlays/Dialog/use-dialog-container.js.map +1 -1
- package/dist/components/overlays/Dialog/use-dialog-open-sync.js +1 -1
- package/dist/components/overlays/Dialog/use-dismiss-confirmation.js +1 -1
- package/dist/components/overlays/Dialog/use-dismiss-confirmation.js.map +1 -1
- package/dist/components/overlays/Dialog/use-retained-dialog-focus.js +1 -1
- package/dist/components/overlays/Modal/Modal.js +2 -2
- package/dist/components/overlays/Modal/Modal.js.map +1 -1
- package/dist/components/overlays/Modal/OpenTransitionContext.js +1 -1
- package/dist/components/overlays/Modal/OpenTransitionContext.js.map +1 -1
- package/dist/components/overlays/Modal/Overlay.js +1 -1
- package/dist/components/overlays/Modal/Overlay.js.map +1 -1
- package/dist/components/overlays/Modal/Popover.js +2 -2
- package/dist/components/overlays/Modal/Popover.js.map +1 -1
- package/dist/components/overlays/Modal/Tray.js +2 -2
- package/dist/components/overlays/Modal/Tray.js.map +1 -1
- package/dist/components/overlays/Modal/Underlay.js +1 -1
- package/dist/components/overlays/Modal/modal-containment.js +1 -1
- package/dist/components/overlays/Notifications/Notification.js +1 -1
- package/dist/components/overlays/Notifications/NotificationAction.js +1 -1
- package/dist/components/overlays/Notifications/NotificationAction.js.map +1 -1
- package/dist/components/overlays/Notifications/NotificationCard.js +1 -1
- package/dist/components/overlays/Notifications/NotificationCard.js.map +1 -1
- package/dist/components/overlays/Notifications/NotificationContext.js +1 -1
- package/dist/components/overlays/Notifications/NotificationItem.js +1 -1
- package/dist/components/overlays/Notifications/NotificationItem.js.map +1 -1
- package/dist/components/overlays/Notifications/OverlayContainer.js +2 -2
- package/dist/components/overlays/Notifications/OverlayContainer.js.map +1 -1
- package/dist/components/overlays/Notifications/OverlayProvider.js +1 -1
- package/dist/components/overlays/Notifications/PersistentNotificationsList.js +1 -1
- package/dist/components/overlays/Notifications/PersistentNotificationsList.js.map +1 -1
- package/dist/components/overlays/Notifications/dismissed-storage.js +1 -1
- package/dist/components/overlays/Notifications/format-relative-time.js +1 -1
- package/dist/components/overlays/Notifications/index.js +1 -1
- package/dist/components/overlays/Notifications/use-notification-state.js +1 -1
- package/dist/components/overlays/Notifications/use-notification-state.js.map +1 -1
- package/dist/components/overlays/Notifications/use-notifications.js +1 -1
- package/dist/components/overlays/Notifications/use-notifications.js.map +1 -1
- package/dist/components/overlays/Notifications/use-overlay-timers.js +1 -1
- package/dist/components/overlays/Notifications/use-overlay-timers.js.map +1 -1
- package/dist/components/overlays/Notifications/use-persistent-notifications.js +1 -1
- package/dist/components/overlays/Notifications/use-persistent-state.js +1 -1
- package/dist/components/overlays/Notifications/use-persistent-state.js.map +1 -1
- package/dist/components/overlays/Notifications/use-toast-state.js +1 -1
- package/dist/components/overlays/Notifications/use-toast-state.js.map +1 -1
- package/dist/components/overlays/Toast/ToastItem.js +1 -1
- package/dist/components/overlays/Toast/index.js +2 -2
- package/dist/components/overlays/Toast/useProgressToast.js +1 -1
- package/dist/components/overlays/Toast/useProgressToast.js.map +1 -1
- package/dist/components/overlays/Toast/useToast.js +2 -2
- package/dist/components/overlays/Tooltip/Tooltip.js +1 -1
- package/dist/components/overlays/Tooltip/Tooltip.js.map +1 -1
- package/dist/components/overlays/Tooltip/TooltipProvider.js +1 -1
- package/dist/components/overlays/Tooltip/TooltipTrigger.js +3 -3
- package/dist/components/overlays/Tooltip/TooltipTrigger.js.map +1 -1
- package/dist/components/overlays/Tooltip/context.js +1 -1
- package/dist/components/overlays/Tooltip/context.js.map +1 -1
- package/dist/components/overlays/Tooltip/split-trigger-props.js +1 -1
- package/dist/components/portal/Portal.js +1 -1
- package/dist/components/portal/PortalProvider.js +1 -1
- package/dist/components/portal/usePortal.js +1 -1
- package/dist/components/shared/DraggableCollection.js +1 -1
- package/dist/components/shared/InvalidIcon.js +1 -1
- package/dist/components/shared/ValidIcon.js +1 -1
- package/dist/components/status/LoadingAnimation/LoadingAnimation.js +1 -1
- package/dist/components/status/LoadingAnimation/LoadingAnimation.js.map +1 -1
- package/dist/components/status/Spin/Cube.js +1 -1
- package/dist/components/status/Spin/InternalSpinner.js +1 -1
- package/dist/components/status/Spin/Spin.js +1 -1
- package/dist/components/status/Spin/SpinsContainer.js +1 -1
- package/dist/data/item-themes.js +8 -32
- package/dist/data/item-themes.js.map +1 -1
- package/dist/data/themes.js +1 -1
- package/dist/eslint-plugin/defaults.generated.js +5 -1
- package/dist/eslint-plugin/defaults.generated.js.map +1 -1
- package/dist/eslint-plugin/index.js +1 -1
- package/dist/eslint-plugin/rules/no-redundant-default-prop.js +1 -1
- package/dist/i18n/I18nProvider.js +1 -1
- package/dist/i18n/createFormatter.js +1 -1
- package/dist/i18n/index.js +4 -4
- package/dist/i18n/instance.js +3 -3
- package/dist/i18n/locales/de-DE/uikit.js +1 -1
- package/dist/i18n/locales/en-US/uikit.js +1 -1
- package/dist/i18n/locales/es-ES/uikit.js +1 -1
- package/dist/i18n/locales/es-MX/uikit.js +1 -1
- package/dist/i18n/locales/fr-FR/uikit.js +1 -1
- package/dist/i18n/locales/it-IT/uikit.js +1 -1
- package/dist/i18n/locales/ja-JP/uikit.js +1 -1
- package/dist/i18n/locales/nb-NO/uikit.js +1 -1
- package/dist/i18n/locales/pt-BR/uikit.js +1 -1
- package/dist/i18n/locales/pt-PT/uikit.js +1 -1
- package/dist/i18n/locales/sv-SE/uikit.js +1 -1
- package/dist/i18n/locales/vi-VN/uikit.js +1 -1
- package/dist/i18n/locales.js +1 -1
- package/dist/i18n/namespace.js +1 -1
- package/dist/i18n/useFormatter.js +1 -1
- package/dist/i18n/useI18n.js +1 -1
- package/dist/icons/AdjustmentsHorizontalIcon.js +1 -1
- package/dist/icons/AdjustmentsIcon.js +1 -1
- package/dist/icons/AiIcon.js +1 -1
- package/dist/icons/AreaChartIcon.js +1 -1
- package/dist/icons/ArrowNarrowDownIcon.js +1 -1
- package/dist/icons/ArrowNarrowUpIcon.js +1 -1
- package/dist/icons/BackwardIcon.js +1 -1
- package/dist/icons/BarChartIcon.js +1 -1
- package/dist/icons/BellFilledIcon.js +1 -1
- package/dist/icons/BellIcon.js +1 -1
- package/dist/icons/BooleanIcon.js +1 -1
- package/dist/icons/CalendarEditIcon.js +1 -1
- package/dist/icons/CalendarIcon.js +1 -1
- package/dist/icons/CaretDownIcon.js +1 -1
- package/dist/icons/CaretUpIcon.js +1 -1
- package/dist/icons/ChartAreaStackedIcon.js +1 -1
- package/dist/icons/ChartAreaStackedPercentageIcon.js +1 -1
- package/dist/icons/ChartBarGroupedHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarGroupedIcon.js +1 -1
- package/dist/icons/ChartBarHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarLineIcon.js +1 -1
- package/dist/icons/ChartBarStackedHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarStackedIcon.js +1 -1
- package/dist/icons/ChartBarStackedPercentageHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarStackedPercentageIcon.js +1 -1
- package/dist/icons/ChartBoxPlot2Icon.js +1 -1
- package/dist/icons/ChartBoxPlotIcon.js +1 -1
- package/dist/icons/ChartBubbleIcon.js +1 -1
- package/dist/icons/ChartDonut2Icon.js +1 -1
- package/dist/icons/ChartFunnelIcon.js +1 -1
- package/dist/icons/ChartHeatmapIcon.js +1 -1
- package/dist/icons/ChartKPIIcon.js +1 -1
- package/dist/icons/ChartPie2Icon.js +1 -1
- package/dist/icons/ChartScatterIcon.js +1 -1
- package/dist/icons/CheckCircleFilledIcon.js +1 -1
- package/dist/icons/CheckCircleIcon.js +1 -1
- package/dist/icons/CheckIcon.js +1 -1
- package/dist/icons/CircleFilledIcon.js +1 -1
- package/dist/icons/ClearIcon.js +1 -1
- package/dist/icons/CloseCircleFilledIcon.js +1 -1
- package/dist/icons/CloseCircleIcon.js +1 -1
- package/dist/icons/CloseIcon.js +1 -1
- package/dist/icons/CodeIcon.js +1 -1
- package/dist/icons/ColumnTotalIcon.js +1 -1
- package/dist/icons/CopyIcon.js +1 -1
- package/dist/icons/CountIcon.js +1 -1
- package/dist/icons/CubeIcon.js +1 -1
- package/dist/icons/CubePauseIcon.js +1 -1
- package/dist/icons/CubePlayIcon.js +1 -1
- package/dist/icons/CurrencyDollarIcon.js +1 -1
- package/dist/icons/DangerIcon.js +1 -1
- package/dist/icons/DashboardIcon.js +1 -1
- package/dist/icons/DatabaseIcon.js +1 -1
- package/dist/icons/DecimalDecreaseIcon.js +1 -1
- package/dist/icons/DecimalIncreaseIcon.js +1 -1
- package/dist/icons/DirectionIcon.js +1 -1
- package/dist/icons/DonutIcon.js +1 -1
- package/dist/icons/DownIcon.js +1 -1
- package/dist/icons/EditIcon.js +1 -1
- package/dist/icons/ExclamationCircleFilledIcon.js +1 -1
- package/dist/icons/ExclamationCircleIcon.js +1 -1
- package/dist/icons/ExclamationIcon.js +1 -1
- package/dist/icons/EyeIcon.js +1 -1
- package/dist/icons/EyeInvisibleIcon.js +1 -1
- package/dist/icons/FilterIcon.js +1 -1
- package/dist/icons/FolderFilledIcon.js +1 -1
- package/dist/icons/FolderIcon.js +1 -1
- package/dist/icons/FolderOpenFilledIcon.js +1 -1
- package/dist/icons/FolderOpenIcon.js +1 -1
- package/dist/icons/ForwardIcon.js +1 -1
- package/dist/icons/GripVerticalIcon.js +1 -1
- package/dist/icons/HierarchyIcon.js +1 -1
- package/dist/icons/HierarchyOpenIcon.js +1 -1
- package/dist/icons/Icon.js +1 -1
- package/dist/icons/InfoCircleIcon.js +1 -1
- package/dist/icons/InfoIcon.js +1 -1
- package/dist/icons/KeyIcon.js +1 -1
- package/dist/icons/LeftIcon.js +1 -1
- package/dist/icons/LineChartIcon.js +1 -1
- package/dist/icons/LoadingIcon.js +1 -1
- package/dist/icons/LockFilledIcon.js +1 -1
- package/dist/icons/LockIcon.js +1 -1
- package/dist/icons/MoreIcon.js +1 -1
- package/dist/icons/NotAllowedIcon.js +1 -1
- package/dist/icons/Number123Icon.js +1 -1
- package/dist/icons/NumberIcon.js +1 -1
- package/dist/icons/PauseCircleFilledIcon.js +1 -1
- package/dist/icons/PauseCircleIcon.js +1 -1
- package/dist/icons/PauseIcon.js +1 -1
- package/dist/icons/PercentageIcon.js +1 -1
- package/dist/icons/PieChartIcon.js +1 -1
- package/dist/icons/PipetteIcon.js +1 -1
- package/dist/icons/PlayCircleIcon.js +1 -1
- package/dist/icons/PlayIcon.js +1 -1
- package/dist/icons/PlusIcon.js +1 -1
- package/dist/icons/ProgressBarIcon.js +1 -1
- package/dist/icons/ReloadIcon.js +1 -1
- package/dist/icons/ReportIcon.js +1 -1
- package/dist/icons/ReturnIcon.js +1 -1
- package/dist/icons/RightIcon.js +1 -1
- package/dist/icons/RowTotalsIcon.js +1 -1
- package/dist/icons/SchemeIcon.js +1 -1
- package/dist/icons/SearchIcon.js +1 -1
- package/dist/icons/SemanticQueryIcon.js +1 -1
- package/dist/icons/SettingsIcon.js +1 -1
- package/dist/icons/ShieldFilledIcon.js +1 -1
- package/dist/icons/ShieldIcon.js +1 -1
- package/dist/icons/SlashIcon.js +1 -1
- package/dist/icons/SparklesIcon.js +1 -1
- package/dist/icons/SqlIcon.js +1 -1
- package/dist/icons/StatsIcon.js +1 -1
- package/dist/icons/StopIcon.js +1 -1
- package/dist/icons/StringIcon.js +1 -1
- package/dist/icons/SubtotalsIcon.js +1 -1
- package/dist/icons/SwitchIcon.js +1 -1
- package/dist/icons/TableIcon.js +1 -1
- package/dist/icons/ThumbsDownIcon.js +1 -1
- package/dist/icons/ThumbsUpIcon.js +1 -1
- package/dist/icons/ThunderboltCrossedIcon.js +1 -1
- package/dist/icons/ThunderboltFilledIcon.js +1 -1
- package/dist/icons/ThunderboltIcon.js +1 -1
- package/dist/icons/TimeIcon.js +1 -1
- package/dist/icons/TrashIcon.js +1 -1
- package/dist/icons/UnlockIcon.js +1 -1
- package/dist/icons/UpIcon.js +1 -1
- package/dist/icons/UserGroupIcon.js +1 -1
- package/dist/icons/UserIcon.js +1 -1
- package/dist/icons/UserLockIcon.js +1 -1
- package/dist/icons/ViewIcon.js +1 -1
- package/dist/icons/WarningFilledIcon.js +1 -1
- package/dist/icons/WarningIcon.js +1 -1
- package/dist/icons/wrap-icon.js +1 -1
- package/dist/index.d.ts +29 -27
- package/dist/index.js +69 -69
- package/dist/probe/canonicalize.js +1 -1
- package/dist/probe/css.js +1 -1
- package/dist/probe/index.js +1 -1
- package/dist/provider.js +2 -2
- package/dist/providers/TrackingProvider.js +1 -1
- package/dist/providers/navigation-url.js +1 -1
- package/dist/providers/navigationAdapter.default.js +1 -1
- package/dist/providers/use-navigation.js +1 -1
- package/dist/tokens/all-tokens.js +1 -1
- package/dist/tokens/base.js +1 -1
- package/dist/tokens/color-seed.js +1 -1
- package/dist/tokens/color-theme.js +1 -1
- package/dist/tokens/colors.js +1 -1
- package/dist/tokens/layout.js +1 -1
- package/dist/tokens/lazy-styles.js +1 -1
- package/dist/tokens/legacy-color.js +1 -1
- package/dist/tokens/palette-config.js +1 -1
- package/dist/tokens/palette.js +23 -11
- package/dist/tokens/palette.js.map +1 -1
- package/dist/tokens/resolve.js +2 -2
- package/dist/tokens/shadows.js +1 -1
- package/dist/tokens/sizes.js +1 -1
- package/dist/tokens/spacing.js +1 -1
- package/dist/tokens/typography.js +1 -1
- package/dist/utils/ResizeSensor.js +1 -1
- package/dist/utils/colors.js +1 -1
- package/dist/utils/dotize.js +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/is-dev-env.js +1 -1
- package/dist/utils/modules.js +1 -1
- package/dist/utils/promise.js +1 -1
- package/dist/utils/raf.js +1 -1
- package/dist/utils/random.js +1 -1
- package/dist/utils/range.js +1 -1
- package/dist/utils/react/RenderCache.js +1 -1
- package/dist/utils/react/Slots.js +1 -1
- package/dist/utils/react/chain.js +1 -1
- package/dist/utils/react/disabledProps.js +1 -1
- package/dist/utils/react/forwardRefWithGenerics.js +1 -1
- package/dist/utils/react/index.d.ts +3 -3
- package/dist/utils/react/index.js +13 -13
- package/dist/utils/react/interactions.js +1 -1
- package/dist/utils/react/isTextOnly.js +1 -1
- package/dist/utils/react/mapProps.js +1 -1
- package/dist/utils/react/mergeProps.js +1 -1
- package/dist/utils/react/nullableValue.js +1 -1
- package/dist/utils/react/overlayKeyPropagation.js +1 -1
- package/dist/utils/react/programmaticFocus.js +1 -1
- package/dist/utils/react/resolveIcon.js +1 -1
- package/dist/utils/react/sharedStore.js +1 -1
- package/dist/utils/react/useBufferedValue.js +1 -1
- package/dist/utils/react/useCombinedRefs.js +1 -1
- package/dist/utils/react/useControlledFocusVisible.js +1 -1
- package/dist/utils/react/useEventBus.js +1 -1
- package/dist/utils/react/useId.js +1 -1
- package/dist/utils/react/useIsDarwin.js +1 -1
- package/dist/utils/react/useKeySymbols.js +1 -1
- package/dist/utils/react/useLayoutEffect.js +1 -1
- package/dist/utils/react/useLocalStorage.js +1 -1
- package/dist/utils/react/useMergeStyles.js +1 -1
- package/dist/utils/react/useOverlayEscapeGuard.js +1 -1
- package/dist/utils/react/useOverlayEscapeGuard.js.map +1 -1
- package/dist/utils/react/usePopoverSync.js +1 -1
- package/dist/utils/react/useQaProps.js +1 -1
- package/dist/utils/react/useScheme.js +1 -1
- package/dist/utils/react/useViewportSize.js +1 -1
- package/dist/utils/react/wrapNodeIfPlain.js +1 -1
- package/dist/utils/selection.js +1 -1
- package/dist/utils/styles.js +1 -1
- package/dist/utils/tree.js +1 -1
- package/dist/utils/warnings.js +1 -1
- package/dist/version.js +2 -2
- package/docs/components/actions/Button.md +10 -0
- package/docs/components/actions/ButtonSplit.md +1 -1
- package/docs/glaze/contrast.mdx +751 -0
- package/docs/glaze/exporting.mdx +635 -0
- package/docs/glaze/getting-started.mdx +487 -0
- package/docs/glaze/hdr.mdx +523 -0
- package/docs/glaze/methodology.mdx +979 -0
- package/docs/glaze/migration.md +476 -285
- package/docs/glaze/mixes.mdx +348 -0
- package/docs/glaze/okhst.mdx +692 -0
- package/docs/glaze/reference/color-definitions.md +552 -0
- package/docs/glaze/reference/color-tokens.md +421 -0
- package/docs/glaze/reference/configuration.md +532 -0
- package/docs/glaze/reference/contrast.md +279 -0
- package/docs/glaze/reference/index.md +225 -0
- package/docs/glaze/reference/output.md +714 -0
- package/docs/glaze/reference/palette.md +435 -0
- package/docs/glaze/reference/theme.md +332 -0
- package/docs/glaze/reference/utilities.md +646 -0
- package/docs/glaze/schemes.mdx +644 -0
- package/docs/glaze/shadows-and-glows.mdx +550 -0
- package/package.json +4 -4
- package/dist/components/actions/index.js +0 -29
- package/dist/components/actions/index.js.map +0 -1
- package/dist/components/fields/ListBoxPopover/ListBoxPopover.d.ts +0 -4
- package/dist/components/fields/ListBoxPopover/index.d.ts +0 -5
- package/dist/components/overlays/Modal/Modal.d.ts +0 -3
- package/dist/components/overlays/Modal/Popover.d.ts +0 -7
- package/dist/components/overlays/Modal/Tray.d.ts +0 -5
- package/dist/components/overlays/Modal/Underlay.d.ts +0 -3
- package/dist/components/overlays/Modal/index.d.ts +0 -8
- package/docs/glaze/api.md +0 -2021
- package/docs/glaze/methodology.md +0 -686
- package/docs/glaze/okhst.md +0 -207
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-notification-state.js","names":["Key","useRef","useState","useEvent","DismissReason","InternalNotification","OverlayNotificationOptions","PersistentNotificationItem","OverlayTimers","DEFAULT_NOTIFICATION_DURATION","DEFAULT_PERSISTENT_NOTIFICATION_DURATION","MAX_NOTIFICATIONS","MAX_DISMISS_SNAPSHOTS","SNAPSHOT_TTL_MS","PersistentCallbacks","addPersistentItem","item","removePersistentItem","id","removePersistentItemSilently","hasDismissedPersistentId","isFullyDismissedId","saveDismissedPersistentId","undoFullyDismissedId","NotificationState","notifications","notificationsRef","ReturnType","addNotification","options","ownerId","removeNotification","reason","restoreNotification","updateNotification","Partial","finalizeNotificationRemoval","internalId","removeByOwner","getDuration","notif","persistent","duration","undefined","matchesNotificationId","String","findNotification","list","find","n","useNotificationState","timersRef","setNotifications","current","idCounter","dismissSnapshotsRef","Map","evictOldest","active","filter","isExiting","length","oldest","clearNotificationTimer","theme","title","description","icon","actions","createdAt","updatedAt","isRead","set","lastDismissReason","size","keys","next","value","delete","prev","map","idStr","snapshot","get","persistentId","startNotificationTimer","stillInState","restored","setTimeout","key","snap","Date","now","existingNotif","returnId","prevTitle","prevDescription","titleChanged","descriptionChanged","activeCount","newNotification","evictedInternalId","owned"],"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;\nconst MAX_DISMISS_SNAPSHOTS = 50;\nconst SNAPSHOT_TTL_MS = 5 * 60 * 1000;\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 // Snapshots of dismissed notifications, keyed by notification id (string).\n // Saved at dismiss time so restoreNotification can re-add the notification\n // even after finalizeNotificationRemoval has removed it from state.\n const dismissSnapshotsRef = useRef<Map<string, InternalNotification>>(\n new Map(),\n );\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 // Snapshot the notification for potential restore after finalization.\n dismissSnapshotsRef.current.set(String(notif.id ?? notif.internalId), {\n ...notif,\n lastDismissReason: reason,\n });\n\n // Prevent unbounded growth of dismiss snapshots.\n while (dismissSnapshotsRef.current.size > MAX_DISMISS_SNAPSHOTS) {\n const oldest = dismissSnapshotsRef.current.keys().next().value;\n\n if (oldest != null) {\n dismissSnapshotsRef.current.delete(oldest);\n } else {\n break;\n }\n }\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 idStr = String(id);\n const snapshot = dismissSnapshotsRef.current.get(idStr);\n\n if (!snapshot) return;\n\n dismissSnapshotsRef.current.delete(idStr);\n\n // Undo persistent side effects based on how the notification was dismissed.\n if (snapshot.persistent && snapshot.lastDismissReason) {\n const persistentId = snapshot.id ?? snapshot.internalId;\n\n if (\n snapshot.lastDismissReason === 'close' ||\n snapshot.lastDismissReason === 'timeout'\n ) {\n persistent.removePersistentItemSilently(persistentId);\n } else if (snapshot.lastDismissReason === 'action') {\n persistent.undoFullyDismissedId(persistentId);\n }\n }\n\n // Restart the auto-dismiss timer.\n const duration = getDuration(snapshot);\n\n if (duration != null && duration > 0) {\n timersRef.current?.startNotificationTimer(\n snapshot.internalId,\n snapshot.id ?? snapshot.internalId,\n duration,\n );\n }\n\n const stillInState = findNotification(notificationsRef.current, id);\n\n if (stillInState) {\n // Exit animation hasn't completed yet — cancel it.\n setNotifications((prev) =>\n prev.map((n) =>\n matchesNotificationId(n, id)\n ? { ...n, isExiting: false, lastDismissReason: undefined }\n : n,\n ),\n );\n } else {\n // Notification was already finalized (removed from state) — re-add it.\n const restored: InternalNotification = {\n ...snapshot,\n isExiting: false,\n lastDismissReason: undefined,\n };\n\n setNotifications((prev) => [...prev, restored]);\n }\n });\n\n // ─── Finalize ──────────────────────────────────────────────────\n\n const finalizeNotificationRemoval = useEvent((internalId: string) => {\n setNotifications((prev) => prev.filter((n) => n.internalId !== internalId));\n\n // Deferred cleanup of the dismiss snapshot. Kept briefly so async action\n // callbacks can still call restoreNotification after the exit animation.\n setTimeout(() => {\n for (const [key, snap] of dismissSnapshotsRef.current) {\n if (snap.internalId === internalId) {\n dismissSnapshotsRef.current.delete(key);\n break;\n }\n }\n }, SNAPSHOT_TTL_MS);\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
|
+
{"version":3,"file":"use-notification-state.js","names":["Key","useRef","useState","useEvent","DismissReason","InternalNotification","OverlayNotificationOptions","PersistentNotificationItem","OverlayTimers","DEFAULT_NOTIFICATION_DURATION","DEFAULT_PERSISTENT_NOTIFICATION_DURATION","MAX_NOTIFICATIONS","MAX_DISMISS_SNAPSHOTS","SNAPSHOT_TTL_MS","PersistentCallbacks","addPersistentItem","item","removePersistentItem","id","removePersistentItemSilently","hasDismissedPersistentId","isFullyDismissedId","saveDismissedPersistentId","undoFullyDismissedId","NotificationState","notifications","notificationsRef","ReturnType","addNotification","options","ownerId","removeNotification","reason","restoreNotification","updateNotification","Partial","finalizeNotificationRemoval","internalId","removeByOwner","getDuration","notif","persistent","duration","undefined","matchesNotificationId","String","findNotification","list","find","n","useNotificationState","timersRef","setNotifications","current","idCounter","dismissSnapshotsRef","Map","evictOldest","active","filter","isExiting","length","oldest","clearNotificationTimer","theme","title","description","icon","actions","createdAt","updatedAt","isRead","set","lastDismissReason","size","keys","next","value","delete","prev","map","idStr","snapshot","get","persistentId","startNotificationTimer","stillInState","restored","setTimeout","key","snap","Date","now","existingNotif","returnId","prevTitle","prevDescription","titleChanged","descriptionChanged","activeCount","newNotification","evictedInternalId","owned"],"sources":["../../../../src/components/overlays/Notifications/use-notification-state.ts"],"sourcesContent":["import { Key, useRef, useState } from 'react';\n\nimport { useEvent } from '../../../_internal/hooks/use-event';\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;\nconst MAX_DISMISS_SNAPSHOTS = 50;\nconst SNAPSHOT_TTL_MS = 5 * 60 * 1000;\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 // Snapshots of dismissed notifications, keyed by notification id (string).\n // Saved at dismiss time so restoreNotification can re-add the notification\n // even after finalizeNotificationRemoval has removed it from state.\n const dismissSnapshotsRef = useRef<Map<string, InternalNotification>>(\n new Map(),\n );\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 // Snapshot the notification for potential restore after finalization.\n dismissSnapshotsRef.current.set(String(notif.id ?? notif.internalId), {\n ...notif,\n lastDismissReason: reason,\n });\n\n // Prevent unbounded growth of dismiss snapshots.\n while (dismissSnapshotsRef.current.size > MAX_DISMISS_SNAPSHOTS) {\n const oldest = dismissSnapshotsRef.current.keys().next().value;\n\n if (oldest != null) {\n dismissSnapshotsRef.current.delete(oldest);\n } else {\n break;\n }\n }\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 idStr = String(id);\n const snapshot = dismissSnapshotsRef.current.get(idStr);\n\n if (!snapshot) return;\n\n dismissSnapshotsRef.current.delete(idStr);\n\n // Undo persistent side effects based on how the notification was dismissed.\n if (snapshot.persistent && snapshot.lastDismissReason) {\n const persistentId = snapshot.id ?? snapshot.internalId;\n\n if (\n snapshot.lastDismissReason === 'close' ||\n snapshot.lastDismissReason === 'timeout'\n ) {\n persistent.removePersistentItemSilently(persistentId);\n } else if (snapshot.lastDismissReason === 'action') {\n persistent.undoFullyDismissedId(persistentId);\n }\n }\n\n // Restart the auto-dismiss timer.\n const duration = getDuration(snapshot);\n\n if (duration != null && duration > 0) {\n timersRef.current?.startNotificationTimer(\n snapshot.internalId,\n snapshot.id ?? snapshot.internalId,\n duration,\n );\n }\n\n const stillInState = findNotification(notificationsRef.current, id);\n\n if (stillInState) {\n // Exit animation hasn't completed yet — cancel it.\n setNotifications((prev) =>\n prev.map((n) =>\n matchesNotificationId(n, id)\n ? { ...n, isExiting: false, lastDismissReason: undefined }\n : n,\n ),\n );\n } else {\n // Notification was already finalized (removed from state) — re-add it.\n const restored: InternalNotification = {\n ...snapshot,\n isExiting: false,\n lastDismissReason: undefined,\n };\n\n setNotifications((prev) => [...prev, restored]);\n }\n });\n\n // ─── Finalize ──────────────────────────────────────────────────\n\n const finalizeNotificationRemoval = useEvent((internalId: string) => {\n setNotifications((prev) => prev.filter((n) => n.internalId !== internalId));\n\n // Deferred cleanup of the dismiss snapshot. Kept briefly so async action\n // callbacks can still call restoreNotification after the exit animation.\n setTimeout(() => {\n for (const [key, snap] of dismissSnapshotsRef.current) {\n if (snap.internalId === internalId) {\n dismissSnapshotsRef.current.delete(key);\n break;\n }\n }\n }, SNAPSHOT_TTL_MS);\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.
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.208.0 | 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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-notifications.js","names":["Key","useEffect","useRef","useEvent","useWarn","useNotificationContext","NotificationHandle","NotificationOptions","NotificationsApi","OverlayNotificationOptions","PersistentNotificationItem","StoredNotificationOptions","ownerIdCounter","generateOwnerId","Date","now","isStoredMode","options","mode","useNotifications","addNotification","removeNotification","addPersistentItem","removePersistentItem","removeByOwner","removePersistentItemsByOwner","ownerIdRef","isMountedRef","cleanupTimerRef","ReturnType","setTimeout","lastOptionsRef","current","persistent","id","once","key","args","storedIdCounter","createStoredHandle","Omit","createdAt","persistentItem","theme","title","description","icon","actions","undefined","updatedAt","ownerId","dismiss","notify","overlayOptions","notificationId","record","clearTimeout"],"sources":["../../../../src/components/overlays/Notifications/use-notifications.ts"],"sourcesContent":["import { Key, useEffect, useRef } from 'react';\n\nimport { useEvent } from '../../../_internal';\nimport { useWarn } from '../../../_internal/hooks/use-warn';\n\nimport { useNotificationContext } from './NotificationContext';\n\nimport type {\n NotificationHandle,\n NotificationOptions,\n NotificationsApi,\n OverlayNotificationOptions,\n PersistentNotificationItem,\n StoredNotificationOptions,\n} from './types';\n\nlet ownerIdCounter = 0;\n\nfunction generateOwnerId(): string {\n ownerIdCounter += 1;\n return `notif-owner-${ownerIdCounter}-${Date.now()}`;\n}\n\nfunction isStoredMode(\n options: NotificationOptions,\n): options is StoredNotificationOptions {\n return options.mode === 'stored';\n}\n\n/**\n * Hook to display and manage notifications.\n *\n * Each hook instance acts as an owner scope:\n * - `notify()` created from this instance attaches ownership metadata.\n * - On unmount, all attached visible overlay notifications are dismissed.\n * - On unmount, all attached persistent records are also removed.\n * - `notify()`/`dismiss()` calls from stale closures after unmount are no-ops.\n *\n * @example\n * ```tsx\n * const { notify, record, dismiss } = useNotifications();\n *\n * notify({\n * id: 'deploy:123',\n * theme: 'success',\n * title: 'Deployment completed',\n * description: 'Version 1.4.2 is live.',\n * actions: (\n * <>\n * <Notification.Action onPress={() => openLogs()}>View logs</Notification.Action>\n * <Notification.Action onPress={() => openDeployment()}>Open</Notification.Action>\n * </>\n * ),\n * });\n *\n * // Store directly to persistent list (no overlay)\n * record({\n * id: 'server:alert-1',\n * theme: 'warning',\n * title: 'Server alert',\n * });\n * ```\n */\nexport function useNotifications(): NotificationsApi {\n const {\n addNotification,\n removeNotification,\n addPersistentItem,\n removePersistentItem,\n removeByOwner,\n removePersistentItemsByOwner,\n } = useNotificationContext();\n\n const ownerIdRef = useRef<string>(generateOwnerId());\n const isMountedRef = useRef(true);\n const cleanupTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Track current options for validation\n const lastOptionsRef = useRef<NotificationOptions | null>(null);\n\n // ─── Validation Warnings ──────────────────────────────────────────\n\n useWarn(\n lastOptionsRef.current &&\n 'persistent' in lastOptionsRef.current &&\n lastOptionsRef.current.persistent === true &&\n lastOptionsRef.current.id == null,\n {\n once: false,\n key: ['Notification', 'persistent-without-id'],\n args: [\n 'Notification: `persistent: true` requires an explicit `id` for reliable dedupe/upsert.',\n ],\n },\n );\n\n useWarn(\n lastOptionsRef.current?.mode === 'stored' &&\n lastOptionsRef.current.id == null,\n {\n once: false,\n key: ['Notification', 'stored-without-id'],\n args: [\n 'Notification: `mode: \"stored\"` should have an explicit `id` for reliable upsert.',\n ],\n },\n );\n\n // ─── Helpers ─────────────────────────────────────────────────────\n\n const storedIdCounter = useRef(0);\n\n const createStoredHandle = useEvent(\n (options: Omit<StoredNotificationOptions, 'mode'>): NotificationHandle => {\n storedIdCounter.current += 1;\n const now = Date.now();\n const id = options.id ?? `stored-${storedIdCounter.current}-${now}`;\n const createdAt = options.createdAt ?? now;\n\n const persistentItem: PersistentNotificationItem = {\n id,\n theme: options.theme,\n title: options.title,\n description: options.description,\n icon: options.icon,\n actions: options.actions ?? undefined,\n createdAt,\n updatedAt: createdAt,\n ownerId: ownerIdRef.current,\n };\n\n addPersistentItem(persistentItem);\n\n return {\n id,\n dismiss: () => {\n removePersistentItem(id);\n },\n };\n },\n );\n\n // ─── API ──────────────────────────────────────────────────────────\n\n const notify = useEvent(\n (options: NotificationOptions): NotificationHandle => {\n // Stale closure guard\n if (!isMountedRef.current) {\n return {\n id: options.id ?? '',\n dismiss: () => {},\n };\n }\n\n lastOptionsRef.current = options;\n\n if (isStoredMode(options)) {\n return createStoredHandle(options);\n }\n\n // Overlay mode\n const overlayOptions: OverlayNotificationOptions = {\n ...options,\n mode: 'overlay',\n };\n\n const notificationId = addNotification(\n overlayOptions,\n ownerIdRef.current,\n );\n\n return {\n id: notificationId,\n dismiss: () => {\n if (isMountedRef.current) {\n removeNotification(notificationId, 'api');\n }\n },\n };\n },\n );\n\n // `record()` is intentionally kept as a separate method from `notify()` to make\n // the API more explicit: `record()` always stores directly to the persistent list\n // (no overlay), while `notify()` defaults to overlay mode. Having both avoids\n // the caller needing to remember to pass `mode: 'stored'` every time.\n const record = useEvent(\n (options: Omit<StoredNotificationOptions, 'mode'>): NotificationHandle => {\n // Stale closure guard\n if (!isMountedRef.current) {\n return {\n id: options.id ?? '',\n dismiss: () => {},\n };\n }\n\n lastOptionsRef.current = { ...options, mode: 'stored' };\n\n return createStoredHandle(options);\n },\n );\n\n const dismiss = useEvent((id: Key) => {\n if (!isMountedRef.current) return;\n\n removeNotification(id, 'api');\n });\n\n // ─── Ownership Cleanup ────────────────────────────────────────────\n\n useEffect(() => {\n isMountedRef.current = true;\n\n // Cancel any pending cleanup (Strict Mode re-mount)\n if (cleanupTimerRef.current) {\n clearTimeout(cleanupTimerRef.current);\n cleanupTimerRef.current = null;\n }\n\n return () => {\n isMountedRef.current = false;\n\n // Deferred cleanup — cancelled if owner re-mounts within same tick\n // (Strict Mode / Suspense safe)\n cleanupTimerRef.current = setTimeout(() => {\n removeByOwner(ownerIdRef.current);\n removePersistentItemsByOwner(ownerIdRef.current);\n }, 0);\n };\n }, [removeByOwner, removePersistentItemsByOwner]);\n\n return { notify, record, dismiss };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-notifications.js","names":["Key","useEffect","useRef","useEvent","useWarn","useNotificationContext","NotificationHandle","NotificationOptions","NotificationsApi","OverlayNotificationOptions","PersistentNotificationItem","StoredNotificationOptions","ownerIdCounter","generateOwnerId","Date","now","isStoredMode","options","mode","useNotifications","addNotification","removeNotification","addPersistentItem","removePersistentItem","removeByOwner","removePersistentItemsByOwner","ownerIdRef","isMountedRef","cleanupTimerRef","ReturnType","setTimeout","lastOptionsRef","current","persistent","id","once","key","args","storedIdCounter","createStoredHandle","Omit","createdAt","persistentItem","theme","title","description","icon","actions","undefined","updatedAt","ownerId","dismiss","notify","overlayOptions","notificationId","record","clearTimeout"],"sources":["../../../../src/components/overlays/Notifications/use-notifications.ts"],"sourcesContent":["import { Key, useEffect, useRef } from 'react';\n\nimport { useEvent } from '../../../_internal/hooks/use-event';\nimport { useWarn } from '../../../_internal/hooks/use-warn';\n\nimport { useNotificationContext } from './NotificationContext';\n\nimport type {\n NotificationHandle,\n NotificationOptions,\n NotificationsApi,\n OverlayNotificationOptions,\n PersistentNotificationItem,\n StoredNotificationOptions,\n} from './types';\n\nlet ownerIdCounter = 0;\n\nfunction generateOwnerId(): string {\n ownerIdCounter += 1;\n return `notif-owner-${ownerIdCounter}-${Date.now()}`;\n}\n\nfunction isStoredMode(\n options: NotificationOptions,\n): options is StoredNotificationOptions {\n return options.mode === 'stored';\n}\n\n/**\n * Hook to display and manage notifications.\n *\n * Each hook instance acts as an owner scope:\n * - `notify()` created from this instance attaches ownership metadata.\n * - On unmount, all attached visible overlay notifications are dismissed.\n * - On unmount, all attached persistent records are also removed.\n * - `notify()`/`dismiss()` calls from stale closures after unmount are no-ops.\n *\n * @example\n * ```tsx\n * const { notify, record, dismiss } = useNotifications();\n *\n * notify({\n * id: 'deploy:123',\n * theme: 'success',\n * title: 'Deployment completed',\n * description: 'Version 1.4.2 is live.',\n * actions: (\n * <>\n * <Notification.Action onPress={() => openLogs()}>View logs</Notification.Action>\n * <Notification.Action onPress={() => openDeployment()}>Open</Notification.Action>\n * </>\n * ),\n * });\n *\n * // Store directly to persistent list (no overlay)\n * record({\n * id: 'server:alert-1',\n * theme: 'warning',\n * title: 'Server alert',\n * });\n * ```\n */\nexport function useNotifications(): NotificationsApi {\n const {\n addNotification,\n removeNotification,\n addPersistentItem,\n removePersistentItem,\n removeByOwner,\n removePersistentItemsByOwner,\n } = useNotificationContext();\n\n const ownerIdRef = useRef<string>(generateOwnerId());\n const isMountedRef = useRef(true);\n const cleanupTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Track current options for validation\n const lastOptionsRef = useRef<NotificationOptions | null>(null);\n\n // ─── Validation Warnings ──────────────────────────────────────────\n\n useWarn(\n lastOptionsRef.current &&\n 'persistent' in lastOptionsRef.current &&\n lastOptionsRef.current.persistent === true &&\n lastOptionsRef.current.id == null,\n {\n once: false,\n key: ['Notification', 'persistent-without-id'],\n args: [\n 'Notification: `persistent: true` requires an explicit `id` for reliable dedupe/upsert.',\n ],\n },\n );\n\n useWarn(\n lastOptionsRef.current?.mode === 'stored' &&\n lastOptionsRef.current.id == null,\n {\n once: false,\n key: ['Notification', 'stored-without-id'],\n args: [\n 'Notification: `mode: \"stored\"` should have an explicit `id` for reliable upsert.',\n ],\n },\n );\n\n // ─── Helpers ─────────────────────────────────────────────────────\n\n const storedIdCounter = useRef(0);\n\n const createStoredHandle = useEvent(\n (options: Omit<StoredNotificationOptions, 'mode'>): NotificationHandle => {\n storedIdCounter.current += 1;\n const now = Date.now();\n const id = options.id ?? `stored-${storedIdCounter.current}-${now}`;\n const createdAt = options.createdAt ?? now;\n\n const persistentItem: PersistentNotificationItem = {\n id,\n theme: options.theme,\n title: options.title,\n description: options.description,\n icon: options.icon,\n actions: options.actions ?? undefined,\n createdAt,\n updatedAt: createdAt,\n ownerId: ownerIdRef.current,\n };\n\n addPersistentItem(persistentItem);\n\n return {\n id,\n dismiss: () => {\n removePersistentItem(id);\n },\n };\n },\n );\n\n // ─── API ──────────────────────────────────────────────────────────\n\n const notify = useEvent(\n (options: NotificationOptions): NotificationHandle => {\n // Stale closure guard\n if (!isMountedRef.current) {\n return {\n id: options.id ?? '',\n dismiss: () => {},\n };\n }\n\n lastOptionsRef.current = options;\n\n if (isStoredMode(options)) {\n return createStoredHandle(options);\n }\n\n // Overlay mode\n const overlayOptions: OverlayNotificationOptions = {\n ...options,\n mode: 'overlay',\n };\n\n const notificationId = addNotification(\n overlayOptions,\n ownerIdRef.current,\n );\n\n return {\n id: notificationId,\n dismiss: () => {\n if (isMountedRef.current) {\n removeNotification(notificationId, 'api');\n }\n },\n };\n },\n );\n\n // `record()` is intentionally kept as a separate method from `notify()` to make\n // the API more explicit: `record()` always stores directly to the persistent list\n // (no overlay), while `notify()` defaults to overlay mode. Having both avoids\n // the caller needing to remember to pass `mode: 'stored'` every time.\n const record = useEvent(\n (options: Omit<StoredNotificationOptions, 'mode'>): NotificationHandle => {\n // Stale closure guard\n if (!isMountedRef.current) {\n return {\n id: options.id ?? '',\n dismiss: () => {},\n };\n }\n\n lastOptionsRef.current = { ...options, mode: 'stored' };\n\n return createStoredHandle(options);\n },\n );\n\n const dismiss = useEvent((id: Key) => {\n if (!isMountedRef.current) return;\n\n removeNotification(id, 'api');\n });\n\n // ─── Ownership Cleanup ────────────────────────────────────────────\n\n useEffect(() => {\n isMountedRef.current = true;\n\n // Cancel any pending cleanup (Strict Mode re-mount)\n if (cleanupTimerRef.current) {\n clearTimeout(cleanupTimerRef.current);\n cleanupTimerRef.current = null;\n }\n\n return () => {\n isMountedRef.current = false;\n\n // Deferred cleanup — cancelled if owner re-mounts within same tick\n // (Strict Mode / Suspense safe)\n cleanupTimerRef.current = setTimeout(() => {\n removeByOwner(ownerIdRef.current);\n removePersistentItemsByOwner(ownerIdRef.current);\n }, 0);\n };\n }, [removeByOwner, removePersistentItemsByOwner]);\n\n return { notify, record, dismiss };\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.208.0 | Cube Dev Team */
|
|
2
2
|
import { useEvent } from "../../../_internal/hooks/use-event.js";
|
|
3
3
|
import { useEffect, useRef } from "react";
|
|
4
4
|
//#region src/components/overlays/Notifications/use-overlay-timers.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-overlay-timers.js","names":["Key","useEffect","useRef","useEvent","InternalToast","DismissReason","InternalNotification","OverlayTimers","startToastTimer","internalId","id","duration","clearToastTimer","startNotificationTimer","clearNotificationTimer","handlePauseChange","paused","OverlayTimersDeps","toastsRef","ReturnType","notificationsRef","removeToast","removeNotification","reason","TimerManager","start","clear","pauseAll","resumeAll","clearAll","createTimerManager","timersMap","Map","setTimeout","pausedMap","remaining","startedAt","isPausedRef","onTimeout","findItem","isExiting","timer","get","clearTimeout","delete","set","Date","now","current","forEach","info","elapsed","Math","max","item","has","useOverlayTimers","deps","toastTimersMap","notificationTimersMap","toastManager","notifManager","find","t","n"],"sources":["../../../../src/components/overlays/Notifications/use-overlay-timers.ts"],"sourcesContent":["import { Key, useEffect, useRef } from 'react';\n\nimport { useEvent } from '../../../_internal';\n\nimport type { InternalToast } from '../Toast/types';\nimport type { DismissReason, InternalNotification } from './types';\n\n// ─── Types ───────────────────────────────────────────────────────────\n\nexport interface OverlayTimers {\n /** Start a toast auto-dismiss timer */\n startToastTimer: (internalId: string, id: Key, duration: number) => void;\n /** Clear a toast timer */\n clearToastTimer: (internalId: string) => void;\n /** Start a notification auto-dismiss timer */\n startNotificationTimer: (\n internalId: string,\n id: Key,\n duration: number,\n ) => void;\n /** Clear a notification timer */\n clearNotificationTimer: (internalId: string) => void;\n /** Handle pause/resume of all timers (e.g. on hover/focus) */\n handlePauseChange: (paused: boolean) => void;\n}\n\nexport interface OverlayTimersDeps {\n /** Ref to current toasts (for resume lookup) */\n toastsRef: ReturnType<typeof useRef<InternalToast[]>>;\n /** Ref to current notifications (for resume lookup) */\n notificationsRef: ReturnType<typeof useRef<InternalNotification[]>>;\n /** Remove a toast by id */\n removeToast: (id: Key) => void;\n /** Remove a notification by id with reason (also invokes onDismiss callback) */\n removeNotification: (id: Key, reason: DismissReason) => void;\n}\n\n// ─── Timer Manager Factory ───────────────────────────────────────────\n\ninterface TimerManager {\n start: (internalId: string, id: Key, duration: number) => void;\n clear: (internalId: string) => void;\n pauseAll: () => void;\n resumeAll: () => void;\n clearAll: () => void;\n}\n\n/**\n * Creates a start/clear/pause/resume pair for a single timer category.\n * Eliminates duplication between toast and notification timer logic.\n */\nfunction createTimerManager(\n timersMap: Map<string, ReturnType<typeof setTimeout>>,\n pausedMap: Map<string, { remaining: number; startedAt: number }>,\n isPausedRef: ReturnType<typeof useRef<boolean>>,\n onTimeout: (id: Key) => void,\n findItem: (\n internalId: string,\n ) => { id?: Key; internalId: string; isExiting?: boolean } | undefined,\n): TimerManager {\n const clear = (internalId: string) => {\n const timer = timersMap.get(internalId);\n\n if (timer) {\n clearTimeout(timer);\n timersMap.delete(internalId);\n }\n\n pausedMap.delete(internalId);\n };\n\n const start = (internalId: string, id: Key, duration: number) => {\n clear(internalId);\n\n pausedMap.set(internalId, {\n remaining: duration,\n startedAt: Date.now(),\n });\n\n if (isPausedRef.current) {\n return;\n }\n\n const timer = setTimeout(() => {\n onTimeout(id);\n }, duration);\n\n timersMap.set(internalId, timer);\n };\n\n const pauseAll = () => {\n timersMap.forEach((timer, internalId) => {\n clearTimeout(timer);\n timersMap.delete(internalId);\n\n const info = pausedMap.get(internalId);\n\n if (info) {\n const elapsed = Date.now() - info.startedAt;\n pausedMap.set(internalId, {\n remaining: Math.max(0, info.remaining - elapsed),\n startedAt: Date.now(),\n });\n }\n });\n };\n\n const resumeAll = () => {\n pausedMap.forEach((info, internalId) => {\n const item = findItem(internalId);\n\n if (!item || item.isExiting || timersMap.has(internalId)) return;\n\n if (info.remaining <= 0) {\n pausedMap.delete(internalId);\n onTimeout(item.id ?? item.internalId);\n\n return;\n }\n\n const timer = setTimeout(() => {\n onTimeout(item.id ?? item.internalId);\n }, info.remaining);\n\n timersMap.set(internalId, timer);\n pausedMap.set(internalId, {\n remaining: info.remaining,\n startedAt: Date.now(),\n });\n });\n };\n\n const clearAll = () => {\n timersMap.forEach((timer) => clearTimeout(timer));\n timersMap.clear();\n };\n\n return { start, clear, pauseAll, resumeAll, clearAll };\n}\n\n// ─── Hook ────────────────────────────────────────────────────────────\n\nexport function useOverlayTimers(deps: OverlayTimersDeps): OverlayTimers {\n const { toastsRef, notificationsRef, removeToast, removeNotification } = deps;\n\n const toastTimersMap = useRef(\n new Map<string, ReturnType<typeof setTimeout>>(),\n ).current;\n const notificationTimersMap = useRef(\n new Map<string, ReturnType<typeof setTimeout>>(),\n ).current;\n const isPausedRef = useRef(false);\n\n // Shared paused-timers map. Toast and notification internalIds use distinct prefixes\n // ('toast-' and 'notif-') so they coexist safely in a single map.\n const pausedMap = useRef(\n new Map<string, { remaining: number; startedAt: number }>(),\n ).current;\n\n const toastManager = useRef<TimerManager | null>(null);\n const notifManager = useRef<TimerManager | null>(null);\n\n // Lazily create managers — deps are stable (useEvent / refs), so this runs once.\n if (!toastManager.current) {\n toastManager.current = createTimerManager(\n toastTimersMap,\n pausedMap,\n isPausedRef,\n (id) => removeToast(id),\n (internalId) =>\n toastsRef.current?.find((t) => t.internalId === internalId),\n );\n }\n\n if (!notifManager.current) {\n notifManager.current = createTimerManager(\n notificationTimersMap,\n pausedMap,\n isPausedRef,\n (id) => removeNotification(id, 'timeout'),\n (internalId) =>\n notificationsRef.current?.find((n) => n.internalId === internalId),\n );\n }\n\n // ─── Stable callbacks ──────────────────────────────────────────────\n\n const startToastTimer = useEvent(\n (internalId: string, id: Key, duration: number) => {\n toastManager.current!.start(internalId, id, duration);\n },\n );\n\n const clearToastTimer = useEvent((internalId: string) => {\n toastManager.current!.clear(internalId);\n });\n\n const startNotificationTimer = useEvent(\n (internalId: string, id: Key, duration: number) => {\n notifManager.current!.start(internalId, id, duration);\n },\n );\n\n const clearNotificationTimer = useEvent((internalId: string) => {\n notifManager.current!.clear(internalId);\n });\n\n // ─── Pause / Resume ─────────────────────────────────────────────\n\n const handlePauseChange = useEvent((paused: boolean) => {\n if (paused === isPausedRef.current) return;\n\n isPausedRef.current = paused;\n\n if (paused) {\n toastManager.current!.pauseAll();\n notifManager.current!.pauseAll();\n } else {\n toastManager.current!.resumeAll();\n notifManager.current!.resumeAll();\n }\n });\n\n // An effect can enqueue an item while paused just before an empty-stack\n // reset resumes timers. Retry once that item reaches the committed lookup,\n // preserving the deadlines of timers that are already running.\n useEffect(() => {\n if (!isPausedRef.current) {\n toastManager.current!.resumeAll();\n notifManager.current!.resumeAll();\n }\n });\n\n // ─── Cleanup on unmount ─────────────────────────────────────────\n\n useEffect(() => {\n return () => {\n toastManager.current!.clearAll();\n notifManager.current!.clearAll();\n pausedMap.clear();\n };\n }, []);\n\n return {\n startToastTimer,\n clearToastTimer,\n startNotificationTimer,\n clearNotificationTimer,\n handlePauseChange,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-overlay-timers.js","names":["Key","useEffect","useRef","useEvent","InternalToast","DismissReason","InternalNotification","OverlayTimers","startToastTimer","internalId","id","duration","clearToastTimer","startNotificationTimer","clearNotificationTimer","handlePauseChange","paused","OverlayTimersDeps","toastsRef","ReturnType","notificationsRef","removeToast","removeNotification","reason","TimerManager","start","clear","pauseAll","resumeAll","clearAll","createTimerManager","timersMap","Map","setTimeout","pausedMap","remaining","startedAt","isPausedRef","onTimeout","findItem","isExiting","timer","get","clearTimeout","delete","set","Date","now","current","forEach","info","elapsed","Math","max","item","has","useOverlayTimers","deps","toastTimersMap","notificationTimersMap","toastManager","notifManager","find","t","n"],"sources":["../../../../src/components/overlays/Notifications/use-overlay-timers.ts"],"sourcesContent":["import { Key, useEffect, useRef } from 'react';\n\nimport { useEvent } from '../../../_internal/hooks/use-event';\n\nimport type { InternalToast } from '../Toast/types';\nimport type { DismissReason, InternalNotification } from './types';\n\n// ─── Types ───────────────────────────────────────────────────────────\n\nexport interface OverlayTimers {\n /** Start a toast auto-dismiss timer */\n startToastTimer: (internalId: string, id: Key, duration: number) => void;\n /** Clear a toast timer */\n clearToastTimer: (internalId: string) => void;\n /** Start a notification auto-dismiss timer */\n startNotificationTimer: (\n internalId: string,\n id: Key,\n duration: number,\n ) => void;\n /** Clear a notification timer */\n clearNotificationTimer: (internalId: string) => void;\n /** Handle pause/resume of all timers (e.g. on hover/focus) */\n handlePauseChange: (paused: boolean) => void;\n}\n\nexport interface OverlayTimersDeps {\n /** Ref to current toasts (for resume lookup) */\n toastsRef: ReturnType<typeof useRef<InternalToast[]>>;\n /** Ref to current notifications (for resume lookup) */\n notificationsRef: ReturnType<typeof useRef<InternalNotification[]>>;\n /** Remove a toast by id */\n removeToast: (id: Key) => void;\n /** Remove a notification by id with reason (also invokes onDismiss callback) */\n removeNotification: (id: Key, reason: DismissReason) => void;\n}\n\n// ─── Timer Manager Factory ───────────────────────────────────────────\n\ninterface TimerManager {\n start: (internalId: string, id: Key, duration: number) => void;\n clear: (internalId: string) => void;\n pauseAll: () => void;\n resumeAll: () => void;\n clearAll: () => void;\n}\n\n/**\n * Creates a start/clear/pause/resume pair for a single timer category.\n * Eliminates duplication between toast and notification timer logic.\n */\nfunction createTimerManager(\n timersMap: Map<string, ReturnType<typeof setTimeout>>,\n pausedMap: Map<string, { remaining: number; startedAt: number }>,\n isPausedRef: ReturnType<typeof useRef<boolean>>,\n onTimeout: (id: Key) => void,\n findItem: (\n internalId: string,\n ) => { id?: Key; internalId: string; isExiting?: boolean } | undefined,\n): TimerManager {\n const clear = (internalId: string) => {\n const timer = timersMap.get(internalId);\n\n if (timer) {\n clearTimeout(timer);\n timersMap.delete(internalId);\n }\n\n pausedMap.delete(internalId);\n };\n\n const start = (internalId: string, id: Key, duration: number) => {\n clear(internalId);\n\n pausedMap.set(internalId, {\n remaining: duration,\n startedAt: Date.now(),\n });\n\n if (isPausedRef.current) {\n return;\n }\n\n const timer = setTimeout(() => {\n onTimeout(id);\n }, duration);\n\n timersMap.set(internalId, timer);\n };\n\n const pauseAll = () => {\n timersMap.forEach((timer, internalId) => {\n clearTimeout(timer);\n timersMap.delete(internalId);\n\n const info = pausedMap.get(internalId);\n\n if (info) {\n const elapsed = Date.now() - info.startedAt;\n pausedMap.set(internalId, {\n remaining: Math.max(0, info.remaining - elapsed),\n startedAt: Date.now(),\n });\n }\n });\n };\n\n const resumeAll = () => {\n pausedMap.forEach((info, internalId) => {\n const item = findItem(internalId);\n\n if (!item || item.isExiting || timersMap.has(internalId)) return;\n\n if (info.remaining <= 0) {\n pausedMap.delete(internalId);\n onTimeout(item.id ?? item.internalId);\n\n return;\n }\n\n const timer = setTimeout(() => {\n onTimeout(item.id ?? item.internalId);\n }, info.remaining);\n\n timersMap.set(internalId, timer);\n pausedMap.set(internalId, {\n remaining: info.remaining,\n startedAt: Date.now(),\n });\n });\n };\n\n const clearAll = () => {\n timersMap.forEach((timer) => clearTimeout(timer));\n timersMap.clear();\n };\n\n return { start, clear, pauseAll, resumeAll, clearAll };\n}\n\n// ─── Hook ────────────────────────────────────────────────────────────\n\nexport function useOverlayTimers(deps: OverlayTimersDeps): OverlayTimers {\n const { toastsRef, notificationsRef, removeToast, removeNotification } = deps;\n\n const toastTimersMap = useRef(\n new Map<string, ReturnType<typeof setTimeout>>(),\n ).current;\n const notificationTimersMap = useRef(\n new Map<string, ReturnType<typeof setTimeout>>(),\n ).current;\n const isPausedRef = useRef(false);\n\n // Shared paused-timers map. Toast and notification internalIds use distinct prefixes\n // ('toast-' and 'notif-') so they coexist safely in a single map.\n const pausedMap = useRef(\n new Map<string, { remaining: number; startedAt: number }>(),\n ).current;\n\n const toastManager = useRef<TimerManager | null>(null);\n const notifManager = useRef<TimerManager | null>(null);\n\n // Lazily create managers — deps are stable (useEvent / refs), so this runs once.\n if (!toastManager.current) {\n toastManager.current = createTimerManager(\n toastTimersMap,\n pausedMap,\n isPausedRef,\n (id) => removeToast(id),\n (internalId) =>\n toastsRef.current?.find((t) => t.internalId === internalId),\n );\n }\n\n if (!notifManager.current) {\n notifManager.current = createTimerManager(\n notificationTimersMap,\n pausedMap,\n isPausedRef,\n (id) => removeNotification(id, 'timeout'),\n (internalId) =>\n notificationsRef.current?.find((n) => n.internalId === internalId),\n );\n }\n\n // ─── Stable callbacks ──────────────────────────────────────────────\n\n const startToastTimer = useEvent(\n (internalId: string, id: Key, duration: number) => {\n toastManager.current!.start(internalId, id, duration);\n },\n );\n\n const clearToastTimer = useEvent((internalId: string) => {\n toastManager.current!.clear(internalId);\n });\n\n const startNotificationTimer = useEvent(\n (internalId: string, id: Key, duration: number) => {\n notifManager.current!.start(internalId, id, duration);\n },\n );\n\n const clearNotificationTimer = useEvent((internalId: string) => {\n notifManager.current!.clear(internalId);\n });\n\n // ─── Pause / Resume ─────────────────────────────────────────────\n\n const handlePauseChange = useEvent((paused: boolean) => {\n if (paused === isPausedRef.current) return;\n\n isPausedRef.current = paused;\n\n if (paused) {\n toastManager.current!.pauseAll();\n notifManager.current!.pauseAll();\n } else {\n toastManager.current!.resumeAll();\n notifManager.current!.resumeAll();\n }\n });\n\n // An effect can enqueue an item while paused just before an empty-stack\n // reset resumes timers. Retry once that item reaches the committed lookup,\n // preserving the deadlines of timers that are already running.\n useEffect(() => {\n if (!isPausedRef.current) {\n toastManager.current!.resumeAll();\n notifManager.current!.resumeAll();\n }\n });\n\n // ─── Cleanup on unmount ─────────────────────────────────────────\n\n useEffect(() => {\n return () => {\n toastManager.current!.clearAll();\n notifManager.current!.clearAll();\n pausedMap.clear();\n };\n }, []);\n\n return {\n startToastTimer,\n clearToastTimer,\n startNotificationTimer,\n clearNotificationTimer,\n handlePauseChange,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.208.0 | Cube Dev Team */
|
|
2
2
|
import { usePersistentNotificationsContext } from "./NotificationContext.js";
|
|
3
3
|
import { c } from "react/compiler-runtime";
|
|
4
4
|
//#region src/components/overlays/Notifications/use-persistent-notifications.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.208.0 | 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 { c } from "react/compiler-runtime";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-persistent-state.js","names":["Key","useRef","useState","useEvent","cleanupAndGetValidIds","saveDismissedId","PersistentNotificationItem","PersistentState","persistentItems","addPersistentItem","item","removePersistentItem","id","removePersistentItemsByOwner","ownerId","clearPersistentItems","markAllAsRead","hasDismissedPersistentId","isFullyDismissedId","saveDismissedPersistentId","undoFullyDismissedId","removePersistentItemSilently","usePersistentState","maxItems","$","_c","t0","Symbol","for","setPersistentItems","dismissedPersistentIdsRef","current","t1","Set","fullyDismissedIdsRef","t2","has","String","add","prev","existingIndex","findIndex","i","newItems","isRead","length","slice","sort","_temp","t3","prev_0","filter","i_0","t4","prev_1","i_1","t5","t6","_temp4","t7","id_0","t8","id_1","t9","id_2","t10","id_3","delete","t11","id_4","prev_3","i_4","t12","prev_2","hasUnread","some","_temp2","map","_temp3","i_3","i_2","a","b","createdAt","_c"],"sources":["../../../../src/components/overlays/Notifications/use-persistent-state.ts"],"sourcesContent":["import { Key, useRef, useState } from 'react';\n\nimport { useEvent } from '../../../_internal';\n\nimport { cleanupAndGetValidIds, saveDismissedId } from './dismissed-storage';\n\nimport type { PersistentNotificationItem } from './types';\n\n// ─── Types ───────────────────────────────────────────────────────────\n\nexport interface PersistentState {\n persistentItems: PersistentNotificationItem[];\n addPersistentItem: (item: PersistentNotificationItem) => void;\n removePersistentItem: (id: Key) => void;\n removePersistentItemsByOwner: (ownerId: string) => void;\n clearPersistentItems: () => void;\n markAllAsRead: () => void;\n /**\n * Returns true if the given id was previously moved to the persistent list\n * and has NOT been explicitly removed from it (i.e. still archived, or was\n * auto-dismissed but not yet user-dismissed from the persistent list).\n */\n hasDismissedPersistentId: (id: Key) => boolean;\n /**\n * Returns true if the given id was explicitly removed from the persistent\n * list by the user. Such notifications should be completely ignored on\n * subsequent triggers (no overlay, no persistent storage).\n */\n isFullyDismissedId: (id: Key) => boolean;\n /**\n * Marks an id as dismissed in both the in-memory set and localStorage.\n * Used for `'action'` dismissals that go through `removePersistentItem`\n * instead of `addPersistentItem`.\n */\n saveDismissedPersistentId: (id: Key) => void;\n /**\n * Removes an id from the fully-dismissed set.\n * Used to undo an `'action'` dismissal when the async action is cancelled.\n */\n undoFullyDismissedId: (id: Key) => void;\n /**\n * Removes an item from the persistent list without marking it as fully dismissed.\n * Used to undo a `'close'` dismissal that moved the notification to persistent.\n */\n removePersistentItemSilently: (id: Key) => void;\n}\n\n// ─── Hook ────────────────────────────────────────────────────────────\n\nexport function usePersistentState(maxItems: number): PersistentState {\n const [persistentItems, setPersistentItems] = useState<\n PersistentNotificationItem[]\n >([]);\n\n // Tracks IDs that have been moved to the persistent list at least once.\n // Used to skip the overlay when the same id reappears.\n // Lazy-initialized from localStorage so dismissed IDs survive page reloads.\n const dismissedPersistentIdsRef = useRef<Set<string> | null>(null);\n if (dismissedPersistentIdsRef.current === null) {\n dismissedPersistentIdsRef.current = cleanupAndGetValidIds();\n }\n\n // Tracks IDs that were explicitly removed from the persistent list by the\n // user. These should be completely ignored on subsequent triggers.\n const fullyDismissedIdsRef = useRef<Set<string>>(new Set());\n\n const addPersistentItem = useEvent((item: PersistentNotificationItem) => {\n // If the user already dismissed this item from the persistent list, don't re-add it.\n if (fullyDismissedIdsRef.current.has(String(item.id))) return;\n\n dismissedPersistentIdsRef.current!.add(String(item.id));\n saveDismissedId(item.id);\n\n setPersistentItems((prev) => {\n // Upsert by id\n const existingIndex = prev.findIndex((i) => i.id === item.id);\n let newItems: PersistentNotificationItem[];\n\n if (existingIndex !== -1) {\n newItems = [...prev];\n // Updated items are marked unread again\n newItems[existingIndex] = {\n ...newItems[existingIndex],\n ...item,\n isRead: false,\n };\n } else {\n newItems = [{ ...item, isRead: item.isRead ?? false }, ...prev];\n }\n\n // Enforce max cap\n if (newItems.length > maxItems) {\n newItems = newItems.slice(0, maxItems);\n }\n\n // Sort newest first\n newItems.sort((a, b) => b.createdAt - a.createdAt);\n\n return newItems;\n });\n });\n\n const removePersistentItem = useEvent((id: Key) => {\n fullyDismissedIdsRef.current.add(String(id));\n setPersistentItems((prev) => prev.filter((i) => i.id !== id));\n });\n\n const removePersistentItemsByOwner = useEvent((ownerId: string) => {\n setPersistentItems((prev) => prev.filter((i) => i.ownerId !== ownerId));\n });\n\n const clearPersistentItems = useEvent(() => {\n setPersistentItems([]);\n });\n\n const markAllAsRead = useEvent(() => {\n setPersistentItems((prev) => {\n const hasUnread = prev.some((i) => !i.isRead);\n\n if (!hasUnread) return prev;\n\n return prev.map((i) => (i.isRead ? i : { ...i, isRead: true }));\n });\n });\n\n const hasDismissedPersistentId = useEvent((id: Key): boolean => {\n return dismissedPersistentIdsRef.current!.has(String(id));\n });\n\n const isFullyDismissedId = useEvent((id: Key): boolean => {\n return fullyDismissedIdsRef.current.has(String(id));\n });\n\n const saveDismissedPersistentId = useEvent((id: Key): void => {\n dismissedPersistentIdsRef.current!.add(String(id));\n saveDismissedId(id);\n });\n\n const undoFullyDismissedId = useEvent((id: Key): void => {\n fullyDismissedIdsRef.current.delete(String(id));\n });\n\n const removePersistentItemSilently = useEvent((id: Key): void => {\n dismissedPersistentIdsRef.current!.delete(String(id));\n setPersistentItems((prev) => prev.filter((i) => i.id !== id));\n });\n\n return {\n persistentItems,\n addPersistentItem,\n removePersistentItem,\n removePersistentItemsByOwner,\n clearPersistentItems,\n markAllAsRead,\n hasDismissedPersistentId,\n isFullyDismissedId,\n saveDismissedPersistentId,\n undoFullyDismissedId,\n removePersistentItemSilently,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-persistent-state.js","names":["Key","useRef","useState","useEvent","cleanupAndGetValidIds","saveDismissedId","PersistentNotificationItem","PersistentState","persistentItems","addPersistentItem","item","removePersistentItem","id","removePersistentItemsByOwner","ownerId","clearPersistentItems","markAllAsRead","hasDismissedPersistentId","isFullyDismissedId","saveDismissedPersistentId","undoFullyDismissedId","removePersistentItemSilently","usePersistentState","maxItems","$","_c","t0","Symbol","for","setPersistentItems","dismissedPersistentIdsRef","current","t1","Set","fullyDismissedIdsRef","t2","has","String","add","prev","existingIndex","findIndex","i","newItems","isRead","length","slice","sort","_temp","t3","prev_0","filter","i_0","t4","prev_1","i_1","t5","t6","_temp4","t7","id_0","t8","id_1","t9","id_2","t10","id_3","delete","t11","id_4","prev_3","i_4","t12","prev_2","hasUnread","some","_temp2","map","_temp3","i_3","i_2","a","b","createdAt","_c"],"sources":["../../../../src/components/overlays/Notifications/use-persistent-state.ts"],"sourcesContent":["import { Key, useRef, useState } from 'react';\n\nimport { useEvent } from '../../../_internal/hooks/use-event';\n\nimport { cleanupAndGetValidIds, saveDismissedId } from './dismissed-storage';\n\nimport type { PersistentNotificationItem } from './types';\n\n// ─── Types ───────────────────────────────────────────────────────────\n\nexport interface PersistentState {\n persistentItems: PersistentNotificationItem[];\n addPersistentItem: (item: PersistentNotificationItem) => void;\n removePersistentItem: (id: Key) => void;\n removePersistentItemsByOwner: (ownerId: string) => void;\n clearPersistentItems: () => void;\n markAllAsRead: () => void;\n /**\n * Returns true if the given id was previously moved to the persistent list\n * and has NOT been explicitly removed from it (i.e. still archived, or was\n * auto-dismissed but not yet user-dismissed from the persistent list).\n */\n hasDismissedPersistentId: (id: Key) => boolean;\n /**\n * Returns true if the given id was explicitly removed from the persistent\n * list by the user. Such notifications should be completely ignored on\n * subsequent triggers (no overlay, no persistent storage).\n */\n isFullyDismissedId: (id: Key) => boolean;\n /**\n * Marks an id as dismissed in both the in-memory set and localStorage.\n * Used for `'action'` dismissals that go through `removePersistentItem`\n * instead of `addPersistentItem`.\n */\n saveDismissedPersistentId: (id: Key) => void;\n /**\n * Removes an id from the fully-dismissed set.\n * Used to undo an `'action'` dismissal when the async action is cancelled.\n */\n undoFullyDismissedId: (id: Key) => void;\n /**\n * Removes an item from the persistent list without marking it as fully dismissed.\n * Used to undo a `'close'` dismissal that moved the notification to persistent.\n */\n removePersistentItemSilently: (id: Key) => void;\n}\n\n// ─── Hook ────────────────────────────────────────────────────────────\n\nexport function usePersistentState(maxItems: number): PersistentState {\n const [persistentItems, setPersistentItems] = useState<\n PersistentNotificationItem[]\n >([]);\n\n // Tracks IDs that have been moved to the persistent list at least once.\n // Used to skip the overlay when the same id reappears.\n // Lazy-initialized from localStorage so dismissed IDs survive page reloads.\n const dismissedPersistentIdsRef = useRef<Set<string> | null>(null);\n if (dismissedPersistentIdsRef.current === null) {\n dismissedPersistentIdsRef.current = cleanupAndGetValidIds();\n }\n\n // Tracks IDs that were explicitly removed from the persistent list by the\n // user. These should be completely ignored on subsequent triggers.\n const fullyDismissedIdsRef = useRef<Set<string>>(new Set());\n\n const addPersistentItem = useEvent((item: PersistentNotificationItem) => {\n // If the user already dismissed this item from the persistent list, don't re-add it.\n if (fullyDismissedIdsRef.current.has(String(item.id))) return;\n\n dismissedPersistentIdsRef.current!.add(String(item.id));\n saveDismissedId(item.id);\n\n setPersistentItems((prev) => {\n // Upsert by id\n const existingIndex = prev.findIndex((i) => i.id === item.id);\n let newItems: PersistentNotificationItem[];\n\n if (existingIndex !== -1) {\n newItems = [...prev];\n // Updated items are marked unread again\n newItems[existingIndex] = {\n ...newItems[existingIndex],\n ...item,\n isRead: false,\n };\n } else {\n newItems = [{ ...item, isRead: item.isRead ?? false }, ...prev];\n }\n\n // Enforce max cap\n if (newItems.length > maxItems) {\n newItems = newItems.slice(0, maxItems);\n }\n\n // Sort newest first\n newItems.sort((a, b) => b.createdAt - a.createdAt);\n\n return newItems;\n });\n });\n\n const removePersistentItem = useEvent((id: Key) => {\n fullyDismissedIdsRef.current.add(String(id));\n setPersistentItems((prev) => prev.filter((i) => i.id !== id));\n });\n\n const removePersistentItemsByOwner = useEvent((ownerId: string) => {\n setPersistentItems((prev) => prev.filter((i) => i.ownerId !== ownerId));\n });\n\n const clearPersistentItems = useEvent(() => {\n setPersistentItems([]);\n });\n\n const markAllAsRead = useEvent(() => {\n setPersistentItems((prev) => {\n const hasUnread = prev.some((i) => !i.isRead);\n\n if (!hasUnread) return prev;\n\n return prev.map((i) => (i.isRead ? i : { ...i, isRead: true }));\n });\n });\n\n const hasDismissedPersistentId = useEvent((id: Key): boolean => {\n return dismissedPersistentIdsRef.current!.has(String(id));\n });\n\n const isFullyDismissedId = useEvent((id: Key): boolean => {\n return fullyDismissedIdsRef.current.has(String(id));\n });\n\n const saveDismissedPersistentId = useEvent((id: Key): void => {\n dismissedPersistentIdsRef.current!.add(String(id));\n saveDismissedId(id);\n });\n\n const undoFullyDismissedId = useEvent((id: Key): void => {\n fullyDismissedIdsRef.current.delete(String(id));\n });\n\n const removePersistentItemSilently = useEvent((id: Key): void => {\n dismissedPersistentIdsRef.current!.delete(String(id));\n setPersistentItems((prev) => prev.filter((i) => i.id !== id));\n });\n\n return {\n persistentItems,\n addPersistentItem,\n removePersistentItem,\n removePersistentItemsByOwner,\n clearPersistentItems,\n markAllAsRead,\n hasDismissedPersistentId,\n isFullyDismissedId,\n saveDismissedPersistentId,\n undoFullyDismissedId,\n removePersistentItemSilently,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.208.0 | Cube Dev Team */
|
|
2
2
|
import { useEvent } from "../../../_internal/hooks/use-event.js";
|
|
3
3
|
import { useRef, useState } from "react";
|
|
4
4
|
//#region src/components/overlays/Notifications/use-toast-state.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-toast-state.js","names":["Key","useRef","useState","useEvent","InternalToast","ToastData","OverlayTimers","DEFAULT_TOAST_DURATION","MAX_TOASTS","generateToastDedupeKey","data","id","String","JSON","stringify","description","theme","title","matchesToastId","item","internalId","findToast","list","find","t","ToastState","toasts","toastsRef","ReturnType","addToast","isProgress","removeToast","updateToast","Partial","finalizeToastRemoval","useToastState","timersRef","setToasts","current","idCounter","toast","clearToastTimer","prev","map","isExiting","filter","Date","now","dedupeKey","duration","undefined","newToast","createdAt","existingToast","wasEvicted","evictedIds","newToasts","activeToasts","progressToasts","temporalToasts","length","oldestTemporal","shift","push","idx","findIndex","splice","evictedId","startToastTimer"],"sources":["../../../../src/components/overlays/Notifications/use-toast-state.ts"],"sourcesContent":["import { Key, useRef, useState } from 'react';\n\nimport { useEvent } from '../../../_internal';\n\nimport type { InternalToast, ToastData } from '../Toast/types';\nimport type { OverlayTimers } from './use-overlay-timers';\n\n// ─── Constants ───────────────────────────────────────────────────────\n\nconst DEFAULT_TOAST_DURATION = 5000;\nconst MAX_TOASTS = 3;\n\n// ─── Dedupe Key ──────────────────────────────────────────────────────\n\n/**\n * Generate a deduplication key for a toast.\n * Uses JSON.stringify with alphabetically ordered keys to prevent false\n * collisions when title/description contains separator characters.\n */\nfunction generateToastDedupeKey(data: ToastData): string {\n if (data.id != null) return String(data.id);\n\n return JSON.stringify({\n description: typeof data.description === 'string' ? data.description : '',\n theme: data.theme ?? 'default',\n title: typeof data.title === 'string' ? data.title : '',\n });\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────\n\nfunction matchesToastId(item: InternalToast, id: Key): boolean {\n return item.id === id || item.internalId === String(id);\n}\n\nfunction findToast(list: InternalToast[], id: Key): InternalToast | undefined {\n return list.find((t) => matchesToastId(t, id));\n}\n\n// ─── Types ───────────────────────────────────────────────────────────\n\nexport interface ToastState {\n toasts: InternalToast[];\n toastsRef: ReturnType<typeof useRef<InternalToast[]>>;\n addToast: (data: ToastData, isProgress?: boolean) => Key;\n removeToast: (id: Key) => void;\n updateToast: (id: Key, data: Partial<ToastData>) => void;\n finalizeToastRemoval: (internalId: string) => void;\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 useToastState(\n timersRef: ReturnType<typeof useRef<OverlayTimers>>,\n): ToastState {\n const [toasts, setToasts] = useState<InternalToast[]>([]);\n const toastsRef = useRef(toasts);\n toastsRef.current = toasts;\n\n const idCounter = useRef(0);\n\n const removeToast = useEvent((id: Key) => {\n // Perform side effects outside the updater (StrictMode-safe).\n const toast = findToast(toastsRef.current, id);\n\n if (toast) {\n timersRef.current?.clearToastTimer(toast.internalId);\n }\n\n setToasts((prev) =>\n prev.map((t) => (matchesToastId(t, id) ? { ...t, isExiting: true } : t)),\n );\n });\n\n const finalizeToastRemoval = useEvent((internalId: string) => {\n setToasts((prev) => prev.filter((t) => t.internalId !== internalId));\n });\n\n const addToast = useEvent((data: ToastData, isProgress = false): Key => {\n idCounter.current += 1;\n const internalId = `toast-${idCounter.current}-${Date.now()}`;\n const dedupeKey = generateToastDedupeKey(data);\n // Only a missing duration takes the default: `null` keeps the toast.\n const duration = isProgress\n ? null\n : data.duration === undefined\n ? DEFAULT_TOAST_DURATION\n : data.duration;\n\n const newToast: InternalToast = {\n ...data,\n internalId,\n isProgress,\n dedupeKey,\n createdAt: Date.now(),\n };\n\n // Perform dedupe side effects outside the updater (StrictMode-safe).\n const existingToast = toastsRef.current.find(\n (t) => t.dedupeKey === dedupeKey && !t.isExiting,\n );\n\n if (existingToast) {\n timersRef.current?.clearToastTimer(existingToast.internalId);\n }\n\n // Single setState call: mark duplicate as exiting, append new toast,\n // and evict oldest temporal toasts if we exceed MAX_TOASTS.\n // Track evicted IDs so we can clear timers outside the updater (StrictMode-safe).\n let wasEvicted = false;\n const evictedIds: string[] = [];\n\n setToasts((prev) => {\n let newToasts = prev;\n\n // Mark existing toast with same dedupe key as exiting\n if (existingToast) {\n newToasts = newToasts.map((t) =>\n t.internalId === existingToast.internalId\n ? { ...t, isExiting: true }\n : t,\n );\n }\n\n // Append the new toast\n newToasts = [...newToasts, newToast];\n\n // Evict oldest temporal toasts if over the cap\n const activeToasts = newToasts.filter((t) => !t.isExiting);\n const progressToasts = activeToasts.filter((t) => t.isProgress);\n const temporalToasts = activeToasts.filter((t) => !t.isProgress);\n\n while (activeToasts.length > MAX_TOASTS) {\n if (temporalToasts.length > 1 || progressToasts.length < MAX_TOASTS) {\n const oldestTemporal = temporalToasts.shift();\n\n if (oldestTemporal) {\n evictedIds.push(oldestTemporal.internalId);\n newToasts = newToasts.map((t) =>\n t.internalId === oldestTemporal.internalId\n ? { ...t, isExiting: true }\n : t,\n );\n const idx = activeToasts.findIndex(\n (t) => t.internalId === oldestTemporal.internalId,\n );\n\n if (idx !== -1) activeToasts.splice(idx, 1);\n\n // Check if the newly added toast was evicted\n if (oldestTemporal.internalId === internalId) {\n wasEvicted = true;\n }\n } else {\n break;\n }\n } else {\n break;\n }\n }\n\n return newToasts;\n });\n\n // Clear timers for evicted toasts outside the updater (StrictMode-safe)\n for (const evictedId of evictedIds) {\n timersRef.current?.clearToastTimer(evictedId);\n }\n\n // Start timer only if the toast wasn't immediately evicted\n if (!wasEvicted && duration != null && duration > 0) {\n timersRef.current?.startToastTimer(\n internalId,\n data.id ?? internalId,\n duration,\n );\n }\n\n return data.id ?? internalId;\n });\n\n const updateToast = useEvent((id: Key, data: Partial<ToastData>) => {\n setToasts((prev) =>\n prev.map((t) => (matchesToastId(t, id) ? { ...t, ...data } : t)),\n );\n });\n\n return {\n toasts,\n toastsRef,\n addToast,\n removeToast,\n updateToast,\n finalizeToastRemoval,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-toast-state.js","names":["Key","useRef","useState","useEvent","InternalToast","ToastData","OverlayTimers","DEFAULT_TOAST_DURATION","MAX_TOASTS","generateToastDedupeKey","data","id","String","JSON","stringify","description","theme","title","matchesToastId","item","internalId","findToast","list","find","t","ToastState","toasts","toastsRef","ReturnType","addToast","isProgress","removeToast","updateToast","Partial","finalizeToastRemoval","useToastState","timersRef","setToasts","current","idCounter","toast","clearToastTimer","prev","map","isExiting","filter","Date","now","dedupeKey","duration","undefined","newToast","createdAt","existingToast","wasEvicted","evictedIds","newToasts","activeToasts","progressToasts","temporalToasts","length","oldestTemporal","shift","push","idx","findIndex","splice","evictedId","startToastTimer"],"sources":["../../../../src/components/overlays/Notifications/use-toast-state.ts"],"sourcesContent":["import { Key, useRef, useState } from 'react';\n\nimport { useEvent } from '../../../_internal/hooks/use-event';\n\nimport type { InternalToast, ToastData } from '../Toast/types';\nimport type { OverlayTimers } from './use-overlay-timers';\n\n// ─── Constants ───────────────────────────────────────────────────────\n\nconst DEFAULT_TOAST_DURATION = 5000;\nconst MAX_TOASTS = 3;\n\n// ─── Dedupe Key ──────────────────────────────────────────────────────\n\n/**\n * Generate a deduplication key for a toast.\n * Uses JSON.stringify with alphabetically ordered keys to prevent false\n * collisions when title/description contains separator characters.\n */\nfunction generateToastDedupeKey(data: ToastData): string {\n if (data.id != null) return String(data.id);\n\n return JSON.stringify({\n description: typeof data.description === 'string' ? data.description : '',\n theme: data.theme ?? 'default',\n title: typeof data.title === 'string' ? data.title : '',\n });\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────\n\nfunction matchesToastId(item: InternalToast, id: Key): boolean {\n return item.id === id || item.internalId === String(id);\n}\n\nfunction findToast(list: InternalToast[], id: Key): InternalToast | undefined {\n return list.find((t) => matchesToastId(t, id));\n}\n\n// ─── Types ───────────────────────────────────────────────────────────\n\nexport interface ToastState {\n toasts: InternalToast[];\n toastsRef: ReturnType<typeof useRef<InternalToast[]>>;\n addToast: (data: ToastData, isProgress?: boolean) => Key;\n removeToast: (id: Key) => void;\n updateToast: (id: Key, data: Partial<ToastData>) => void;\n finalizeToastRemoval: (internalId: string) => void;\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 useToastState(\n timersRef: ReturnType<typeof useRef<OverlayTimers>>,\n): ToastState {\n const [toasts, setToasts] = useState<InternalToast[]>([]);\n const toastsRef = useRef(toasts);\n toastsRef.current = toasts;\n\n const idCounter = useRef(0);\n\n const removeToast = useEvent((id: Key) => {\n // Perform side effects outside the updater (StrictMode-safe).\n const toast = findToast(toastsRef.current, id);\n\n if (toast) {\n timersRef.current?.clearToastTimer(toast.internalId);\n }\n\n setToasts((prev) =>\n prev.map((t) => (matchesToastId(t, id) ? { ...t, isExiting: true } : t)),\n );\n });\n\n const finalizeToastRemoval = useEvent((internalId: string) => {\n setToasts((prev) => prev.filter((t) => t.internalId !== internalId));\n });\n\n const addToast = useEvent((data: ToastData, isProgress = false): Key => {\n idCounter.current += 1;\n const internalId = `toast-${idCounter.current}-${Date.now()}`;\n const dedupeKey = generateToastDedupeKey(data);\n // Only a missing duration takes the default: `null` keeps the toast.\n const duration = isProgress\n ? null\n : data.duration === undefined\n ? DEFAULT_TOAST_DURATION\n : data.duration;\n\n const newToast: InternalToast = {\n ...data,\n internalId,\n isProgress,\n dedupeKey,\n createdAt: Date.now(),\n };\n\n // Perform dedupe side effects outside the updater (StrictMode-safe).\n const existingToast = toastsRef.current.find(\n (t) => t.dedupeKey === dedupeKey && !t.isExiting,\n );\n\n if (existingToast) {\n timersRef.current?.clearToastTimer(existingToast.internalId);\n }\n\n // Single setState call: mark duplicate as exiting, append new toast,\n // and evict oldest temporal toasts if we exceed MAX_TOASTS.\n // Track evicted IDs so we can clear timers outside the updater (StrictMode-safe).\n let wasEvicted = false;\n const evictedIds: string[] = [];\n\n setToasts((prev) => {\n let newToasts = prev;\n\n // Mark existing toast with same dedupe key as exiting\n if (existingToast) {\n newToasts = newToasts.map((t) =>\n t.internalId === existingToast.internalId\n ? { ...t, isExiting: true }\n : t,\n );\n }\n\n // Append the new toast\n newToasts = [...newToasts, newToast];\n\n // Evict oldest temporal toasts if over the cap\n const activeToasts = newToasts.filter((t) => !t.isExiting);\n const progressToasts = activeToasts.filter((t) => t.isProgress);\n const temporalToasts = activeToasts.filter((t) => !t.isProgress);\n\n while (activeToasts.length > MAX_TOASTS) {\n if (temporalToasts.length > 1 || progressToasts.length < MAX_TOASTS) {\n const oldestTemporal = temporalToasts.shift();\n\n if (oldestTemporal) {\n evictedIds.push(oldestTemporal.internalId);\n newToasts = newToasts.map((t) =>\n t.internalId === oldestTemporal.internalId\n ? { ...t, isExiting: true }\n : t,\n );\n const idx = activeToasts.findIndex(\n (t) => t.internalId === oldestTemporal.internalId,\n );\n\n if (idx !== -1) activeToasts.splice(idx, 1);\n\n // Check if the newly added toast was evicted\n if (oldestTemporal.internalId === internalId) {\n wasEvicted = true;\n }\n } else {\n break;\n }\n } else {\n break;\n }\n }\n\n return newToasts;\n });\n\n // Clear timers for evicted toasts outside the updater (StrictMode-safe)\n for (const evictedId of evictedIds) {\n timersRef.current?.clearToastTimer(evictedId);\n }\n\n // Start timer only if the toast wasn't immediately evicted\n if (!wasEvicted && duration != null && duration > 0) {\n timersRef.current?.startToastTimer(\n internalId,\n data.id ?? internalId,\n duration,\n );\n }\n\n return data.id ?? internalId;\n });\n\n const updateToast = useEvent((id: Key, data: Partial<ToastData>) => {\n setToasts((prev) =>\n prev.map((t) => (matchesToastId(t, id) ? { ...t, ...data } : t)),\n );\n });\n\n return {\n toasts,\n toastsRef,\n addToast,\n removeToast,\n updateToast,\n finalizeToastRemoval,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.208.0 | Cube Dev Team */
|
|
2
2
|
import { Item as _Item } from "../../content/Item/Item.js";
|
|
3
3
|
import { getThemeIcon } from "./useToast.js";
|
|
4
4
|
import { c } from "react/compiler-runtime";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.208.0 | Cube Dev Team */
|
|
2
2
|
import { useToastContext } from "../Notifications/NotificationContext.js";
|
|
3
|
-
import { useProgressToast } from "./useProgressToast.js";
|
|
4
3
|
import { getThemeIcon, useToast } from "./useToast.js";
|
|
5
4
|
import { ToastItem } from "./ToastItem.js";
|
|
5
|
+
import { useProgressToast } from "./useProgressToast.js";
|
|
6
6
|
import { c } from "react/compiler-runtime";
|
|
7
7
|
import { useEffect, useRef } from "react";
|
|
8
8
|
//#region src/components/overlays/Toast/index.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.208.0 | Cube Dev Team */
|
|
2
2
|
import { useEvent } from "../../../_internal/hooks/use-event.js";
|
|
3
3
|
import { ItemAction } from "../../actions/ItemAction/ItemAction.js";
|
|
4
4
|
import { useI18n } from "../../../i18n/useI18n.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useProgressToast.js","names":["Key","useEffect","useRef","useEvent","useI18n","ItemAction","useToastContext","ProgressToastEmpty","ProgressToastOptions","ToastData","RESULT_DURATION","isEmptyOptions","options","Object","keys","length","getStringValue","value","undefined","useProgressToast","addToast","removeToast","updateToast","t","toastIdRef","wasLoadingRef","hideTimerRef","ReturnType","setTimeout","isFirstRenderRef","optionsRef","hasBeenLoadingRef","hiddenByUserRef","prevThemeRef","prevTitleRef","prevDescriptionRef","current","clearHideTimer","clearTimeout","isEmpty","isLoading","isDismissable","currentTheme","theme","currentTitle","title","currentDescription","description","handleHide","wasLoading","isFirstRender","currentOptions","currentIsEmpty","currentIsLoading","_isDismissable","currentToastData","themeChanged","titleChanged","descriptionChanged","dataChanged","hideAction","mergedActions","actions","toastData","icon","itemProps","duration","showToast","showToastWithTimer"],"sources":["../../../../src/components/overlays/Toast/useProgressToast.tsx"],"sourcesContent":["import { Key, useEffect, useRef } from 'react';\n\nimport { useEvent } from '../../../_internal';\nimport { useI18n } from '../../../i18n';\nimport { ItemAction } from '../../actions/ItemAction/ItemAction';\n\nimport { useToastContext } from './ToastProvider';\n\nimport type {\n ProgressToastEmpty,\n ProgressToastOptions,\n ToastData,\n} from './types';\n\nconst RESULT_DURATION = 3000;\n\n/**\n * Check if the options represent an \"empty\" value (null, undefined, false, or empty object).\n * When empty, the hook should immediately remove any existing toast.\n */\nfunction isEmptyOptions(\n options: ProgressToastOptions | ProgressToastEmpty,\n): options is ProgressToastEmpty {\n if (options == null || options === false) return true;\n if (typeof options === 'object' && Object.keys(options).length === 0)\n return true;\n return false;\n}\n\n// Get string value for comparison (only strings are compared for re-show logic)\nfunction getStringValue(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\n/**\n * Hook to display a progress toast that persists while loading.\n *\n * @example\n * ```tsx\n * useProgressToast(\n * isLoading\n * ? { isLoading: true, title: 'Saving...', icon: <Spinner /> }\n * : { isLoading: false, title: 'Saved!', icon: <IconCheck />, theme: 'success' }\n * );\n *\n * // Or with error handling:\n * useProgressToast(\n * isLoading\n * ? { isLoading: true, title: 'Saving...', icon: <Spinner /> }\n * : isError\n * ? { isLoading: false, title: 'Error', description: errorMessage, theme: 'danger' }\n * : { isLoading: false, title: 'Saved!', theme: 'success' }\n * );\n *\n * // Pass empty value to immediately remove any existing toast:\n * useProgressToast(shouldShow ? { isLoading: true, title: 'Loading...' } : null);\n *\n * // Or call with no argument to dismiss:\n * useProgressToast();\n * ```\n */\nexport function useProgressToast(\n options?: ProgressToastOptions | ProgressToastEmpty,\n): void {\n const { addToast, removeToast, updateToast } = useToastContext();\n const { t } = useI18n();\n\n const toastIdRef = useRef<Key | null>(null);\n const wasLoadingRef = useRef<boolean | null>(null);\n const hideTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const isFirstRenderRef = useRef(true);\n const optionsRef = useRef(options);\n const hasBeenLoadingRef = useRef(false);\n const hiddenByUserRef = useRef(false);\n\n // Track previous string values for re-show comparison\n const prevThemeRef = useRef<string | undefined>(undefined);\n const prevTitleRef = useRef<string | undefined>(undefined);\n const prevDescriptionRef = useRef<string | undefined>(undefined);\n\n // Always update optionsRef to latest\n optionsRef.current = options;\n\n // Clear any pending hide timer\n const clearHideTimer = () => {\n if (hideTimerRef.current) {\n clearTimeout(hideTimerRef.current);\n hideTimerRef.current = null;\n }\n };\n\n // Check if current options are empty\n const isEmpty = isEmptyOptions(options);\n\n // Extract values only when options are not empty\n const isLoading = isEmpty ? false : options.isLoading;\n const isDismissable = isEmpty ? false : !!options.isDismissable;\n const currentTheme = isEmpty ? undefined : options.theme;\n const currentTitle = isEmpty ? undefined : getStringValue(options.title);\n const currentDescription = isEmpty\n ? undefined\n : getStringValue(options.description);\n\n const handleHide = useEvent(() => {\n if (toastIdRef.current != null) {\n removeToast(toastIdRef.current);\n toastIdRef.current = null;\n }\n\n hiddenByUserRef.current = true;\n });\n\n useEffect(() => {\n const wasLoading = wasLoadingRef.current;\n const isFirstRender = isFirstRenderRef.current;\n const currentOptions = optionsRef.current;\n const currentIsEmpty = isEmptyOptions(currentOptions);\n\n // Handle empty options - immediately remove any existing toast\n if (currentIsEmpty) {\n clearHideTimer();\n\n if (toastIdRef.current != null) {\n removeToast(toastIdRef.current);\n toastIdRef.current = null;\n }\n\n // Reset loading gate so the next cycle requires isLoading again\n hasBeenLoadingRef.current = false;\n hiddenByUserRef.current = false;\n wasLoadingRef.current = null;\n isFirstRenderRef.current = false;\n prevThemeRef.current = undefined;\n prevTitleRef.current = undefined;\n prevDescriptionRef.current = undefined;\n return;\n }\n\n // From here, we know options is a valid ProgressToastOptions\n const {\n isLoading: currentIsLoading,\n isDismissable: _isDismissable,\n ...currentToastData\n } = currentOptions;\n\n // Check if meaningful data changed (only string values)\n const themeChanged = currentTheme !== prevThemeRef.current;\n const titleChanged = currentTitle !== prevTitleRef.current;\n const descriptionChanged =\n currentDescription !== prevDescriptionRef.current;\n const dataChanged = themeChanged || titleChanged || descriptionChanged;\n\n const hideAction =\n isDismissable && currentIsLoading ? (\n <ItemAction isSelected type=\"outline\" onPress={handleHide}>\n {t('toast.hide', 'Hide')}\n </ItemAction>\n ) : null;\n\n const mergedActions = hideAction ? (\n <>\n {currentToastData.actions}\n {hideAction}\n </>\n ) : (\n currentToastData.actions\n );\n\n const toastData: ToastData = {\n title: undefined,\n description: undefined,\n theme: undefined,\n icon: undefined,\n itemProps: undefined,\n ...currentToastData,\n actions: mergedActions,\n isLoading: currentIsLoading,\n duration: null,\n };\n\n // Show a new toast or update an existing one in-place (no exit/enter animation).\n const showToast = () => {\n if (toastIdRef.current != null) {\n updateToast(toastIdRef.current, toastData);\n } else {\n toastIdRef.current = addToast(toastData, true);\n }\n };\n\n // Show/update toast and schedule removal after RESULT_DURATION.\n const showToastWithTimer = () => {\n showToast();\n\n hideTimerRef.current = setTimeout(() => {\n if (toastIdRef.current != null) {\n removeToast(toastIdRef.current);\n toastIdRef.current = null;\n }\n }, RESULT_DURATION);\n };\n\n if (currentIsLoading) {\n // Starting or continuing loading\n hasBeenLoadingRef.current = true;\n clearHideTimer();\n\n if (hiddenByUserRef.current) {\n // User dismissed the loading toast; don't re-show during this loading cycle.\n } else if (toastIdRef.current == null) {\n // Create new toast\n showToast();\n } else if (dataChanged) {\n // Toast exists but data changed (e.g., switching back to loading from another state)\n showToast();\n }\n } else if (wasLoading === true && !currentIsLoading) {\n // Transitioning from loading to not loading\n hiddenByUserRef.current = false;\n clearHideTimer();\n\n if (currentTitle) {\n // Show result toast with timer\n showToastWithTimer();\n } else {\n // No content - just remove the loading toast immediately\n if (toastIdRef.current != null) {\n removeToast(toastIdRef.current);\n toastIdRef.current = null;\n }\n }\n } else if (\n !currentIsLoading &&\n !isFirstRender &&\n hasBeenLoadingRef.current &&\n dataChanged &&\n toastIdRef.current != null\n ) {\n // Not loading, data changed while toast is still visible — update it.\n if (currentTitle) {\n clearHideTimer();\n showToastWithTimer();\n } else {\n clearHideTimer();\n removeToast(toastIdRef.current);\n toastIdRef.current = null;\n }\n }\n\n // Update refs for next comparison\n wasLoadingRef.current = currentIsLoading;\n isFirstRenderRef.current = false;\n prevThemeRef.current = currentTheme;\n prevTitleRef.current = currentTitle;\n prevDescriptionRef.current = currentDescription;\n }, [\n isEmpty,\n isLoading,\n isDismissable,\n currentTheme,\n currentTitle,\n currentDescription,\n addToast,\n removeToast,\n updateToast,\n handleHide,\n t,\n ]);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n clearHideTimer();\n\n if (toastIdRef.current != null) {\n removeToast(toastIdRef.current);\n toastIdRef.current = null;\n }\n };\n }, [removeToast]);\n}\n"],"mappings":";;;;;;;;AAcA,MAAMU,kBAAkB;;;;;AAMxB,SAASC,eACPC,SAC+B;CAC/B,IAAIA,WAAW,QAAQA,YAAY,OAAO,OAAO;CACjD,IAAI,OAAOA,YAAY,YAAYC,OAAOC,KAAKF,OAAO,CAAC,CAACG,WAAW,GACjE,OAAO;CACT,OAAO;AACT;AAGA,SAASC,eAAeC,OAAoC;CAC1D,OAAO,OAAOA,UAAU,WAAWA,QAAQC,KAAAA;AAC7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,SAAgBC,iBACdP,SACM;CACN,MAAM,EAAEQ,UAAUC,aAAaC,gBAAgBhB,gBAAgB;CAC/D,MAAM,EAAEiB,MAAMnB,QAAQ;CAEtB,MAAMoB,aAAatB,OAAmB,IAAI;CAC1C,MAAMuB,gBAAgBvB,OAAuB,IAAI;CACjD,MAAMwB,eAAexB,OAA6C,IAAI;CACtE,MAAM2B,mBAAmB3B,OAAO,IAAI;CACpC,MAAM4B,aAAa5B,OAAOU,OAAO;CACjC,MAAMmB,oBAAoB7B,OAAO,KAAK;CACtC,MAAM8B,kBAAkB9B,OAAO,KAAK;CAGpC,MAAM+B,eAAe/B,OAA2BgB,KAAAA,CAAS;CACzD,MAAMgB,eAAehC,OAA2BgB,KAAAA,CAAS;CACzD,MAAMiB,qBAAqBjC,OAA2BgB,KAAAA,CAAS;CAG/DY,WAAWM,UAAUxB;CAGrB,MAAMyB,uBAAuB;EAC3B,IAAIX,aAAaU,SAAS;GACxBE,aAAaZ,aAAaU,OAAO;GACjCV,aAAaU,UAAU;EACzB;CACF;CAGA,MAAMG,UAAU5B,eAAeC,OAAO;CAGtC,MAAM4B,YAAYD,UAAU,QAAQ3B,QAAQ4B;CAC5C,MAAMC,gBAAgBF,UAAU,QAAQ,CAAC,CAAC3B,QAAQ6B;CAClD,MAAMC,eAAeH,UAAUrB,KAAAA,IAAYN,QAAQ+B;CACnD,MAAMC,eAAeL,UAAUrB,KAAAA,IAAYF,eAAeJ,QAAQiC,KAAK;CACvE,MAAMC,qBAAqBP,UACvBrB,KAAAA,IACAF,eAAeJ,QAAQmC,WAAW;CAEtC,MAAMC,aAAa7C,eAAe;EAChC,IAAIqB,WAAWY,WAAW,MAAM;GAC9Bf,YAAYG,WAAWY,OAAO;GAC9BZ,WAAWY,UAAU;EACvB;EAEAJ,gBAAgBI,UAAU;CAC5B,CAAC;CAEDnC,gBAAgB;EACd,MAAMgD,aAAaxB,cAAcW;EACjC,MAAMc,gBAAgBrB,iBAAiBO;EACvC,MAAMe,iBAAiBrB,WAAWM;EAIlC,IAHuBzB,eAAewC,cAGlCC,GAAgB;GAClBf,eAAe;GAEf,IAAIb,WAAWY,WAAW,MAAM;IAC9Bf,YAAYG,WAAWY,OAAO;IAC9BZ,WAAWY,UAAU;GACvB;GAGAL,kBAAkBK,UAAU;GAC5BJ,gBAAgBI,UAAU;GAC1BX,cAAcW,UAAU;GACxBP,iBAAiBO,UAAU;GAC3BH,aAAaG,UAAUlB,KAAAA;GACvBgB,aAAaE,UAAUlB,KAAAA;GACvBiB,mBAAmBC,UAAUlB,KAAAA;GAC7B;EACF;EAGA,MAAM,EACJsB,WAAWa,kBACXZ,eAAea,gBACf,GAAGC,qBACDJ;EAGJ,MAAMK,eAAed,iBAAiBT,aAAaG;EACnD,MAAMqB,eAAeb,iBAAiBV,aAAaE;EACnD,MAAMsB,qBACJZ,uBAAuBX,mBAAmBC;EAC5C,MAAMuB,cAAcH,gBAAgBC,gBAAgBC;EAEpD,MAAME,aACJnB,iBAAiBY,mBACf,oBAAC,YAAD;GAAY,YAAA;GAAW,MAAK;GAAU,SAASL;GAC5CzB,UAAAA,EAAE,cAAc,MAAM;EACb,CAAA,IACV;EAEN,MAAMsC,gBAAgBD,aACpB,qBAAA,YAAA,EAAA,UAAA,CACGL,iBAAiBO,SACjBF,UACH,EAAA,CAAA,IAEAL,iBAAiBO;EAGnB,MAAMC,YAAuB;GAC3BlB,OAAO3B,KAAAA;GACP6B,aAAa7B,KAAAA;GACbyB,OAAOzB,KAAAA;GACP8C,MAAM9C,KAAAA;GACN+C,WAAW/C,KAAAA;GACX,GAAGqC;GACHO,SAASD;GACTrB,WAAWa;GACXa,UAAU;EACZ;EAGA,MAAMC,kBAAkB;GACtB,IAAI3C,WAAWY,WAAW,MACxBd,YAAYE,WAAWY,SAAS2B,SAAS;QAEzCvC,WAAWY,UAAUhB,SAAS2C,WAAW,IAAI;EAEjD;EAGA,MAAMK,2BAA2B;GAC/BD,UAAU;GAEVzC,aAAaU,UAAUR,iBAAiB;IACtC,IAAIJ,WAAWY,WAAW,MAAM;KAC9Bf,YAAYG,WAAWY,OAAO;KAC9BZ,WAAWY,UAAU;IACvB;GACF,GAAG1B,eAAe;EACpB;EAEA,IAAI2C,kBAAkB;GAEpBtB,kBAAkBK,UAAU;GAC5BC,eAAe;GAEf,IAAIL,gBAAgBI,SAAS,CAC3B,OACK,IAAIZ,WAAWY,WAAW,MAE/B+B,UAAU;QACL,IAAIR,aAETQ,UAAU;EAEd,OAAO,IAAIlB,eAAe,QAAQ,CAACI,kBAAkB;GAEnDrB,gBAAgBI,UAAU;GAC1BC,eAAe;GAEf,IAAIO,cAEFwB,mBAAmB;QAGnB,IAAI5C,WAAWY,WAAW,MAAM;IAC9Bf,YAAYG,WAAWY,OAAO;IAC9BZ,WAAWY,UAAU;GACvB;EAEJ,OAAO,IACL,CAACiB,oBACD,CAACH,iBACDnB,kBAAkBK,WAClBuB,eACAnC,WAAWY,WAAW,MACtB;GAEA,IAAIQ,cAAc;IAChBP,eAAe;IACf+B,mBAAmB;GACrB,OAAO;IACL/B,eAAe;IACfhB,YAAYG,WAAWY,OAAO;IAC9BZ,WAAWY,UAAU;GACvB;EACF;EAGAX,cAAcW,UAAUiB;EACxBxB,iBAAiBO,UAAU;EAC3BH,aAAaG,UAAUM;EACvBR,aAAaE,UAAUQ;EACvBT,mBAAmBC,UAAUU;CAC/B,GAAG;EACDP;EACAC;EACAC;EACAC;EACAE;EACAE;EACA1B;EACAC;EACAC;EACA0B;EACAzB;CAAC,CACF;CAGDtB,gBAAgB;EACd,aAAa;GACXoC,eAAe;GAEf,IAAIb,WAAWY,WAAW,MAAM;IAC9Bf,YAAYG,WAAWY,OAAO;IAC9BZ,WAAWY,UAAU;GACvB;EACF;CACF,GAAG,CAACf,WAAW,CAAC;AAClB"}
|
|
1
|
+
{"version":3,"file":"useProgressToast.js","names":["Key","useEffect","useRef","useEvent","useI18n","ItemAction","useToastContext","ProgressToastEmpty","ProgressToastOptions","ToastData","RESULT_DURATION","isEmptyOptions","options","Object","keys","length","getStringValue","value","undefined","useProgressToast","addToast","removeToast","updateToast","t","toastIdRef","wasLoadingRef","hideTimerRef","ReturnType","setTimeout","isFirstRenderRef","optionsRef","hasBeenLoadingRef","hiddenByUserRef","prevThemeRef","prevTitleRef","prevDescriptionRef","current","clearHideTimer","clearTimeout","isEmpty","isLoading","isDismissable","currentTheme","theme","currentTitle","title","currentDescription","description","handleHide","wasLoading","isFirstRender","currentOptions","currentIsEmpty","currentIsLoading","_isDismissable","currentToastData","themeChanged","titleChanged","descriptionChanged","dataChanged","hideAction","mergedActions","actions","toastData","icon","itemProps","duration","showToast","showToastWithTimer"],"sources":["../../../../src/components/overlays/Toast/useProgressToast.tsx"],"sourcesContent":["import { Key, useEffect, useRef } from 'react';\n\nimport { useEvent } from '../../../_internal/hooks/use-event';\nimport { useI18n } from '../../../i18n/useI18n';\nimport { ItemAction } from '../../actions/ItemAction/ItemAction';\n\nimport { useToastContext } from './ToastProvider';\n\nimport type {\n ProgressToastEmpty,\n ProgressToastOptions,\n ToastData,\n} from './types';\n\nconst RESULT_DURATION = 3000;\n\n/**\n * Check if the options represent an \"empty\" value (null, undefined, false, or empty object).\n * When empty, the hook should immediately remove any existing toast.\n */\nfunction isEmptyOptions(\n options: ProgressToastOptions | ProgressToastEmpty,\n): options is ProgressToastEmpty {\n if (options == null || options === false) return true;\n if (typeof options === 'object' && Object.keys(options).length === 0)\n return true;\n return false;\n}\n\n// Get string value for comparison (only strings are compared for re-show logic)\nfunction getStringValue(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\n/**\n * Hook to display a progress toast that persists while loading.\n *\n * @example\n * ```tsx\n * useProgressToast(\n * isLoading\n * ? { isLoading: true, title: 'Saving...', icon: <Spinner /> }\n * : { isLoading: false, title: 'Saved!', icon: <IconCheck />, theme: 'success' }\n * );\n *\n * // Or with error handling:\n * useProgressToast(\n * isLoading\n * ? { isLoading: true, title: 'Saving...', icon: <Spinner /> }\n * : isError\n * ? { isLoading: false, title: 'Error', description: errorMessage, theme: 'danger' }\n * : { isLoading: false, title: 'Saved!', theme: 'success' }\n * );\n *\n * // Pass empty value to immediately remove any existing toast:\n * useProgressToast(shouldShow ? { isLoading: true, title: 'Loading...' } : null);\n *\n * // Or call with no argument to dismiss:\n * useProgressToast();\n * ```\n */\nexport function useProgressToast(\n options?: ProgressToastOptions | ProgressToastEmpty,\n): void {\n const { addToast, removeToast, updateToast } = useToastContext();\n const { t } = useI18n();\n\n const toastIdRef = useRef<Key | null>(null);\n const wasLoadingRef = useRef<boolean | null>(null);\n const hideTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const isFirstRenderRef = useRef(true);\n const optionsRef = useRef(options);\n const hasBeenLoadingRef = useRef(false);\n const hiddenByUserRef = useRef(false);\n\n // Track previous string values for re-show comparison\n const prevThemeRef = useRef<string | undefined>(undefined);\n const prevTitleRef = useRef<string | undefined>(undefined);\n const prevDescriptionRef = useRef<string | undefined>(undefined);\n\n // Always update optionsRef to latest\n optionsRef.current = options;\n\n // Clear any pending hide timer\n const clearHideTimer = () => {\n if (hideTimerRef.current) {\n clearTimeout(hideTimerRef.current);\n hideTimerRef.current = null;\n }\n };\n\n // Check if current options are empty\n const isEmpty = isEmptyOptions(options);\n\n // Extract values only when options are not empty\n const isLoading = isEmpty ? false : options.isLoading;\n const isDismissable = isEmpty ? false : !!options.isDismissable;\n const currentTheme = isEmpty ? undefined : options.theme;\n const currentTitle = isEmpty ? undefined : getStringValue(options.title);\n const currentDescription = isEmpty\n ? undefined\n : getStringValue(options.description);\n\n const handleHide = useEvent(() => {\n if (toastIdRef.current != null) {\n removeToast(toastIdRef.current);\n toastIdRef.current = null;\n }\n\n hiddenByUserRef.current = true;\n });\n\n useEffect(() => {\n const wasLoading = wasLoadingRef.current;\n const isFirstRender = isFirstRenderRef.current;\n const currentOptions = optionsRef.current;\n const currentIsEmpty = isEmptyOptions(currentOptions);\n\n // Handle empty options - immediately remove any existing toast\n if (currentIsEmpty) {\n clearHideTimer();\n\n if (toastIdRef.current != null) {\n removeToast(toastIdRef.current);\n toastIdRef.current = null;\n }\n\n // Reset loading gate so the next cycle requires isLoading again\n hasBeenLoadingRef.current = false;\n hiddenByUserRef.current = false;\n wasLoadingRef.current = null;\n isFirstRenderRef.current = false;\n prevThemeRef.current = undefined;\n prevTitleRef.current = undefined;\n prevDescriptionRef.current = undefined;\n return;\n }\n\n // From here, we know options is a valid ProgressToastOptions\n const {\n isLoading: currentIsLoading,\n isDismissable: _isDismissable,\n ...currentToastData\n } = currentOptions;\n\n // Check if meaningful data changed (only string values)\n const themeChanged = currentTheme !== prevThemeRef.current;\n const titleChanged = currentTitle !== prevTitleRef.current;\n const descriptionChanged =\n currentDescription !== prevDescriptionRef.current;\n const dataChanged = themeChanged || titleChanged || descriptionChanged;\n\n const hideAction =\n isDismissable && currentIsLoading ? (\n <ItemAction isSelected type=\"outline\" onPress={handleHide}>\n {t('toast.hide', 'Hide')}\n </ItemAction>\n ) : null;\n\n const mergedActions = hideAction ? (\n <>\n {currentToastData.actions}\n {hideAction}\n </>\n ) : (\n currentToastData.actions\n );\n\n const toastData: ToastData = {\n title: undefined,\n description: undefined,\n theme: undefined,\n icon: undefined,\n itemProps: undefined,\n ...currentToastData,\n actions: mergedActions,\n isLoading: currentIsLoading,\n duration: null,\n };\n\n // Show a new toast or update an existing one in-place (no exit/enter animation).\n const showToast = () => {\n if (toastIdRef.current != null) {\n updateToast(toastIdRef.current, toastData);\n } else {\n toastIdRef.current = addToast(toastData, true);\n }\n };\n\n // Show/update toast and schedule removal after RESULT_DURATION.\n const showToastWithTimer = () => {\n showToast();\n\n hideTimerRef.current = setTimeout(() => {\n if (toastIdRef.current != null) {\n removeToast(toastIdRef.current);\n toastIdRef.current = null;\n }\n }, RESULT_DURATION);\n };\n\n if (currentIsLoading) {\n // Starting or continuing loading\n hasBeenLoadingRef.current = true;\n clearHideTimer();\n\n if (hiddenByUserRef.current) {\n // User dismissed the loading toast; don't re-show during this loading cycle.\n } else if (toastIdRef.current == null) {\n // Create new toast\n showToast();\n } else if (dataChanged) {\n // Toast exists but data changed (e.g., switching back to loading from another state)\n showToast();\n }\n } else if (wasLoading === true && !currentIsLoading) {\n // Transitioning from loading to not loading\n hiddenByUserRef.current = false;\n clearHideTimer();\n\n if (currentTitle) {\n // Show result toast with timer\n showToastWithTimer();\n } else {\n // No content - just remove the loading toast immediately\n if (toastIdRef.current != null) {\n removeToast(toastIdRef.current);\n toastIdRef.current = null;\n }\n }\n } else if (\n !currentIsLoading &&\n !isFirstRender &&\n hasBeenLoadingRef.current &&\n dataChanged &&\n toastIdRef.current != null\n ) {\n // Not loading, data changed while toast is still visible — update it.\n if (currentTitle) {\n clearHideTimer();\n showToastWithTimer();\n } else {\n clearHideTimer();\n removeToast(toastIdRef.current);\n toastIdRef.current = null;\n }\n }\n\n // Update refs for next comparison\n wasLoadingRef.current = currentIsLoading;\n isFirstRenderRef.current = false;\n prevThemeRef.current = currentTheme;\n prevTitleRef.current = currentTitle;\n prevDescriptionRef.current = currentDescription;\n }, [\n isEmpty,\n isLoading,\n isDismissable,\n currentTheme,\n currentTitle,\n currentDescription,\n addToast,\n removeToast,\n updateToast,\n handleHide,\n t,\n ]);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n clearHideTimer();\n\n if (toastIdRef.current != null) {\n removeToast(toastIdRef.current);\n toastIdRef.current = null;\n }\n };\n }, [removeToast]);\n}\n"],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.208.0 | Cube Dev Team */
|
|
2
2
|
import { CheckIcon } from "../../../icons/CheckIcon.js";
|
|
3
3
|
import { InfoCircleIcon } from "../../../icons/InfoCircleIcon.js";
|
|
4
|
-
import { useToastContext } from "../Notifications/NotificationContext.js";
|
|
5
4
|
import { DangerIcon } from "../../../icons/DangerIcon.js";
|
|
6
5
|
import { WarningIcon } from "../../../icons/WarningIcon.js";
|
|
6
|
+
import { useToastContext } from "../Notifications/NotificationContext.js";
|
|
7
7
|
import { isValidElement, useMemo } from "react";
|
|
8
8
|
import { jsx } from "react/jsx-runtime";
|
|
9
9
|
//#region src/components/overlays/Toast/useToast.tsx
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.208.0 | Cube Dev Team */
|
|
2
2
|
import { extractStyles } from "../../../utils/styles.js";
|
|
3
3
|
import { useLayoutEffect as useLayoutEffect$1 } from "../../../utils/react/useLayoutEffect.js";
|
|
4
4
|
import { mergeProps as mergeProps$1 } from "../../../utils/react/mergeProps.js";
|