@astryxdesign/core 0.1.1 → 0.1.2-canary.04e71b2
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/CHANGELOG.md +105 -0
- package/README.md +131 -13
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +11 -5
- package/dist/AvatarGroup/AvatarGroupOverflow.d.ts +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.js +4 -1
- package/dist/Banner/Banner.d.ts +7 -0
- package/dist/Banner/Banner.d.ts.map +1 -1
- package/dist/Banner/Banner.js +9 -2
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.js +24 -5
- package/dist/Button/Button.d.ts +12 -2
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +53 -17
- package/dist/Calendar/Calendar.d.ts +5 -4
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +82 -43
- package/dist/Calendar/hooks/index.d.ts +0 -2
- package/dist/Calendar/hooks/index.d.ts.map +1 -1
- package/dist/Calendar/hooks/index.js +1 -2
- package/dist/Calendar/index.d.ts +3 -3
- package/dist/Calendar/index.d.ts.map +1 -1
- package/dist/Calendar/index.js +1 -1
- package/dist/Calendar/styles.d.ts +3 -9
- package/dist/Calendar/styles.d.ts.map +1 -1
- package/dist/Calendar/styles.js +3 -11
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +17 -3
- package/dist/Center/Center.d.ts +11 -1
- package/dist/Center/Center.d.ts.map +1 -1
- package/dist/Center/Center.js +9 -3
- package/dist/Chat/ChatMessageList.d.ts +14 -1
- package/dist/Chat/ChatMessageList.d.ts.map +1 -1
- package/dist/Chat/ChatMessageList.js +2 -0
- package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
- package/dist/Chat/useTriggerMenu.js +4 -1
- package/dist/CheckboxInput/CheckboxInput.d.ts +23 -2
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +51 -9
- package/dist/CheckboxList/CheckboxList.d.ts +13 -1
- package/dist/CheckboxList/CheckboxList.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxList.js +39 -9
- package/dist/CheckboxList/CheckboxListContext.d.ts +7 -0
- package/dist/CheckboxList/CheckboxListContext.d.ts.map +1 -1
- package/dist/Citation/Citation.d.ts.map +1 -1
- package/dist/Citation/Citation.js +3 -3
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +49 -37
- package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPalette.js +5 -5
- package/dist/ContextMenu/ContextMenu.d.ts +4 -5
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +93 -11
- package/dist/DateInput/DateInput.d.ts +23 -1
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +59 -8
- package/dist/DateRangeInput/DateRangeInput.d.ts +23 -1
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +42 -9
- package/dist/DateTimeInput/DateTimeInput.d.ts +35 -2
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +78 -15
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +12 -0
- package/dist/DropdownMenu/DropdownMenu.d.ts +1 -8
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +42 -14
- package/dist/EmptyState/EmptyState.d.ts.map +1 -1
- package/dist/EmptyState/EmptyState.js +7 -1
- package/dist/Field/Field.d.ts +19 -2
- package/dist/Field/Field.d.ts.map +1 -1
- package/dist/Field/Field.js +4 -0
- package/dist/Field/FieldLabel.d.ts +21 -2
- package/dist/Field/FieldLabel.d.ts.map +1 -1
- package/dist/Field/FieldLabel.js +41 -26
- package/dist/FileInput/FileInput.d.ts +22 -1
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +56 -10
- package/dist/Grid/Grid.d.ts +11 -1
- package/dist/Grid/Grid.d.ts.map +1 -1
- package/dist/Grid/Grid.js +8 -0
- package/dist/HoverCard/HoverCard.d.ts +2 -2
- package/dist/HoverCard/HoverCard.d.ts.map +1 -1
- package/dist/HoverCard/HoverCard.js +18 -6
- package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
- package/dist/HoverCard/useHoverCard.js +7 -3
- package/dist/InputGroup/InputGroup.d.ts +2 -2
- package/dist/InputGroup/InputGroup.d.ts.map +1 -1
- package/dist/InputGroup/InputGroup.js +14 -5
- package/dist/InputGroup/InputGroupContext.d.ts +4 -0
- package/dist/InputGroup/InputGroupContext.d.ts.map +1 -1
- package/dist/InputGroup/InputGroupContext.js +2 -2
- package/dist/InputGroup/index.d.ts +1 -0
- package/dist/InputGroup/index.d.ts.map +1 -1
- package/dist/Kbd/Kbd.d.ts.map +1 -1
- package/dist/Kbd/Kbd.js +34 -2
- package/dist/Layer/anchorName.d.ts +20 -0
- package/dist/Layer/anchorName.d.ts.map +1 -0
- package/dist/Layer/anchorName.js +36 -0
- package/dist/Layer/layerAnimations.stylex.d.ts +4 -0
- package/dist/Layer/layerAnimations.stylex.d.ts.map +1 -1
- package/dist/Layer/layerAnimations.stylex.js +8 -4
- package/dist/Layer/useLayer.d.ts +29 -0
- package/dist/Layer/useLayer.d.ts.map +1 -1
- package/dist/Layer/useLayer.js +55 -11
- package/dist/Layout/Layout.d.ts +4 -11
- package/dist/Layout/Layout.d.ts.map +1 -1
- package/dist/Layout/Layout.js +10 -11
- package/dist/Layout/LayoutFooter.d.ts +2 -2
- package/dist/Layout/LayoutFooter.d.ts.map +1 -1
- package/dist/Layout/LayoutHeader.d.ts +2 -2
- package/dist/Layout/LayoutHeader.d.ts.map +1 -1
- package/dist/Layout/LayoutPanel.d.ts +2 -2
- package/dist/Layout/LayoutPanel.d.ts.map +1 -1
- package/dist/Layout/padding.stylex.d.ts +51 -0
- package/dist/Layout/padding.stylex.d.ts.map +1 -1
- package/dist/Layout/padding.stylex.js +63 -0
- package/dist/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/Lightbox/Lightbox.js +4 -2
- package/dist/Link/Link.d.ts +17 -2
- package/dist/Link/Link.d.ts.map +1 -1
- package/dist/Link/Link.js +20 -9
- package/dist/Link/LinkProvider.d.ts +1 -0
- package/dist/Link/LinkProvider.d.ts.map +1 -1
- package/dist/Link/LinkProvider.js +1 -0
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.js +18 -3
- package/dist/MobileNav/MobileNav.d.ts.map +1 -1
- package/dist/MobileNav/MobileNav.js +13 -0
- package/dist/MoreMenu/MoreMenu.d.ts +1 -7
- package/dist/MoreMenu/MoreMenu.d.ts.map +1 -1
- package/dist/MoreMenu/MoreMenu.js +0 -2
- package/dist/MultiSelector/MultiSelector.d.ts +25 -2
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +103 -22
- package/dist/MultiSelector/hooks.d.ts +12 -1
- package/dist/MultiSelector/hooks.d.ts.map +1 -1
- package/dist/MultiSelector/hooks.js +14 -1
- package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
- package/dist/NavMenu/NavHeadingMenu.js +34 -3
- package/dist/NumberInput/NumberInput.d.ts +23 -2
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +62 -12
- package/dist/Pagination/Pagination.d.ts +1 -1
- package/dist/Pagination/Pagination.d.ts.map +1 -1
- package/dist/Pagination/Pagination.js +46 -28
- package/dist/Popover/usePopover.d.ts +25 -2
- package/dist/Popover/usePopover.d.ts.map +1 -1
- package/dist/Popover/usePopover.js +18 -6
- package/dist/PowerSearch/PowerSearch.d.ts +11 -1
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +6 -1
- package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
- package/dist/ProgressBar/ProgressBar.js +3 -5
- package/dist/RadioList/RadioList.d.ts +20 -2
- package/dist/RadioList/RadioList.d.ts.map +1 -1
- package/dist/RadioList/RadioList.js +105 -9
- package/dist/RadioList/RadioListItem.d.ts.map +1 -1
- package/dist/RadioList/RadioListItem.js +13 -2
- package/dist/SegmentedControl/SegmentedControl.d.ts +13 -2
- package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControl.js +78 -44
- package/dist/SegmentedControl/SegmentedControlContext.d.ts +7 -0
- package/dist/SegmentedControl/SegmentedControlContext.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.js +13 -2
- package/dist/Selector/Selector.d.ts +22 -1
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +84 -23
- package/dist/Selector/hooks.d.ts +8 -1
- package/dist/Selector/hooks.d.ts.map +1 -1
- package/dist/Selector/hooks.js +14 -1
- package/dist/SideNav/SideNavItem.d.ts.map +1 -1
- package/dist/SideNav/SideNavItem.js +1 -1
- package/dist/Skeleton/Skeleton.d.ts.map +1 -1
- package/dist/Skeleton/Skeleton.js +8 -2
- package/dist/Slider/Slider.d.ts +21 -0
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +38 -11
- package/dist/Spinner/Spinner.d.ts.map +1 -1
- package/dist/Spinner/Spinner.js +1 -1
- package/dist/Stack/Stack.d.ts +38 -23
- package/dist/Stack/Stack.d.ts.map +1 -1
- package/dist/Stack/Stack.js +25 -1
- package/dist/Stack/StackItem.d.ts +12 -23
- package/dist/Stack/StackItem.d.ts.map +1 -1
- package/dist/Stack/StackItem.js +8 -1
- package/dist/Switch/Switch.d.ts +23 -2
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +41 -11
- package/dist/TabList/Tab.d.ts.map +1 -1
- package/dist/TabList/Tab.js +6 -0
- package/dist/TabList/TabList.d.ts +16 -4
- package/dist/TabList/TabList.d.ts.map +1 -1
- package/dist/TabList/TabList.js +86 -10
- package/dist/TabList/TabListContext.d.ts +5 -0
- package/dist/TabList/TabListContext.d.ts.map +1 -1
- package/dist/TabList/TabListContext.js +5 -0
- package/dist/TabList/TabMenu.d.ts.map +1 -1
- package/dist/TabList/TabMenu.js +6 -1
- package/dist/Table/BaseTable.d.ts.map +1 -1
- package/dist/Table/BaseTable.js +38 -16
- package/dist/Table/Table.d.ts.map +1 -1
- package/dist/Table/Table.js +36 -7
- package/dist/Table/TableCell.d.ts +8 -1
- package/dist/Table/TableCell.d.ts.map +1 -1
- package/dist/Table/TableCell.js +10 -10
- package/dist/Table/TableHeaderCell.d.ts +8 -1
- package/dist/Table/TableHeaderCell.d.ts.map +1 -1
- package/dist/Table/TableHeaderCell.js +16 -16
- package/dist/Table/TableRow.d.ts +6 -1
- package/dist/Table/TableRow.d.ts.map +1 -1
- package/dist/Table/TableRow.js +15 -7
- package/dist/Table/index.d.ts +4 -1
- package/dist/Table/index.d.ts.map +1 -1
- package/dist/Table/index.js +3 -2
- package/dist/Table/plugins/pagination/paginateData.d.ts +2 -1
- package/dist/Table/plugins/pagination/paginateData.d.ts.map +1 -1
- package/dist/Table/plugins/pagination/paginateData.js +8 -3
- package/dist/Table/plugins/pagination/useTablePagination.d.ts.map +1 -1
- package/dist/Table/plugins/pagination/useTablePagination.js +6 -1
- package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
- package/dist/Table/plugins/sortable/useTableSortable.js +59 -3
- package/dist/Table/plugins/stickyColumns/index.d.ts +3 -0
- package/dist/Table/plugins/stickyColumns/index.d.ts.map +1 -0
- package/dist/Table/plugins/stickyColumns/index.js +3 -0
- package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts +25 -0
- package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -0
- package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +369 -0
- package/dist/Table/tableContextMenu.d.ts +33 -0
- package/dist/Table/tableContextMenu.d.ts.map +1 -0
- package/dist/Table/tableContextMenu.js +133 -0
- package/dist/Table/types.d.ts +161 -5
- package/dist/Table/types.d.ts.map +1 -1
- package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
- package/dist/Table/useBaseTablePlugins.js +1 -1
- package/dist/Text/text.stylex.d.ts +2 -2
- package/dist/Text/text.stylex.js +2 -2
- package/dist/TextArea/TextArea.d.ts +22 -1
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +41 -9
- package/dist/TextInput/TextInput.d.ts +23 -2
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +55 -10
- package/dist/TimeInput/TimeInput.d.ts +23 -1
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +53 -10
- package/dist/Timestamp/Timestamp.d.ts +1 -1
- package/dist/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +28 -3
- package/dist/Toast/Toast.d.ts.map +1 -1
- package/dist/Toast/Toast.js +14 -0
- package/dist/Toast/ToastViewport.d.ts.map +1 -1
- package/dist/Toast/ToastViewport.js +132 -3
- package/dist/ToggleButton/ToggleButton.d.ts +7 -9
- package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
- package/dist/ToggleButton/ToggleButton.js +34 -57
- package/dist/Tokenizer/Tokenizer.d.ts +12 -1
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +27 -5
- package/dist/Toolbar/Toolbar.d.ts +3 -3
- package/dist/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/Toolbar/Toolbar.js +51 -7
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +57 -9
- package/dist/TreeList/TreeList.d.ts +1 -1
- package/dist/TreeList/TreeList.d.ts.map +1 -1
- package/dist/TreeList/TreeList.js +72 -2
- package/dist/TreeList/TreeListItem.d.ts +11 -1
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +51 -12
- package/dist/TreeList/treeListItem.markers.stylex.d.ts +16 -0
- package/dist/TreeList/treeListItem.markers.stylex.d.ts.map +1 -0
- package/dist/TreeList/treeListItem.markers.stylex.js +22 -0
- package/dist/Typeahead/BaseTypeahead.d.ts +9 -0
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +67 -6
- package/dist/Typeahead/Typeahead.d.ts +24 -1
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +29 -5
- package/dist/VisuallyHidden/VisuallyHidden.d.ts +61 -0
- package/dist/VisuallyHidden/VisuallyHidden.d.ts.map +1 -0
- package/dist/VisuallyHidden/VisuallyHidden.js +65 -0
- package/dist/VisuallyHidden/index.d.ts +11 -0
- package/dist/VisuallyHidden/index.d.ts.map +1 -0
- package/dist/VisuallyHidden/index.js +13 -0
- package/dist/astryx.css +40 -1
- package/dist/astryx.umd.js +147 -0
- package/dist/astryx.umd.js.map +7 -0
- package/dist/hooks/focusableSelector.d.ts +22 -0
- package/dist/hooks/focusableSelector.d.ts.map +1 -0
- package/dist/hooks/focusableSelector.js +24 -0
- package/dist/hooks/index.d.ts +12 -2
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +7 -2
- package/dist/hooks/useAnnounce.d.ts +40 -0
- package/dist/hooks/useAnnounce.d.ts.map +1 -0
- package/dist/hooks/useAnnounce.js +142 -0
- package/dist/hooks/useClickableContainer.d.ts +16 -1
- package/dist/hooks/useClickableContainer.d.ts.map +1 -1
- package/dist/hooks/useClickableContainer.js +16 -4
- package/dist/hooks/useEntryAnimation.d.ts.map +1 -1
- package/dist/hooks/useEntryAnimation.js +4 -4
- package/dist/hooks/useFocusTrap.d.ts +18 -0
- package/dist/hooks/useFocusTrap.d.ts.map +1 -1
- package/dist/hooks/useFocusTrap.js +87 -3
- package/dist/hooks/useGridFocus.d.ts +88 -1
- package/dist/hooks/useGridFocus.d.ts.map +1 -1
- package/dist/hooks/useGridFocus.js +261 -62
- package/dist/hooks/useKeyboardHint.d.ts +82 -0
- package/dist/hooks/useKeyboardHint.d.ts.map +1 -0
- package/dist/hooks/useKeyboardHint.js +220 -0
- package/dist/hooks/useListFocus.d.ts +78 -7
- package/dist/hooks/useListFocus.d.ts.map +1 -1
- package/dist/hooks/useListFocus.js +305 -52
- package/dist/hooks/useLongPress.d.ts +21 -0
- package/dist/hooks/useLongPress.d.ts.map +1 -0
- package/dist/hooks/useLongPress.js +89 -0
- package/dist/hooks/useTreeFocus.d.ts +157 -0
- package/dist/hooks/useTreeFocus.d.ts.map +1 -0
- package/dist/hooks/useTreeFocus.js +337 -0
- package/dist/hooks/useTypeahead.d.ts +63 -0
- package/dist/hooks/useTypeahead.d.ts.map +1 -0
- package/dist/hooks/useTypeahead.js +117 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/theme/generateThemeRules.js +1 -1
- package/dist/theme/syntax/SyntaxTheme.d.ts +1 -1
- package/dist/theme/syntax/SyntaxTheme.js +1 -1
- package/dist/theme/syntax/defineSyntaxTheme.d.ts.map +1 -1
- package/dist/theme/syntax/defineSyntaxTheme.js +2 -2
- package/dist/theme/syntax/presets.d.ts +1 -1
- package/dist/theme/syntax/presets.d.ts.map +1 -1
- package/dist/theme/syntax/presets.js +1 -1
- package/dist/theme/syntax/tokens.d.ts +1 -1
- package/dist/theme/syntax/tokens.js +1 -1
- package/dist/theme/types.d.ts +1 -1
- package/dist/utils/dateTypes.d.ts +12 -0
- package/dist/utils/dateTypes.d.ts.map +1 -1
- package/dist/utils/dateTypes.js +41 -1
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +3 -1
- package/dist/utils/inputAria.d.ts +29 -0
- package/dist/utils/inputAria.d.ts.map +1 -0
- package/dist/utils/inputAria.js +30 -0
- package/dist/utils/timeParser.d.ts.map +1 -1
- package/dist/utils/timeParser.js +5 -2
- package/package.json +15 -5
- package/src/Avatar/Avatar.test.tsx +37 -0
- package/src/Avatar/Avatar.tsx +10 -5
- package/src/AvatarGroup/AvatarGroupOverflow.tsx +3 -0
- package/src/Banner/Banner.doc.mjs +8 -0
- package/src/Banner/Banner.test.tsx +16 -7
- package/src/Banner/Banner.tsx +9 -2
- package/src/Breadcrumbs/BreadcrumbItem.tsx +25 -7
- package/src/Breadcrumbs/Breadcrumbs.test.tsx +31 -10
- package/src/Button/Button.doc.mjs +6 -0
- package/src/Button/Button.test.tsx +105 -11
- package/src/Button/Button.tsx +76 -21
- package/src/Calendar/Calendar.doc.mjs +4 -4
- package/src/Calendar/Calendar.test.tsx +168 -30
- package/src/Calendar/Calendar.tsx +121 -66
- package/src/Calendar/hooks/index.ts +0 -6
- package/src/Calendar/index.ts +1 -3
- package/src/Calendar/styles.ts +4 -9
- package/src/Carousel/Carousel.doc.mjs +7 -1
- package/src/Carousel/Carousel.test.tsx +20 -0
- package/src/Carousel/Carousel.tsx +16 -1
- package/src/Center/Center.doc.mjs +12 -2
- package/src/Center/Center.tsx +28 -3
- package/src/Chat/ChatComposer.doc.mjs +3 -0
- package/src/Chat/ChatComposerDrawer.doc.mjs +12 -0
- package/src/Chat/ChatMessageList.doc.mjs +8 -0
- package/src/Chat/ChatMessageList.test.tsx +18 -0
- package/src/Chat/ChatMessageList.tsx +16 -0
- package/src/Chat/useTriggerMenu.tsx +3 -0
- package/src/CheckboxInput/CheckboxInput.doc.mjs +18 -0
- package/src/CheckboxInput/CheckboxInput.test.tsx +172 -27
- package/src/CheckboxInput/CheckboxInput.tsx +78 -6
- package/src/CheckboxList/CheckboxList.doc.mjs +9 -0
- package/src/CheckboxList/CheckboxList.test.tsx +169 -16
- package/src/CheckboxList/CheckboxList.tsx +56 -3
- package/src/CheckboxList/CheckboxListContext.tsx +7 -0
- package/src/Citation/Citation.doc.mjs +10 -0
- package/src/Citation/Citation.test.tsx +117 -0
- package/src/Citation/Citation.tsx +9 -1
- package/src/ClickableCard/ClickableCard.doc.mjs +15 -0
- package/src/CodeBlock/CodeBlock.test.tsx +115 -0
- package/src/CodeBlock/CodeBlock.tsx +61 -33
- package/src/CommandPalette/CommandPalette.test.tsx +47 -1
- package/src/CommandPalette/CommandPalette.tsx +9 -21
- package/src/ContextMenu/ContextMenu.doc.mjs +4 -4
- package/src/ContextMenu/ContextMenu.test.tsx +155 -1
- package/src/ContextMenu/ContextMenu.tsx +113 -16
- package/src/DateInput/DateInput.doc.mjs +281 -56
- package/src/DateInput/DateInput.test.tsx +188 -2
- package/src/DateInput/DateInput.tsx +89 -10
- package/src/DateRangeInput/DateRangeInput.doc.mjs +251 -46
- package/src/DateRangeInput/DateRangeInput.test.tsx +182 -20
- package/src/DateRangeInput/DateRangeInput.tsx +63 -5
- package/src/DateTimeInput/DateTimeInput.doc.mjs +368 -67
- package/src/DateTimeInput/DateTimeInput.test.tsx +279 -11
- package/src/DateTimeInput/DateTimeInput.tsx +125 -17
- package/src/Dialog/Dialog.doc.mjs +2 -2
- package/src/Dialog/Dialog.tsx +12 -0
- package/src/DropdownMenu/DropdownMenu.doc.mjs +1 -8
- package/src/DropdownMenu/DropdownMenu.test.tsx +56 -42
- package/src/DropdownMenu/DropdownMenu.tsx +52 -18
- package/src/EmptyState/EmptyState.test.tsx +4 -2
- package/src/EmptyState/EmptyState.tsx +6 -2
- package/src/Field/Field.test.tsx +32 -0
- package/src/Field/Field.tsx +23 -5
- package/src/Field/FieldLabel.tsx +55 -17
- package/src/FileInput/FileInput.doc.mjs +17 -0
- package/src/FileInput/FileInput.test.tsx +283 -49
- package/src/FileInput/FileInput.tsx +76 -4
- package/src/Grid/Grid.doc.mjs +14 -4
- package/src/Grid/Grid.tsx +20 -0
- package/src/HoverCard/HoverCard.doc.mjs +3 -0
- package/src/HoverCard/HoverCard.test.tsx +189 -2
- package/src/HoverCard/HoverCard.tsx +20 -16
- package/src/HoverCard/useHoverCard.tsx +13 -10
- package/src/Icon/Icon.doc.mjs +8 -0
- package/src/InputGroup/InputGroup.doc.mjs +2 -2
- package/src/InputGroup/InputGroup.test.tsx +98 -60
- package/src/InputGroup/InputGroup.tsx +21 -4
- package/src/InputGroup/InputGroupContext.ts +9 -4
- package/src/InputGroup/index.ts +1 -0
- package/src/Kbd/Kbd.test.tsx +22 -4
- package/src/Kbd/Kbd.tsx +37 -12
- package/src/Layer/anchorName.test.ts +146 -0
- package/src/Layer/anchorName.ts +46 -0
- package/src/Layer/layerAnimations.stylex.ts +20 -4
- package/src/Layer/useLayer.doc.mjs +12 -2
- package/src/Layer/useLayer.tsx +100 -15
- package/src/Layout/Layout.doc.mjs +1 -1
- package/src/Layout/Layout.tsx +8 -16
- package/src/Layout/LayoutFooter.doc.mjs +4 -4
- package/src/Layout/LayoutFooter.tsx +3 -3
- package/src/Layout/LayoutHeader.doc.mjs +4 -4
- package/src/Layout/LayoutHeader.tsx +3 -3
- package/src/Layout/LayoutPanel.tsx +3 -3
- package/src/Layout/padding.stylex.ts +52 -0
- package/src/Lightbox/Lightbox.doc.mjs +9 -2
- package/src/Lightbox/Lightbox.test.tsx +53 -5
- package/src/Lightbox/Lightbox.tsx +9 -4
- package/src/Link/Link.doc.mjs +14 -0
- package/src/Link/Link.test.tsx +52 -2
- package/src/Link/Link.tsx +42 -7
- package/src/Link/LinkProvider.tsx +1 -0
- package/src/List/List.doc.mjs +7 -0
- package/src/Markdown/Markdown.doc.mjs +2 -0
- package/src/Markdown/Markdown.test.tsx +28 -26
- package/src/Markdown/Markdown.tsx +21 -6
- package/src/MetadataList/MetadataListItem.doc.mjs +4 -0
- package/src/MobileNav/MobileNav.doc.mjs +8 -8
- package/src/MobileNav/MobileNav.tsx +13 -0
- package/src/MobileNav/MobileNavReopen.test.tsx +118 -0
- package/src/MoreMenu/MoreMenu.doc.mjs +2 -17
- package/src/MoreMenu/MoreMenu.tsx +0 -9
- package/src/MultiSelector/MultiSelector.doc.mjs +25 -0
- package/src/MultiSelector/MultiSelector.test.tsx +375 -8
- package/src/MultiSelector/MultiSelector.tsx +145 -21
- package/src/MultiSelector/hooks.ts +27 -0
- package/src/NavMenu/NavHeadingMenu.test.tsx +77 -1
- package/src/NavMenu/NavHeadingMenu.tsx +50 -3
- package/src/NumberInput/NumberInput.doc.mjs +17 -0
- package/src/NumberInput/NumberInput.test.tsx +242 -40
- package/src/NumberInput/NumberInput.tsx +89 -11
- package/src/OverflowList/OverflowList.doc.mjs +17 -0
- package/src/Pagination/Pagination.doc.mjs +3 -3
- package/src/Pagination/Pagination.test.tsx +250 -14
- package/src/Pagination/Pagination.tsx +54 -29
- package/src/Popover/usePopover.doc.mjs +7 -3
- package/src/Popover/usePopover.tsx +49 -6
- package/src/PowerSearch/PowerSearch.doc.mjs +15 -0
- package/src/PowerSearch/PowerSearch.test.tsx +97 -1
- package/src/PowerSearch/PowerSearch.tsx +16 -3
- package/src/ProgressBar/ProgressBar.test.tsx +45 -27
- package/src/ProgressBar/ProgressBar.tsx +3 -4
- package/src/RadioList/RadioList.doc.mjs +9 -0
- package/src/RadioList/RadioList.test.tsx +252 -16
- package/src/RadioList/RadioList.tsx +166 -10
- package/src/RadioList/RadioListItem.tsx +14 -2
- package/src/Resizable/Resizable.doc.mjs +1 -1
- package/src/Section/Section.doc.mjs +11 -0
- package/src/SegmentedControl/SegmentedControl.doc.mjs +9 -0
- package/src/SegmentedControl/SegmentedControl.test.tsx +214 -42
- package/src/SegmentedControl/SegmentedControl.tsx +102 -54
- package/src/SegmentedControl/SegmentedControlContext.ts +7 -0
- package/src/SegmentedControl/SegmentedControlItem.tsx +14 -1
- package/src/SelectableCard/SelectableCard.doc.mjs +15 -0
- package/src/Selector/Selector.doc.mjs +25 -0
- package/src/Selector/Selector.test.tsx +322 -15
- package/src/Selector/Selector.tsx +126 -40
- package/src/Selector/hooks.ts +23 -0
- package/src/SideNav/SideNav.test.tsx +16 -0
- package/src/SideNav/SideNavItem.tsx +2 -4
- package/src/Skeleton/Skeleton.doc.mjs +11 -1
- package/src/Skeleton/Skeleton.test.tsx +25 -0
- package/src/Skeleton/Skeleton.tsx +11 -1
- package/src/Slider/Slider.doc.mjs +19 -0
- package/src/Slider/Slider.test.tsx +158 -18
- package/src/Slider/Slider.tsx +54 -6
- package/src/Spinner/Spinner.tsx +7 -1
- package/src/Stack/Stack.doc.mjs +77 -0
- package/src/Stack/Stack.test.tsx +55 -5
- package/src/Stack/Stack.tsx +73 -24
- package/src/Stack/StackItem.test.tsx +23 -0
- package/src/Stack/StackItem.tsx +20 -23
- package/src/Switch/Switch.doc.mjs +15 -0
- package/src/Switch/Switch.test.tsx +162 -27
- package/src/Switch/Switch.tsx +61 -21
- package/src/TabList/Tab.tsx +6 -0
- package/src/TabList/TabList.doc.mjs +12 -0
- package/src/TabList/TabList.test.tsx +208 -0
- package/src/TabList/TabList.tsx +102 -12
- package/src/TabList/TabListContext.ts +7 -3
- package/src/TabList/TabMenu.tsx +6 -3
- package/src/Table/BaseTable.tsx +72 -41
- package/src/Table/Table.doc.mjs +14 -0
- package/src/Table/Table.test.tsx +39 -30
- package/src/Table/Table.tsx +27 -1
- package/src/Table/TableCell.tsx +25 -23
- package/src/Table/TableHeaderCell.tsx +28 -29
- package/src/Table/TableRow.tsx +37 -7
- package/src/Table/index.ts +6 -2
- package/src/Table/plugins/pagination/paginateData.ts +10 -3
- package/src/Table/plugins/pagination/useTablePagination.test.tsx +16 -0
- package/src/Table/plugins/pagination/useTablePagination.tsx +8 -1
- package/src/Table/plugins/sortable/useTableSortable.test.tsx +91 -2
- package/src/Table/plugins/sortable/useTableSortable.tsx +53 -1
- package/src/Table/plugins/stickyColumns/index.ts +4 -0
- package/src/Table/plugins/stickyColumns/useTableStickyColumns.test.tsx +163 -0
- package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +407 -0
- package/src/Table/tableContextMenu.test.tsx +157 -0
- package/src/Table/tableContextMenu.tsx +142 -0
- package/src/Table/types.ts +175 -4
- package/src/Table/useBaseTablePlugins.ts +1 -0
- package/src/Table/useTableColumnResize.doc.mjs +96 -0
- package/src/Table/useTableStickyColumns.doc.mjs +59 -0
- package/src/Text/Heading.doc.mjs +15 -2
- package/src/Text/Text.doc.mjs +7 -1
- package/src/Text/text.stylex.ts +2 -2
- package/src/TextArea/TextArea.doc.mjs +17 -0
- package/src/TextArea/TextArea.test.tsx +167 -35
- package/src/TextArea/TextArea.tsx +62 -15
- package/src/TextInput/TextInput.doc.mjs +17 -0
- package/src/TextInput/TextInput.test.tsx +168 -34
- package/src/TextInput/TextInput.tsx +77 -9
- package/src/TimeInput/TimeInput.doc.mjs +335 -60
- package/src/TimeInput/TimeInput.test.tsx +144 -7
- package/src/TimeInput/TimeInput.tsx +74 -5
- package/src/Timestamp/Timestamp.doc.mjs +9 -0
- package/src/Timestamp/Timestamp.test.tsx +44 -18
- package/src/Timestamp/Timestamp.tsx +30 -10
- package/src/Toast/Toast.tsx +14 -0
- package/src/Toast/ToastViewport.test.tsx +204 -0
- package/src/Toast/ToastViewport.tsx +167 -21
- package/src/ToggleButton/ToggleButton.doc.mjs +9 -3
- package/src/ToggleButton/ToggleButton.test.tsx +39 -18
- package/src/ToggleButton/ToggleButton.tsx +46 -83
- package/src/Tokenizer/Tokenizer.doc.mjs +15 -0
- package/src/Tokenizer/Tokenizer.test.tsx +105 -1
- package/src/Tokenizer/Tokenizer.tsx +41 -2
- package/src/Toolbar/Toolbar.doc.mjs +65 -5
- package/src/Toolbar/Toolbar.test.tsx +109 -6
- package/src/Toolbar/Toolbar.tsx +59 -5
- package/src/Tooltip/Tooltip.test.tsx +81 -0
- package/src/Tooltip/useTooltip.tsx +57 -11
- package/src/TreeList/TreeList.test.tsx +295 -6
- package/src/TreeList/TreeList.tsx +73 -1
- package/src/TreeList/TreeListItem.tsx +51 -5
- package/src/TreeList/treeListItem.markers.stylex.ts +20 -0
- package/src/Typeahead/BaseTypeahead.tsx +86 -9
- package/src/Typeahead/Typeahead.doc.mjs +136 -30
- package/src/Typeahead/Typeahead.test.tsx +331 -1
- package/src/Typeahead/Typeahead.tsx +52 -1
- package/src/VisuallyHidden/VisuallyHidden.doc.mjs +80 -0
- package/src/VisuallyHidden/VisuallyHidden.test.tsx +76 -0
- package/src/VisuallyHidden/VisuallyHidden.tsx +113 -0
- package/src/VisuallyHidden/index.ts +15 -0
- package/src/hooks/focusableSelector.ts +25 -0
- package/src/hooks/index.ts +28 -2
- package/src/hooks/useAnnounce.test.tsx +101 -0
- package/src/hooks/useAnnounce.ts +168 -0
- package/src/hooks/useClickableContainer.ts +16 -4
- package/src/hooks/useEntryAnimation.ts +16 -4
- package/src/hooks/useFocusTrap.test.tsx +132 -0
- package/src/hooks/useFocusTrap.ts +98 -4
- package/src/hooks/useGridFocus.doc.mjs +40 -2
- package/src/hooks/useGridFocus.test.tsx +132 -0
- package/src/hooks/useGridFocus.ts +343 -67
- package/src/hooks/useImageMode.test.ts +133 -0
- package/src/hooks/useKeyboardHint.doc.mjs +101 -0
- package/src/hooks/useKeyboardHint.test.tsx +70 -0
- package/src/hooks/useKeyboardHint.tsx +332 -0
- package/src/hooks/useListFocus.doc.mjs +50 -10
- package/src/hooks/useListFocus.test.tsx +375 -0
- package/src/hooks/useListFocus.ts +395 -57
- package/src/hooks/useLongPress.test.tsx +134 -0
- package/src/hooks/useLongPress.ts +119 -0
- package/src/hooks/useTreeFocus.doc.mjs +140 -0
- package/src/hooks/useTreeFocus.test.tsx +214 -0
- package/src/hooks/useTreeFocus.ts +559 -0
- package/src/hooks/useTypeahead.test.tsx +109 -0
- package/src/hooks/useTypeahead.ts +183 -0
- package/src/index.ts +1 -0
- package/src/theme/derivedVarRegistry.test.ts +4 -0
- package/src/theme/generateThemeRules.test.ts +7 -8
- package/src/theme/generateThemeRules.ts +1 -1
- package/src/theme/syntax/SyntaxTheme.tsx +1 -1
- package/src/theme/syntax/defineSyntaxTheme.ts +20 -11
- package/src/theme/syntax/presets.ts +5 -2
- package/src/theme/syntax/tokens.ts +1 -1
- package/src/theme/types.ts +1 -1
- package/src/utils/dateTypes.test.ts +40 -0
- package/src/utils/dateTypes.ts +40 -0
- package/src/utils/index.ts +9 -0
- package/src/utils/inputAria.test.ts +39 -0
- package/src/utils/inputAria.ts +58 -0
- package/src/utils/timeParser.test.ts +10 -0
- package/src/utils/timeParser.ts +5 -2
- package/dist/Calendar/hooks/useCalendarRovingTabindex.d.ts +0 -57
- package/dist/Calendar/hooks/useCalendarRovingTabindex.d.ts.map +0 -1
- package/dist/Calendar/hooks/useCalendarRovingTabindex.js +0 -96
- package/src/Calendar/hooks/useCalendarRovingTabindex.ts +0 -118
|
@@ -63,6 +63,7 @@ import type {BaseProps} from '../BaseProps';
|
|
|
63
63
|
import type {SizeValue} from '../utils/types';
|
|
64
64
|
import {useSize} from '../SizeContext/SizeContext';
|
|
65
65
|
import {useInputContainer} from '../hooks/useInputContainer';
|
|
66
|
+
import {useTooltip} from '../Tooltip';
|
|
66
67
|
import {themeProps} from '../utils/themeProps';
|
|
67
68
|
|
|
68
69
|
const styles = stylex.create({
|
|
@@ -183,6 +184,29 @@ export interface TimeInputProps extends Omit<
|
|
|
183
184
|
*/
|
|
184
185
|
isDisabled?: boolean;
|
|
185
186
|
|
|
187
|
+
/**
|
|
188
|
+
* Explains why the input is disabled. When set together with
|
|
189
|
+
* `isDisabled`, the input shows a tooltip with this text on hover and
|
|
190
|
+
* keyboard focus, and the field stays focusable (via `aria-disabled`)
|
|
191
|
+
* so the reason is discoverable by keyboard and assistive technology.
|
|
192
|
+
* Typing and arrow-key adjustment stay blocked.
|
|
193
|
+
*
|
|
194
|
+
* Use this instead of wrapping a disabled input in `Tooltip` — disabled
|
|
195
|
+
* controls don't emit the pointer events an external tooltip needs.
|
|
196
|
+
*
|
|
197
|
+
* @example
|
|
198
|
+
* ```
|
|
199
|
+
* <TimeInput
|
|
200
|
+
* label="Start time"
|
|
201
|
+
* value={time}
|
|
202
|
+
* onChange={setTime}
|
|
203
|
+
* isDisabled
|
|
204
|
+
* disabledMessage="You need the Editor role to change this"
|
|
205
|
+
* />
|
|
206
|
+
* ```
|
|
207
|
+
*/
|
|
208
|
+
disabledMessage?: string;
|
|
209
|
+
|
|
186
210
|
/**
|
|
187
211
|
* The selected time in ISO format (HH:MM or HH:MM:SS).
|
|
188
212
|
*/
|
|
@@ -301,6 +325,7 @@ export function TimeInput({
|
|
|
301
325
|
isOptional = false,
|
|
302
326
|
isRequired = false,
|
|
303
327
|
isDisabled = false,
|
|
328
|
+
disabledMessage,
|
|
304
329
|
value,
|
|
305
330
|
onChange,
|
|
306
331
|
changeAction,
|
|
@@ -334,6 +359,19 @@ export function TimeInput({
|
|
|
334
359
|
const [optimisticValue, setOptimisticValue] = useOptimistic(value);
|
|
335
360
|
const isBusy = isLoading || optimisticValue !== value;
|
|
336
361
|
|
|
362
|
+
// Disabled-reason tooltip. Disabled controls swallow pointer events, so the
|
|
363
|
+
// tooltip listeners attach to the input container (which already exists) and
|
|
364
|
+
// the input stays perceivable via aria-disabled instead of the disabled
|
|
365
|
+
// attribute. Typing is blocked with readOnly and value mutation guards.
|
|
366
|
+
const showsDisabledMessage = isDisabled && !!disabledMessage;
|
|
367
|
+
const disabledMessageTooltip = useTooltip({
|
|
368
|
+
placement: 'above',
|
|
369
|
+
// The container div is not naturally focusable; focusin bubbles up from
|
|
370
|
+
// the input, so always attach focus listeners.
|
|
371
|
+
focusTrigger: 'always',
|
|
372
|
+
isEnabled: showsDisabledMessage,
|
|
373
|
+
});
|
|
374
|
+
|
|
337
375
|
// Status icon mapping
|
|
338
376
|
const statusIconMap: Record<InputStatusType, IconName> = {
|
|
339
377
|
warning: 'warning',
|
|
@@ -354,6 +392,7 @@ export function TimeInput({
|
|
|
354
392
|
[
|
|
355
393
|
description ? descriptionID : null,
|
|
356
394
|
status?.message ? statusMessageID : null,
|
|
395
|
+
showsDisabledMessage ? disabledMessageTooltip.describedBy : null,
|
|
357
396
|
]
|
|
358
397
|
.filter(Boolean)
|
|
359
398
|
.join(' ') || undefined;
|
|
@@ -415,6 +454,11 @@ export function TimeInput({
|
|
|
415
454
|
// Handle input text change - update immediately if valid
|
|
416
455
|
const handleInputChange = useCallback(
|
|
417
456
|
(e: React.ChangeEvent<HTMLInputElement>) => {
|
|
457
|
+
// With a disabledMessage the input drops `disabled` for focusability, so
|
|
458
|
+
// guard value mutation explicitly (readOnly also blocks typing).
|
|
459
|
+
if (isDisabled) {
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
418
462
|
const newValue = e.target.value;
|
|
419
463
|
setPendingInput(newValue);
|
|
420
464
|
|
|
@@ -424,13 +468,19 @@ export function TimeInput({
|
|
|
424
468
|
fireChange(parsed);
|
|
425
469
|
}
|
|
426
470
|
},
|
|
427
|
-
[hasSeconds, min, max, value, fireChange],
|
|
471
|
+
[hasSeconds, min, max, value, fireChange, isDisabled],
|
|
428
472
|
);
|
|
429
473
|
|
|
430
474
|
// Handle focus
|
|
431
475
|
const handleFocus = useCallback(() => {
|
|
476
|
+
// A disabled input stays focusable (via aria-disabled) so its reason is
|
|
477
|
+
// discoverable, but it must not present editing affordances — keep the
|
|
478
|
+
// static placeholder rather than swapping in the format hint.
|
|
479
|
+
if (isDisabled) {
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
432
482
|
setIsFocused(true);
|
|
433
|
-
}, []);
|
|
483
|
+
}, [isDisabled]);
|
|
434
484
|
|
|
435
485
|
// Handle blur - validate and clear pending input
|
|
436
486
|
const handleBlur = useCallback(
|
|
@@ -466,6 +516,11 @@ export function TimeInput({
|
|
|
466
516
|
// Handle keyboard navigation on input
|
|
467
517
|
const handleInputKeyDown = useCallback(
|
|
468
518
|
(e: KeyboardEvent<HTMLInputElement>) => {
|
|
519
|
+
// Arrow-key adjustment mutates the value; block it while showing a
|
|
520
|
+
// disabled reason (the input keeps focusability via aria-disabled).
|
|
521
|
+
if (isDisabled) {
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
469
524
|
if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
|
|
470
525
|
e.preventDefault();
|
|
471
526
|
|
|
@@ -492,7 +547,7 @@ export function TimeInput({
|
|
|
492
547
|
}
|
|
493
548
|
}
|
|
494
549
|
},
|
|
495
|
-
[value, hasSeconds, increment, min, max, fireChange],
|
|
550
|
+
[value, hasSeconds, increment, min, max, fireChange, isDisabled],
|
|
496
551
|
);
|
|
497
552
|
|
|
498
553
|
// Handle clear button click
|
|
@@ -531,7 +586,13 @@ export function TimeInput({
|
|
|
531
586
|
labelTooltip={labelTooltip}
|
|
532
587
|
width={width}>
|
|
533
588
|
<div
|
|
534
|
-
ref={
|
|
589
|
+
ref={el => {
|
|
590
|
+
containerRef.current = el;
|
|
591
|
+
// Anchor + hover/focus listeners for the disabled-message tooltip.
|
|
592
|
+
// Handlers are gated internally by isEnabled, so attaching
|
|
593
|
+
// unconditionally is safe.
|
|
594
|
+
disabledMessageTooltip.ref(el);
|
|
595
|
+
}}
|
|
535
596
|
onClick={handleWrapperClick}
|
|
536
597
|
onMouseUp={handleWrapperMouseUp}
|
|
537
598
|
{...mergeProps(
|
|
@@ -561,7 +622,12 @@ export function TimeInput({
|
|
|
561
622
|
onBlur={handleBlur}
|
|
562
623
|
onKeyDown={handleInputKeyDown}
|
|
563
624
|
placeholder={displayPlaceholder}
|
|
564
|
-
|
|
625
|
+
// With a disabledMessage the input keeps focusability via
|
|
626
|
+
// aria-disabled so the reason is focus-discoverable; typing and
|
|
627
|
+
// arrow-key adjustment are blocked with readOnly and the guards.
|
|
628
|
+
disabled={isDisabled && !showsDisabledMessage}
|
|
629
|
+
aria-disabled={showsDisabledMessage ? 'true' : undefined}
|
|
630
|
+
readOnly={showsDisabledMessage || undefined}
|
|
565
631
|
autoFocus={hasAutoFocus}
|
|
566
632
|
data-autofocus={hasAutoFocus || undefined}
|
|
567
633
|
aria-describedby={ariaDescribedBy}
|
|
@@ -592,6 +658,9 @@ export function TimeInput({
|
|
|
592
658
|
/>
|
|
593
659
|
)}
|
|
594
660
|
</div>
|
|
661
|
+
|
|
662
|
+
{showsDisabledMessage &&
|
|
663
|
+
disabledMessageTooltip.renderTooltip(disabledMessage)}
|
|
595
664
|
</Field>
|
|
596
665
|
);
|
|
597
666
|
}
|
|
@@ -7,6 +7,15 @@ export const docs = {
|
|
|
7
7
|
displayName: 'Timestamp',
|
|
8
8
|
category: 'Content',
|
|
9
9
|
keywords: ['date', 'time', 'datetime', 'relative', 'ago', 'clock', 'format', 'duration'],
|
|
10
|
+
playground: {
|
|
11
|
+
// `value` is required but has no semantic default, so the properties-tab
|
|
12
|
+
// preview fell back to the literal string "value" — which
|
|
13
|
+
// `new Date("value")` rejects, crashing the preview with "Invalid time
|
|
14
|
+
// value". Seed a valid ISO 8601 date so the interactive preview renders.
|
|
15
|
+
defaults: {
|
|
16
|
+
value: '2026-02-19T17:00:00Z',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
10
19
|
props: [
|
|
11
20
|
{
|
|
12
21
|
name: 'value',
|
|
@@ -33,10 +33,30 @@ describe('Timestamp', () => {
|
|
|
33
33
|
expect(screen.getByText('2 hours ago')).toBeInTheDocument();
|
|
34
34
|
});
|
|
35
35
|
|
|
36
|
-
it('renders "
|
|
36
|
+
it('renders "now" for very recent times', () => {
|
|
37
37
|
const fiveSecondsAgo = Date.now() / 1000 - 5;
|
|
38
38
|
render(<Timestamp value={fiveSecondsAgo} format="relative" />);
|
|
39
|
-
expect(screen.getByText('
|
|
39
|
+
expect(screen.getByText('now')).toBeInTheDocument();
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('renders "now" for the current instant (not a future phrase)', () => {
|
|
43
|
+
// A value equal to "right now". Because the internal `now` baseline is
|
|
44
|
+
// captured at render time, it can lag the value by a fraction of a second,
|
|
45
|
+
// producing a tiny negative delta that must not be treated as the future.
|
|
46
|
+
render(<Timestamp value={Date.now() / 1000} format="relative" />);
|
|
47
|
+
expect(screen.queryByText(/^in /)).not.toBeInTheDocument();
|
|
48
|
+
expect(screen.getByText('now')).toBeInTheDocument();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('renders "now" for a value a hair in the future (clock skew)', () => {
|
|
52
|
+
// Real-world clock / captured-now skew can make a current-ish value land a
|
|
53
|
+
// fraction of a second in the future relative to the component's internal
|
|
54
|
+
// `now`. This must read as the present ("now"), never "in a few
|
|
55
|
+
// seconds". Regression test for the right-now -> future-phrase bug.
|
|
56
|
+
const aHairInTheFuture = Date.now() / 1000 + 0.6;
|
|
57
|
+
render(<Timestamp value={aHairInTheFuture} format="relative" />);
|
|
58
|
+
expect(screen.queryByText(/^in /)).not.toBeInTheDocument();
|
|
59
|
+
expect(screen.getByText('now')).toBeInTheDocument();
|
|
40
60
|
});
|
|
41
61
|
|
|
42
62
|
it('renders "yesterday" for times ~1 day ago', () => {
|
|
@@ -49,11 +69,7 @@ describe('Timestamp', () => {
|
|
|
49
69
|
|
|
50
70
|
it('renders date format', () => {
|
|
51
71
|
render(
|
|
52
|
-
<Timestamp
|
|
53
|
-
value="2026-02-19T17:00:00Z"
|
|
54
|
-
format="date"
|
|
55
|
-
data-testid="ts"
|
|
56
|
-
/>,
|
|
72
|
+
<Timestamp value="2026-02-19T17:00:00Z" format="date" data-testid="ts" />,
|
|
57
73
|
);
|
|
58
74
|
const el = screen.getByTestId('ts');
|
|
59
75
|
expect(el.textContent).toContain('2026');
|
|
@@ -77,11 +93,7 @@ describe('Timestamp', () => {
|
|
|
77
93
|
|
|
78
94
|
it('renders time format', () => {
|
|
79
95
|
render(
|
|
80
|
-
<Timestamp
|
|
81
|
-
value="2026-02-19T17:00:00Z"
|
|
82
|
-
format="time"
|
|
83
|
-
data-testid="ts"
|
|
84
|
-
/>,
|
|
96
|
+
<Timestamp value="2026-02-19T17:00:00Z" format="time" data-testid="ts" />,
|
|
85
97
|
);
|
|
86
98
|
const el = screen.getByTestId('ts');
|
|
87
99
|
// Should contain time but not year
|
|
@@ -197,7 +209,7 @@ describe('Timestamp', () => {
|
|
|
197
209
|
it('live updates relative time', () => {
|
|
198
210
|
const now = Date.now() / 1000;
|
|
199
211
|
render(<Timestamp value={now - 5} format="relative" isLive />);
|
|
200
|
-
expect(screen.getByText('
|
|
212
|
+
expect(screen.getByText('now')).toBeInTheDocument();
|
|
201
213
|
|
|
202
214
|
act(() => {
|
|
203
215
|
vi.advanceTimersByTime(30_000);
|
|
@@ -210,11 +222,7 @@ describe('Timestamp', () => {
|
|
|
210
222
|
it('forwards ref', () => {
|
|
211
223
|
const ref = {current: null as HTMLTimeElement | null};
|
|
212
224
|
render(
|
|
213
|
-
<Timestamp
|
|
214
|
-
ref={ref}
|
|
215
|
-
value="2026-03-25T10:00:00Z"
|
|
216
|
-
format="date_time"
|
|
217
|
-
/>,
|
|
225
|
+
<Timestamp ref={ref} value="2026-03-25T10:00:00Z" format="date_time" />,
|
|
218
226
|
);
|
|
219
227
|
expect(ref.current).toBeInstanceOf(HTMLTimeElement);
|
|
220
228
|
});
|
|
@@ -240,6 +248,24 @@ describe('Timestamp', () => {
|
|
|
240
248
|
expect(screen.getByText('in 1 hour')).toBeInTheDocument();
|
|
241
249
|
});
|
|
242
250
|
|
|
251
|
+
it('renders "now" for a value a few seconds in the future (clock skew)', () => {
|
|
252
|
+
// Beyond the sub-second render lag but still within the skew tolerance: a
|
|
253
|
+
// value ~20s ahead of our clock is almost always skew (the value's clock
|
|
254
|
+
// running fast), not a genuine future event, so it should read as the
|
|
255
|
+
// present rather than "in a few seconds".
|
|
256
|
+
const twentySecondsFromNow = Date.now() / 1000 + 20;
|
|
257
|
+
render(<Timestamp value={twentySecondsFromNow} format="relative" />);
|
|
258
|
+
expect(screen.queryByText(/^in /)).not.toBeInTheDocument();
|
|
259
|
+
expect(screen.getByText('now')).toBeInTheDocument();
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
it('renders a genuine near-future time beyond the skew tolerance', () => {
|
|
263
|
+
// Past the skew window — this is a real upcoming time, not clock drift.
|
|
264
|
+
const fortyFiveSecondsFromNow = Date.now() / 1000 + 45;
|
|
265
|
+
render(<Timestamp value={fortyFiveSecondsFromNow} format="relative" />);
|
|
266
|
+
expect(screen.getByText('in a few seconds')).toBeInTheDocument();
|
|
267
|
+
});
|
|
268
|
+
|
|
243
269
|
// --- Long-ago relative ---
|
|
244
270
|
|
|
245
271
|
it('renders months ago for dates older than 30 days', () => {
|
|
@@ -19,12 +19,7 @@
|
|
|
19
19
|
import {useEffect, useRef, useState, lazy, Suspense} from 'react';
|
|
20
20
|
import * as stylex from '@stylexjs/stylex';
|
|
21
21
|
import {Text} from '../Text';
|
|
22
|
-
import type {
|
|
23
|
-
TextType,
|
|
24
|
-
TextSize,
|
|
25
|
-
TextColor,
|
|
26
|
-
TextWeight,
|
|
27
|
-
} from '../theme/types';
|
|
22
|
+
import type {TextType, TextSize, TextColor, TextWeight} from '../theme/types';
|
|
28
23
|
import {mergeProps, mergeRefs} from '../utils';
|
|
29
24
|
import type {BaseProps} from '../BaseProps';
|
|
30
25
|
import {themeProps} from '../utils/themeProps';
|
|
@@ -54,7 +49,7 @@ export interface TimestampProps extends BaseProps<HTMLTimeElement> {
|
|
|
54
49
|
value: string | number;
|
|
55
50
|
/**
|
|
56
51
|
* Display format.
|
|
57
|
-
* - `'relative'`: "2 hours ago", "yesterday", "
|
|
52
|
+
* - `'relative'`: "2 hours ago", "yesterday", "now"
|
|
58
53
|
* - `'auto'`: Relative for recent times, `date_time` for older
|
|
59
54
|
* - `'date'`: "Mar 21, 2025"
|
|
60
55
|
* - `'date_time'`: "Mar 21, 2025, 2:51 PM"
|
|
@@ -138,6 +133,18 @@ const YEAR = 365 * DAY;
|
|
|
138
133
|
/** Default auto threshold: 7 days in seconds */
|
|
139
134
|
const DEFAULT_AUTO_THRESHOLD = 7 * DAY;
|
|
140
135
|
|
|
136
|
+
/**
|
|
137
|
+
* Tolerance (in seconds) for treating a *future* timestamp as the present.
|
|
138
|
+
* A value only a handful of seconds ahead of our reference clock is almost
|
|
139
|
+
* always clock skew — the displayed `now` lagging the real clock, or the value
|
|
140
|
+
* being produced on a slightly faster clock — not a genuine future event, so
|
|
141
|
+
* it reads as "now" rather than a confusing "in a few seconds". The future
|
|
142
|
+
* side gets a wider window than the past (which only needs to absorb the
|
|
143
|
+
* sub-second render-time lag) because future drift is far more likely to be
|
|
144
|
+
* skew than real.
|
|
145
|
+
*/
|
|
146
|
+
const FUTURE_SKEW_TOLERANCE = 30;
|
|
147
|
+
|
|
141
148
|
function parseValue(value: string | number): Date {
|
|
142
149
|
if (typeof value === 'number') {
|
|
143
150
|
// Heuristic: if the number is less than 1e12, treat as seconds; otherwise ms.
|
|
@@ -150,9 +157,25 @@ function parseValue(value: string | number): Date {
|
|
|
150
157
|
function getRelativeTimeString(date: Date, now: Date): string {
|
|
151
158
|
const diffSeconds = Math.round((now.getTime() - date.getTime()) / 1000);
|
|
152
159
|
|
|
160
|
+
// Treat values at (or a hair before/after) the present as "now". The
|
|
161
|
+
// internal `now` reference is captured at render time, so it can lag the
|
|
162
|
+
// real clock; a value equal to "right now" can land a fraction of a second
|
|
163
|
+
// in the future and round to a small negative delta. Without this clamp,
|
|
164
|
+
// such values fall into the future branch and render "in a few seconds".
|
|
165
|
+
if (Math.abs(diffSeconds) < 10) {
|
|
166
|
+
return 'now';
|
|
167
|
+
}
|
|
168
|
+
|
|
153
169
|
if (diffSeconds < 0) {
|
|
154
170
|
// Future dates
|
|
155
171
|
const absDiff = Math.abs(diffSeconds);
|
|
172
|
+
// A value only a few seconds ahead of our clock is almost always skew, not
|
|
173
|
+
// a genuine future event — render it as the present rather than a
|
|
174
|
+
// confusing "in a few seconds". Wider than the past window above on
|
|
175
|
+
// purpose (see FUTURE_SKEW_TOLERANCE).
|
|
176
|
+
if (absDiff <= FUTURE_SKEW_TOLERANCE) {
|
|
177
|
+
return 'now';
|
|
178
|
+
}
|
|
156
179
|
if (absDiff < MINUTE) {
|
|
157
180
|
return 'in a few seconds';
|
|
158
181
|
}
|
|
@@ -176,9 +199,6 @@ function getRelativeTimeString(date: Date, now: Date): string {
|
|
|
176
199
|
return `in ${years} ${years === 1 ? 'year' : 'years'}`;
|
|
177
200
|
}
|
|
178
201
|
|
|
179
|
-
if (diffSeconds < 10) {
|
|
180
|
-
return 'just now';
|
|
181
|
-
}
|
|
182
202
|
if (diffSeconds < MINUTE) {
|
|
183
203
|
return `${diffSeconds} seconds ago`;
|
|
184
204
|
}
|
package/src/Toast/Toast.tsx
CHANGED
|
@@ -167,6 +167,20 @@ export function Toast({
|
|
|
167
167
|
};
|
|
168
168
|
}, [autoHideDuration, startTimer]);
|
|
169
169
|
|
|
170
|
+
// Pause the auto-hide timer while the window is not focused, so a toast
|
|
171
|
+
// doesn't silently expire while the user is in another window or tab.
|
|
172
|
+
useEffect(() => {
|
|
173
|
+
if (!isAutoHide) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
window.addEventListener('blur', pauseTimer);
|
|
177
|
+
window.addEventListener('focus', resumeTimer);
|
|
178
|
+
return () => {
|
|
179
|
+
window.removeEventListener('blur', pauseTimer);
|
|
180
|
+
window.removeEventListener('focus', resumeTimer);
|
|
181
|
+
};
|
|
182
|
+
}, [isAutoHide, pauseTimer, resumeTimer]);
|
|
183
|
+
|
|
170
184
|
const handleDismiss = useCallback(() => {
|
|
171
185
|
onDismiss('manual');
|
|
172
186
|
}, [onDismiss]);
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file ToastViewport.test.tsx
|
|
5
|
+
* @input Uses vitest, @testing-library/react, ToastViewport + useToast
|
|
6
|
+
* @output Unit tests for toast keyboard reach and focus management
|
|
7
|
+
* @position Testing; validates ToastViewport.tsx + Toast.tsx focus behavior
|
|
8
|
+
*
|
|
9
|
+
* SYNC: When ToastViewport.tsx or Toast.tsx focus handling changes, update these tests
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import {describe, it, expect, vi, beforeAll} from 'vitest';
|
|
13
|
+
import {render, screen, fireEvent, act} from '@testing-library/react';
|
|
14
|
+
import React from 'react';
|
|
15
|
+
import {ToastViewport} from './ToastViewport';
|
|
16
|
+
import {useToast} from './useToast';
|
|
17
|
+
import type {ToastOptions} from './types';
|
|
18
|
+
|
|
19
|
+
// Popover API is not implemented in jsdom.
|
|
20
|
+
beforeAll(() => {
|
|
21
|
+
if (typeof HTMLElement.prototype.showPopover === 'undefined') {
|
|
22
|
+
HTMLElement.prototype.showPopover = vi.fn();
|
|
23
|
+
HTMLElement.prototype.hidePopover = vi.fn();
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// Module-level constant default props (avoids unstable-default-props lint).
|
|
28
|
+
const EMPTY_OPTIONS: ToastOptions = {body: 'placeholder'};
|
|
29
|
+
|
|
30
|
+
function ShowToastButton({
|
|
31
|
+
options = EMPTY_OPTIONS,
|
|
32
|
+
triggerLabel = 'Trigger',
|
|
33
|
+
}: {
|
|
34
|
+
options?: ToastOptions;
|
|
35
|
+
triggerLabel?: string;
|
|
36
|
+
}) {
|
|
37
|
+
const toast = useToast();
|
|
38
|
+
return (
|
|
39
|
+
<button type="button" onClick={() => toast(options)}>
|
|
40
|
+
{triggerLabel}
|
|
41
|
+
</button>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const INFO_A: ToastOptions = {body: 'Toast A'};
|
|
46
|
+
const INFO_B: ToastOptions = {body: 'Toast B'};
|
|
47
|
+
const AUTO_TOAST: ToastOptions = {body: 'Auto toast', autoHideDuration: 3000};
|
|
48
|
+
|
|
49
|
+
function renderViewport(children: React.ReactNode) {
|
|
50
|
+
return render(<ToastViewport isTopLayer={false}>{children}</ToastViewport>);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Fire the transition-end that ToastViewport listens for to unmount an
|
|
54
|
+
// exiting toast (jsdom does not run CSS transitions).
|
|
55
|
+
function completeExit(toastId: string) {
|
|
56
|
+
const node = document.querySelector<HTMLElement>(
|
|
57
|
+
`[data-toast-id="${toastId}"]`,
|
|
58
|
+
);
|
|
59
|
+
if (node) {
|
|
60
|
+
fireEvent.transitionEnd(node, {propertyName: 'grid-template-rows'});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
describe('ToastViewport keyboard reach + focus', () => {
|
|
65
|
+
it('F6 moves focus into the newest toast', () => {
|
|
66
|
+
renderViewport(
|
|
67
|
+
<ShowToastButton options={INFO_A} triggerLabel="Trigger A" />,
|
|
68
|
+
);
|
|
69
|
+
const trigger = screen.getByText('Trigger A');
|
|
70
|
+
trigger.focus();
|
|
71
|
+
act(() => {
|
|
72
|
+
fireEvent.click(trigger);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
expect(screen.getByText('Toast A')).toBeInTheDocument();
|
|
76
|
+
expect(document.activeElement).toBe(trigger);
|
|
77
|
+
|
|
78
|
+
act(() => {
|
|
79
|
+
fireEvent.keyDown(document, {key: 'F6'});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// Focus lands on the dismiss button of the newest toast.
|
|
83
|
+
const dismiss = screen.getByRole('button', {name: 'Dismiss notification'});
|
|
84
|
+
expect(document.activeElement).toBe(dismiss);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('dismissing a focused toast moves focus to a remaining toast, not body', () => {
|
|
88
|
+
renderViewport(
|
|
89
|
+
<>
|
|
90
|
+
<ShowToastButton options={INFO_A} triggerLabel="Trigger A" />
|
|
91
|
+
<ShowToastButton options={INFO_B} triggerLabel="Trigger B" />
|
|
92
|
+
</>,
|
|
93
|
+
);
|
|
94
|
+
act(() => {
|
|
95
|
+
fireEvent.click(screen.getByText('Trigger A'));
|
|
96
|
+
});
|
|
97
|
+
act(() => {
|
|
98
|
+
fireEvent.click(screen.getByText('Trigger B'));
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
const dismissButtons = screen.getAllByRole('button', {
|
|
102
|
+
name: 'Dismiss notification',
|
|
103
|
+
});
|
|
104
|
+
expect(dismissButtons).toHaveLength(2);
|
|
105
|
+
|
|
106
|
+
// Focus the first toast's dismiss button, then dismiss it.
|
|
107
|
+
const firstToast = document.querySelectorAll('[data-toast-id]')[0];
|
|
108
|
+
const firstToastId = firstToast.getAttribute('data-toast-id')!;
|
|
109
|
+
const firstDismiss = firstToast.querySelector<HTMLElement>(
|
|
110
|
+
'button[aria-label="Dismiss notification"]',
|
|
111
|
+
)!;
|
|
112
|
+
firstDismiss.focus();
|
|
113
|
+
expect(document.activeElement).toBe(firstDismiss);
|
|
114
|
+
|
|
115
|
+
act(() => {
|
|
116
|
+
fireEvent.click(firstDismiss);
|
|
117
|
+
});
|
|
118
|
+
act(() => {
|
|
119
|
+
completeExit(firstToastId);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// Focus must NOT drop to <body>; it moves to the remaining toast.
|
|
123
|
+
expect(document.activeElement).not.toBe(document.body);
|
|
124
|
+
expect(document.activeElement?.getAttribute('aria-label')).toBe(
|
|
125
|
+
'Dismiss notification',
|
|
126
|
+
);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('dismissing the last focused toast restores the previously-focused element', () => {
|
|
130
|
+
renderViewport(
|
|
131
|
+
<ShowToastButton options={INFO_A} triggerLabel="Trigger A" />,
|
|
132
|
+
);
|
|
133
|
+
const trigger = screen.getByText('Trigger A');
|
|
134
|
+
trigger.focus();
|
|
135
|
+
act(() => {
|
|
136
|
+
fireEvent.click(trigger);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// F6 into the toast, remembering the trigger as the prior focus.
|
|
140
|
+
act(() => {
|
|
141
|
+
fireEvent.keyDown(document, {key: 'F6'});
|
|
142
|
+
});
|
|
143
|
+
const dismiss = screen.getByRole('button', {name: 'Dismiss notification'});
|
|
144
|
+
expect(document.activeElement).toBe(dismiss);
|
|
145
|
+
|
|
146
|
+
const toastId = document
|
|
147
|
+
.querySelector('[data-toast-id]')!
|
|
148
|
+
.getAttribute('data-toast-id')!;
|
|
149
|
+
|
|
150
|
+
act(() => {
|
|
151
|
+
fireEvent.click(dismiss);
|
|
152
|
+
});
|
|
153
|
+
act(() => {
|
|
154
|
+
completeExit(toastId);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
// No toasts left — focus returns to the element focused before F6.
|
|
158
|
+
expect(document.activeElement).toBe(trigger);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
describe('Toast blur timer pause', () => {
|
|
163
|
+
it('pauses the auto-hide timer while the window is blurred', () => {
|
|
164
|
+
vi.useFakeTimers();
|
|
165
|
+
try {
|
|
166
|
+
renderViewport(
|
|
167
|
+
<ShowToastButton options={AUTO_TOAST} triggerLabel="Trigger Auto" />,
|
|
168
|
+
);
|
|
169
|
+
act(() => {
|
|
170
|
+
fireEvent.click(screen.getByText('Trigger Auto'));
|
|
171
|
+
});
|
|
172
|
+
expect(screen.getByText('Auto toast')).toBeInTheDocument();
|
|
173
|
+
|
|
174
|
+
// Window loses focus — timer should pause.
|
|
175
|
+
act(() => {
|
|
176
|
+
window.dispatchEvent(new Event('blur'));
|
|
177
|
+
});
|
|
178
|
+
act(() => {
|
|
179
|
+
vi.advanceTimersByTime(5000);
|
|
180
|
+
});
|
|
181
|
+
// Still present because the timer was paused while blurred.
|
|
182
|
+
expect(screen.getByText('Auto toast')).toBeInTheDocument();
|
|
183
|
+
|
|
184
|
+
// Window regains focus — timer resumes and the toast dismisses.
|
|
185
|
+
act(() => {
|
|
186
|
+
window.dispatchEvent(new Event('focus'));
|
|
187
|
+
});
|
|
188
|
+
act(() => {
|
|
189
|
+
vi.advanceTimersByTime(5000);
|
|
190
|
+
});
|
|
191
|
+
const toastId = document
|
|
192
|
+
.querySelector('[data-toast-id]')
|
|
193
|
+
?.getAttribute('data-toast-id');
|
|
194
|
+
if (toastId) {
|
|
195
|
+
act(() => {
|
|
196
|
+
completeExit(toastId);
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
expect(screen.queryByText('Auto toast')).not.toBeInTheDocument();
|
|
200
|
+
} finally {
|
|
201
|
+
vi.useRealTimers();
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
});
|