@astryxdesign/core 0.4.7 → 0.5.0-canary.009bcb3
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 +161 -1
- package/dist/AlertDialog/AlertDialog.d.ts +1 -1
- package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
- package/dist/AlertDialog/AlertDialog.js +45 -20
- package/dist/AppShell/AppShell.d.ts.map +1 -1
- package/dist/AppShell/AppShell.js +3 -2
- package/dist/AspectRatio/AspectRatio.d.ts +24 -0
- package/dist/AspectRatio/AspectRatio.d.ts.map +1 -1
- package/dist/AspectRatio/AspectRatio.js +23 -4
- package/dist/Avatar/Avatar.d.ts +25 -1
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +58 -19
- package/dist/Avatar/index.d.ts +2 -2
- package/dist/Avatar/index.d.ts.map +1 -1
- package/dist/Avatar/index.js +1 -1
- package/dist/AvatarGroup/AvatarGroup.d.ts +9 -2
- package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroup.js +8 -4
- package/dist/AvatarGroup/AvatarGroupContext.d.ts +2 -1
- package/dist/AvatarGroup/AvatarGroupContext.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.js +10 -6
- package/dist/Banner/Banner.d.ts +49 -15
- package/dist/Banner/Banner.d.ts.map +1 -1
- package/dist/Banner/Banner.js +62 -20
- package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheet.js +17 -4
- package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetSwitcher.js +3 -2
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.js +11 -10
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +11 -6
- package/dist/ButtonGroup/ButtonGroup.d.ts +5 -1
- package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
- package/dist/ButtonGroup/ButtonGroup.js +26 -7
- package/dist/Calendar/Calendar.d.ts +7 -3
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +21 -23
- package/dist/Calendar/getInitialFocusDate.d.ts +46 -0
- package/dist/Calendar/getInitialFocusDate.d.ts.map +1 -0
- package/dist/Calendar/getInitialFocusDate.js +62 -0
- package/dist/Calendar/styles.d.ts +5 -14
- package/dist/Calendar/styles.d.ts.map +1 -1
- package/dist/Calendar/styles.js +15 -15
- package/dist/Card/Card.d.ts +12 -12
- package/dist/Card/Card.d.ts.map +1 -1
- package/dist/Card/Card.js +17 -9
- package/dist/Card/index.d.ts +35 -1
- package/dist/Card/index.d.ts.map +1 -1
- package/dist/Card/index.js +21 -1
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +3 -3
- package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
- package/dist/Chat/ChatComposerInput.js +2 -3
- package/dist/Chat/ChatLayout.d.ts.map +1 -1
- package/dist/Chat/ChatLayout.js +3 -3
- package/dist/Chat/ChatMessageList.d.ts +22 -3
- package/dist/Chat/ChatMessageList.d.ts.map +1 -1
- package/dist/Chat/ChatMessageList.js +6 -3
- package/dist/Chat/ChatTokenizedText.d.ts +2 -0
- package/dist/Chat/ChatTokenizedText.d.ts.map +1 -1
- package/dist/Chat/ChatTokenizedText.js +11 -6
- package/dist/Chat/useChatComposerTokens.js +1 -1
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +10 -3
- package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
- package/dist/ClickableCard/ClickableCard.js +3 -3
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +15 -4
- package/dist/CodeBlock/highlightRanges.js +1 -1
- package/dist/CodeBlock/highlightStyles.js +13 -13
- package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteInput.js +3 -2
- package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteItem.js +3 -2
- package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
- package/dist/ComplexSelector/ComplexSelector.js +1 -3
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +4 -3
- package/dist/DateInput/DateInput.d.ts +43 -0
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +22 -2
- package/dist/DateInput/NativeDateField.d.ts +10 -0
- package/dist/DateInput/NativeDateField.d.ts.map +1 -0
- package/dist/DateInput/NativeDateField.js +494 -0
- package/dist/DateInput/TouchDateField.d.ts.map +1 -1
- package/dist/DateInput/TouchDateField.js +82 -23
- package/dist/DateInput/index.d.ts +1 -1
- package/dist/DateInput/index.d.ts.map +1 -1
- package/dist/DateInput/nativeDateSegments.d.ts +22 -0
- package/dist/DateInput/nativeDateSegments.d.ts.map +1 -0
- package/dist/DateInput/nativeDateSegments.js +111 -0
- package/dist/DateRangeInput/DateRangeInput.d.ts +4 -2
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.d.ts +21 -1
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +406 -12
- package/dist/DateTimeInput/index.d.ts +1 -1
- package/dist/DateTimeInput/index.d.ts.map +1 -1
- package/dist/Dialog/Dialog.d.ts +21 -1
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +110 -58
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +4 -13
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuSubMenu.js +6 -5
- package/dist/Field/FieldLabel.d.ts.map +1 -1
- package/dist/Field/FieldLabel.js +9 -1
- package/dist/Field/InputClearButton.d.ts +9 -3
- package/dist/Field/InputClearButton.d.ts.map +1 -1
- package/dist/Field/InputClearButton.js +14 -3
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +3 -2
- package/dist/Heading/Heading.d.ts.map +1 -1
- package/dist/Heading/Heading.js +6 -3
- package/dist/HoverCard/HoverCard.d.ts +6 -0
- package/dist/HoverCard/HoverCard.d.ts.map +1 -1
- package/dist/HoverCard/HoverCard.js +104 -3
- package/dist/HoverCard/useHoverCard.d.ts +19 -2
- package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
- package/dist/HoverCard/useHoverCard.js +74 -26
- package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -1
- package/dist/Indicator/CheckboxIndicator.js +6 -2
- package/dist/Item/Item.d.ts.map +1 -1
- package/dist/Item/Item.js +4 -2
- package/dist/Kbd/Kbd.d.ts.map +1 -1
- package/dist/Kbd/Kbd.js +2 -19
- package/dist/Layer/LayerDepthContext.d.ts +52 -0
- package/dist/Layer/LayerDepthContext.d.ts.map +1 -0
- package/dist/Layer/LayerDepthContext.js +66 -0
- package/dist/Layer/gestureCounter.d.ts +8 -0
- package/dist/Layer/gestureCounter.d.ts.map +1 -0
- package/dist/Layer/gestureCounter.js +53 -0
- package/dist/Layer/index.d.ts +3 -0
- package/dist/Layer/index.d.ts.map +1 -1
- package/dist/Layer/index.js +4 -0
- package/dist/Layer/layerStack.d.ts +98 -0
- package/dist/Layer/layerStack.d.ts.map +1 -0
- package/dist/Layer/layerStack.js +306 -0
- package/dist/Layer/useLayer.d.ts +23 -13
- package/dist/Layer/useLayer.d.ts.map +1 -1
- package/dist/Layer/useLayer.js +128 -8
- package/dist/Layer/useLayerDismissal.d.ts +93 -0
- package/dist/Layer/useLayerDismissal.d.ts.map +1 -0
- package/dist/Layer/useLayerDismissal.js +91 -0
- package/dist/Lightbox/Lightbox.d.ts +1 -0
- package/dist/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/Lightbox/Lightbox.js +103 -81
- package/dist/List/List.d.ts +1 -1
- package/dist/List/List.d.ts.map +1 -1
- package/dist/List/List.js +15 -4
- package/dist/Markdown/Markdown.d.ts +1 -1
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.js +20 -7
- package/dist/Markdown/index.d.ts +1 -1
- package/dist/Markdown/index.d.ts.map +1 -1
- package/dist/Markdown/parser.d.ts +38 -1
- package/dist/Markdown/parser.d.ts.map +1 -1
- package/dist/Markdown/parser.js +182 -32
- package/dist/MetadataList/MetadataListItem.d.ts +1 -1
- package/dist/MetadataList/MetadataListItem.d.ts.map +1 -1
- package/dist/MetadataList/MetadataListItem.js +4 -1
- package/dist/MobileNav/MobileNav.d.ts +6 -1
- package/dist/MobileNav/MobileNav.d.ts.map +1 -1
- package/dist/MobileNav/MobileNav.js +61 -36
- package/dist/MultiSelector/MultiSelector.d.ts +32 -1
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +73 -15
- package/dist/MultiSelector/hooks.d.ts +7 -1
- package/dist/MultiSelector/hooks.d.ts.map +1 -1
- package/dist/MultiSelector/hooks.js +3 -2
- package/dist/MultiSelector/index.d.ts +1 -1
- package/dist/MultiSelector/index.d.ts.map +1 -1
- package/dist/NavIcon/NavIcon.d.ts.map +1 -1
- package/dist/NavIcon/NavIcon.js +5 -1
- package/dist/NavMenu/NavHeadingMenu.d.ts +1 -1
- package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
- package/dist/NavMenu/NavHeadingMenu.js +9 -5
- package/dist/NumberInput/NumberInput.d.ts +6 -1
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +54 -104
- package/dist/NumberInput/numberInputCommit.d.ts +34 -0
- package/dist/NumberInput/numberInputCommit.d.ts.map +1 -0
- package/dist/NumberInput/numberInputCommit.js +71 -0
- package/dist/NumberInput/numberParser.d.ts +64 -0
- package/dist/NumberInput/numberParser.d.ts.map +1 -0
- package/dist/NumberInput/numberParser.js +350 -0
- package/dist/Outline/Outline.d.ts.map +1 -1
- package/dist/Outline/Outline.js +3 -2
- package/dist/OverflowList/OverflowList.d.ts.map +1 -1
- package/dist/OverflowList/OverflowList.js +3 -2
- package/dist/Overlay/Overlay.d.ts.map +1 -1
- package/dist/Overlay/Overlay.js +3 -2
- package/dist/Popover/Popover.d.ts.map +1 -1
- package/dist/Popover/Popover.js +1 -9
- package/dist/Popover/usePopover.d.ts +7 -41
- package/dist/Popover/usePopover.d.ts.map +1 -1
- package/dist/Popover/usePopover.js +40 -21
- package/dist/PowerSearch/PowerSearch.d.ts +8 -2
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +19 -6
- package/dist/PowerSearch/PowerSearchEditPopover.d.ts +3 -1
- package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchEditPopover.js +28 -6
- package/dist/PowerSearch/PowerSearchValueEditor.d.ts +3 -1
- package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchValueEditor.js +110 -27
- package/dist/PowerSearch/types.d.ts +2 -0
- package/dist/PowerSearch/types.d.ts.map +1 -1
- package/dist/PowerSearch/usePowerSearchSource.d.ts +6 -1
- package/dist/PowerSearch/usePowerSearchSource.d.ts.map +1 -1
- package/dist/PowerSearch/usePowerSearchSource.js +14 -5
- package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
- package/dist/ProgressBar/ProgressBar.js +18 -5
- package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
- package/dist/Resizable/ResizeHandle.js +3 -2
- package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControl.js +3 -2
- package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
- package/dist/SelectableCard/SelectableCard.js +12 -3
- package/dist/Selector/Selector.d.ts +18 -1
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +91 -18
- package/dist/Selector/hooks.d.ts +7 -1
- package/dist/Selector/hooks.d.ts.map +1 -1
- package/dist/Selector/hooks.js +3 -2
- package/dist/SideNav/SideNav.d.ts.map +1 -1
- package/dist/SideNav/SideNav.js +4 -3
- package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
- package/dist/SideNav/SideNavHeading.js +8 -7
- package/dist/SideNav/SideNavItem.d.ts.map +1 -1
- package/dist/SideNav/SideNavItem.js +4 -3
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +37 -5
- package/dist/Spinner/Spinner.d.ts +3 -3
- package/dist/Spinner/Spinner.d.ts.map +1 -1
- package/dist/Spinner/Spinner.js +130 -78
- package/dist/StatusDot/StatusDot.d.ts.map +1 -1
- package/dist/StatusDot/StatusDot.js +6 -1
- package/dist/Stepper/Step.d.ts +140 -0
- package/dist/Stepper/Step.d.ts.map +1 -0
- package/dist/Stepper/Step.js +1045 -0
- package/dist/Stepper/StepStatus.d.ts +24 -0
- package/dist/Stepper/StepStatus.d.ts.map +1 -0
- package/dist/Stepper/StepStatus.js +1 -0
- package/dist/Stepper/Stepper.d.ts +93 -0
- package/dist/Stepper/Stepper.d.ts.map +1 -0
- package/dist/Stepper/Stepper.js +184 -0
- package/dist/Stepper/StepperContext.d.ts +41 -0
- package/dist/Stepper/StepperContext.d.ts.map +1 -0
- package/dist/Stepper/StepperContext.js +34 -0
- package/dist/Stepper/index.d.ts +8 -0
- package/dist/Stepper/index.d.ts.map +1 -0
- package/dist/Stepper/index.js +7 -0
- package/dist/Stepper/stepper.stylex.d.ts +15 -0
- package/dist/Stepper/stepper.stylex.d.ts.map +1 -0
- package/dist/Stepper/stepper.stylex.js +20 -0
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +8 -3
- package/dist/TabList/Tab.d.ts +15 -2
- package/dist/TabList/Tab.d.ts.map +1 -1
- package/dist/TabList/Tab.js +32 -7
- package/dist/TabList/TabList.d.ts +46 -7
- package/dist/TabList/TabList.d.ts.map +1 -1
- package/dist/TabList/TabList.js +353 -23
- package/dist/TabList/TabListContext.d.ts +11 -1
- package/dist/TabList/TabListContext.d.ts.map +1 -1
- package/dist/TabList/TabListContext.js +11 -2
- package/dist/TabList/TabMenu.d.ts.map +1 -1
- package/dist/TabList/TabMenu.js +3 -2
- package/dist/TabList/index.d.ts +2 -2
- package/dist/TabList/index.d.ts.map +1 -1
- package/dist/Table/BaseTable.d.ts.map +1 -1
- package/dist/Table/BaseTable.js +10 -2
- package/dist/Table/Table.d.ts.map +1 -1
- package/dist/Table/Table.js +3 -6
- package/dist/Table/TableRow.d.ts +16 -5
- package/dist/Table/TableRow.d.ts.map +1 -1
- package/dist/Table/TableRow.js +16 -5
- package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
- package/dist/Table/plugins/filtering/useTableFiltering.js +73 -4
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts +26 -0
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +54 -11
- package/dist/Table/plugins/pagination/useTablePagination.d.ts +3 -0
- package/dist/Table/plugins/pagination/useTablePagination.d.ts.map +1 -1
- package/dist/Table/plugins/pagination/useTablePagination.js +21 -4
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +7 -2
- package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts.map +1 -1
- package/dist/Table/plugins/rowStatus/useTableRowStatus.js +10 -3
- package/dist/Table/plugins/selection/useTableSelection.d.ts +16 -0
- package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
- package/dist/Table/plugins/selection/useTableSelection.js +43 -5
- package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
- package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +3 -4
- package/dist/Table/types.d.ts +22 -4
- package/dist/Table/types.d.ts.map +1 -1
- package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
- package/dist/Table/useBaseTablePlugins.js +5 -0
- package/dist/Text/Text.d.ts.map +1 -1
- package/dist/Text/Text.js +6 -3
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +16 -10
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +3 -2
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +3 -2
- package/dist/Timestamp/Timestamp.d.ts +1 -1
- package/dist/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +15 -21
- package/dist/Toast/Toast.d.ts.map +1 -1
- package/dist/Toast/Toast.js +22 -7
- package/dist/Toast/ToastViewport.d.ts +1 -0
- package/dist/Toast/ToastViewport.d.ts.map +1 -1
- package/dist/Toast/ToastViewport.js +71 -18
- package/dist/Token/Token.d.ts +1 -1
- package/dist/Token/Token.d.ts.map +1 -1
- package/dist/Token/Token.js +20 -9
- package/dist/Token/TokenLink.d.ts +1 -1
- package/dist/Token/TokenLink.d.ts.map +1 -1
- package/dist/Token/TokenLink.js +7 -4
- package/dist/Tokenizer/Tokenizer.d.ts +14 -1
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +33 -21
- package/dist/Tooltip/Tooltip.d.ts +5 -0
- package/dist/Tooltip/Tooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.d.ts +5 -0
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +39 -24
- package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
- package/dist/TopNav/TopNavHeading.js +5 -4
- package/dist/TopNav/TopNavMegaMenu.d.ts +1 -1
- package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMegaMenu.js +31 -11
- package/dist/TopNav/TopNavMenu.d.ts +1 -1
- package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMenu.js +22 -7
- package/dist/TreeList/TreeList.d.ts +1 -1
- package/dist/TreeList/TreeList.d.ts.map +1 -1
- package/dist/TreeList/TreeList.js +7 -2
- package/dist/Typeahead/BaseTypeahead.d.ts +35 -0
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +119 -37
- package/dist/Typeahead/Typeahead.d.ts +8 -1
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +5 -2
- package/dist/Typeahead/TypeaheadItem.d.ts +1 -1
- package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
- package/dist/Typeahead/TypeaheadItem.js +7 -2
- package/dist/astryx.css +113 -11
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/useFocusTrap.d.ts +7 -4
- package/dist/hooks/useFocusTrap.d.ts.map +1 -1
- package/dist/hooks/useFocusTrap.js +60 -95
- package/dist/hooks/useHotkeys.d.ts.map +1 -1
- package/dist/hooks/useHotkeys.js +3 -18
- package/dist/hooks/useMergedRefs.d.ts +18 -0
- package/dist/hooks/useMergedRefs.d.ts.map +1 -0
- package/dist/hooks/useMergedRefs.js +25 -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/Theme.d.ts.map +1 -1
- package/dist/theme/Theme.js +46 -10
- package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
- package/dist/theme/derivedVarRegistry.js +24 -4
- package/dist/theme/generateThemeRules.d.ts +21 -0
- package/dist/theme/generateThemeRules.d.ts.map +1 -1
- package/dist/theme/generateThemeRules.js +26 -0
- package/dist/theme/syntax/tokens.d.ts +1 -1
- package/dist/theme/syntax/tokens.d.ts.map +1 -1
- package/dist/theme/syntax/tokens.js +5 -2
- package/dist/utils/groupItems.d.ts +5 -1
- package/dist/utils/groupItems.d.ts.map +1 -1
- package/dist/utils/groupItems.js +9 -9
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/isApplePlatform.d.ts +18 -0
- package/dist/utils/isApplePlatform.d.ts.map +1 -0
- package/dist/utils/isApplePlatform.js +37 -0
- package/dist/utils/sharedResizeObserver.d.ts.map +1 -1
- package/dist/utils/sharedResizeObserver.js +10 -1
- package/dist/utils/timeParser.d.ts +1 -1
- package/dist/utils/timeParser.d.ts.map +1 -1
- package/dist/utils/timeParser.js +26 -12
- package/locales/af-ZA.json +6 -6
- package/locales/ar-SA.json +6 -6
- package/locales/ca-ES.json +5 -5
- package/locales/cs-CZ.json +6 -6
- package/locales/da-DK.json +6 -6
- package/locales/de-DE.json +6 -6
- package/locales/el-GR.json +6 -6
- package/locales/en.json +163 -11
- package/locales/es-ES.json +5 -5
- package/locales/fi-FI.json +6 -6
- package/locales/fr-FR.json +6 -6
- package/locales/he-IL.json +6 -6
- package/locales/hu-HU.json +6 -6
- package/locales/it-IT.json +6 -6
- package/locales/ja-JP.json +6 -6
- package/locales/ko-KR.json +6 -6
- package/locales/nl-NL.json +6 -6
- package/locales/no-NO.json +6 -6
- package/locales/pl-PL.json +6 -6
- package/locales/pseudo.json +114 -0
- package/locales/pt-BR.json +6 -6
- package/locales/pt-PT.json +6 -6
- package/locales/ro-RO.json +6 -6
- package/locales/ru-RU.json +6 -6
- package/locales/sr-SP.json +6 -6
- package/locales/sv-SE.json +6 -6
- package/locales/tr-TR.json +6 -6
- package/locales/uk-UA.json +6 -6
- package/locales/vi-VN.json +6 -6
- package/locales/zh-CN.json +6 -6
- package/locales/zh-TW.json +6 -6
- package/package.json +8 -3
- package/src/AlertDialog/AlertDialog.doc.mjs +114 -30
- package/src/AlertDialog/AlertDialog.test.tsx +211 -2
- package/src/AlertDialog/AlertDialog.tsx +62 -20
- package/src/AppShell/AppShell.tsx +3 -2
- package/src/AspectRatio/AspectRatio.doc.mjs +6 -3
- package/src/AspectRatio/AspectRatio.test.tsx +57 -10
- package/src/AspectRatio/AspectRatio.tsx +40 -1
- package/src/Avatar/Avatar.doc.mjs +14 -3
- package/src/Avatar/Avatar.test.tsx +97 -0
- package/src/Avatar/Avatar.tsx +125 -52
- package/src/Avatar/index.ts +2 -2
- package/src/AvatarGroup/AvatarGroup.doc.mjs +8 -2
- package/src/AvatarGroup/AvatarGroup.test.tsx +24 -0
- package/src/AvatarGroup/AvatarGroup.tsx +15 -6
- package/src/AvatarGroup/AvatarGroupContext.ts +5 -3
- package/src/AvatarGroup/AvatarGroupOverflow.tsx +10 -4
- package/src/Banner/Banner.doc.mjs +22 -11
- package/src/Banner/Banner.test.tsx +177 -25
- package/src/Banner/Banner.tsx +93 -27
- package/src/BottomSheet/BottomSheet.test.tsx +123 -0
- package/src/BottomSheet/BottomSheet.tsx +17 -4
- package/src/BottomSheet/BottomSheetSwitcher.tsx +3 -2
- package/src/Breadcrumbs/BreadcrumbItem.tsx +9 -5
- package/src/Button/Button.doc.mjs +24 -1
- package/src/Button/Button.test.tsx +32 -4
- package/src/Button/Button.tsx +12 -5
- package/src/ButtonGroup/ButtonGroup.doc.mjs +10 -1
- package/src/ButtonGroup/ButtonGroup.test.tsx +404 -1
- package/src/ButtonGroup/ButtonGroup.tsx +23 -5
- package/src/Calendar/Calendar.doc.mjs +7 -6
- package/src/Calendar/Calendar.test.tsx +143 -0
- package/src/Calendar/Calendar.tsx +30 -26
- package/src/Calendar/getInitialFocusDate.test.ts +94 -0
- package/src/Calendar/getInitialFocusDate.ts +93 -0
- package/src/Calendar/styles.ts +49 -31
- package/src/Card/Card.doc.mjs +10 -7
- package/src/Card/Card.test.tsx +113 -19
- package/src/Card/Card.tsx +67 -89
- package/src/Card/index.ts +36 -1
- package/src/Carousel/Carousel.tsx +3 -2
- package/src/Chat/ChatComposerInput.tsx +5 -1
- package/src/Chat/ChatLayout.tsx +3 -2
- package/src/Chat/ChatMessageList.doc.mjs +9 -1
- package/src/Chat/ChatMessageList.test.tsx +46 -0
- package/src/Chat/ChatMessageList.tsx +28 -4
- package/src/Chat/ChatTokenizedText.tsx +17 -10
- package/src/Chat/useChatComposerTokens.ts +1 -1
- package/src/CheckboxInput/CheckboxInput.doc.mjs +2 -0
- package/src/CheckboxInput/CheckboxInput.test.tsx +15 -0
- package/src/CheckboxInput/CheckboxInput.tsx +8 -2
- package/src/ClickableCard/ClickableCard.tsx +3 -2
- package/src/CodeBlock/CodeBlock.doc.mjs +16 -4
- package/src/CodeBlock/CodeBlock.test.tsx +37 -0
- package/src/CodeBlock/CodeBlock.tsx +20 -4
- package/src/CodeBlock/highlightRanges.ts +1 -1
- package/src/CodeBlock/highlightStyles.ts +13 -13
- package/src/CommandPalette/CommandPaletteInput.tsx +3 -2
- package/src/CommandPalette/CommandPaletteItem.tsx +3 -2
- package/src/ComplexSelector/ComplexSelector.test.tsx +32 -0
- package/src/ComplexSelector/ComplexSelector.tsx +1 -3
- package/src/ContextMenu/ContextMenu.doc.mjs +5 -0
- package/src/ContextMenu/ContextMenu.tsx +4 -3
- package/src/DateInput/DateInput.doc.mjs +16 -0
- package/src/DateInput/DateInput.tsx +55 -2
- package/src/DateInput/DateInputTouch.test.tsx +146 -32
- package/src/DateInput/NativeDateField.test.tsx +635 -0
- package/src/DateInput/NativeDateField.tsx +641 -0
- package/src/DateInput/TouchDateField.tsx +108 -24
- package/src/DateInput/index.ts +1 -0
- package/src/DateInput/nativeDateSegments.ts +127 -0
- package/src/DateRangeInput/DateRangeInput.doc.mjs +2 -2
- package/src/DateRangeInput/DateRangeInput.test.tsx +22 -0
- package/src/DateRangeInput/DateRangeInput.tsx +4 -2
- package/src/DateTimeInput/DateTimeInput.doc.mjs +18 -0
- package/src/DateTimeInput/DateTimeInput.test.tsx +1088 -0
- package/src/DateTimeInput/DateTimeInput.tsx +556 -24
- package/src/DateTimeInput/index.ts +1 -0
- package/src/Dialog/Dialog.doc.mjs +8 -3
- package/src/Dialog/Dialog.test.tsx +429 -2
- package/src/Dialog/Dialog.tsx +133 -58
- package/src/DropdownMenu/DropdownMenu.doc.mjs +6 -0
- package/src/DropdownMenu/DropdownMenu.test.tsx +44 -10
- package/src/DropdownMenu/DropdownMenu.tsx +4 -13
- package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +8 -5
- package/src/DropdownMenu/DropdownMenuSubMenu.tsx +8 -11
- package/src/Field/Field.doc.mjs +13 -2
- package/src/Field/FieldLabel.test.tsx +29 -0
- package/src/Field/FieldLabel.tsx +7 -0
- package/src/Field/InputClearButton.test.tsx +15 -1
- package/src/Field/InputClearButton.tsx +28 -4
- package/src/FileInput/FileInput.tsx +3 -2
- package/src/Heading/Heading.test.tsx +23 -1
- package/src/Heading/Heading.tsx +6 -3
- package/src/HoverCard/HoverCard.doc.mjs +13 -2
- package/src/HoverCard/HoverCard.test.tsx +154 -4
- package/src/HoverCard/HoverCard.tsx +143 -3
- package/src/HoverCard/useHoverCard.tsx +104 -33
- package/src/Indicator/CheckboxIndicator.tsx +14 -8
- package/src/Indicator/Indicator.doc.mjs +2 -0
- package/src/Item/Item.tsx +5 -4
- package/src/Kbd/Kbd.tsx +2 -19
- package/src/Layer/LayerDepthContext.tsx +62 -0
- package/src/Layer/gestureCounter.ts +57 -0
- package/src/Layer/index.ts +9 -0
- package/src/Layer/layerDismissalFamilies.test.tsx +359 -0
- package/src/Layer/layerDismissalInvariants.test.tsx +417 -0
- package/src/Layer/layerStack.ts +362 -0
- package/src/Layer/useLayer.test.tsx +324 -15
- package/src/Layer/useLayer.tsx +164 -8
- package/src/Layer/useLayerDismissal.test.tsx +469 -0
- package/src/Layer/useLayerDismissal.ts +173 -0
- package/src/Layout/Layout.doc.mjs +2 -2
- package/src/Layout/__tests__/edgeCompensation.test.tsx +1 -1
- package/src/Lightbox/Lightbox.doc.mjs +12 -0
- package/src/Lightbox/Lightbox.tsx +124 -102
- package/src/Link/Link.doc.mjs +39 -0
- package/src/List/List.test.tsx +38 -0
- package/src/List/List.tsx +8 -1
- package/src/Markdown/Markdown.doc.mjs +5 -0
- package/src/Markdown/Markdown.test.tsx +37 -0
- package/src/Markdown/Markdown.tsx +16 -5
- package/src/Markdown/incremental.test.ts +16 -2
- package/src/Markdown/index.ts +1 -0
- package/src/Markdown/parser.perf.test.ts +96 -1
- package/src/Markdown/parser.test.ts +178 -2
- package/src/Markdown/parser.ts +253 -32
- package/src/MetadataList/MetadataList.test.tsx +75 -2
- package/src/MetadataList/MetadataListItem.tsx +5 -2
- package/src/MobileNav/MobileNav.tsx +62 -36
- package/src/MoreMenu/MoreMenu.doc.mjs +7 -1
- package/src/MultiSelector/MultiSelector.doc.mjs +49 -1
- package/src/MultiSelector/MultiSelector.test.tsx +311 -0
- package/src/MultiSelector/MultiSelector.tsx +151 -15
- package/src/MultiSelector/hooks.ts +9 -2
- package/src/MultiSelector/index.ts +1 -0
- package/src/NavIcon/NavIcon.doc.mjs +8 -2
- package/src/NavIcon/NavIcon.test.tsx +9 -0
- package/src/NavIcon/NavIcon.tsx +5 -1
- package/src/NavMenu/NavHeadingMenu.test.tsx +30 -0
- package/src/NavMenu/NavHeadingMenu.tsx +9 -5
- package/src/NumberInput/NumberInput.doc.mjs +31 -7
- package/src/NumberInput/NumberInput.test.tsx +436 -8
- package/src/NumberInput/NumberInput.tsx +62 -114
- package/src/NumberInput/numberInputCommit.test.ts +72 -0
- package/src/NumberInput/numberInputCommit.ts +103 -0
- package/src/NumberInput/numberParser.docblock.test.ts +234 -0
- package/src/NumberInput/numberParser.test.ts +222 -0
- package/src/NumberInput/numberParser.ts +403 -0
- package/src/Outline/Outline.tsx +3 -2
- package/src/OverflowList/OverflowList.tsx +3 -2
- package/src/Overlay/Overlay.tsx +3 -2
- package/src/Pagination/Pagination.test.tsx +3 -2
- package/src/Popover/Popover.test.tsx +14 -0
- package/src/Popover/Popover.tsx +1 -9
- package/src/Popover/usePopover.tsx +57 -32
- package/src/PowerSearch/PowerSearch.doc.mjs +160 -28
- package/src/PowerSearch/PowerSearch.test.tsx +240 -1
- package/src/PowerSearch/PowerSearch.tsx +34 -5
- package/src/PowerSearch/PowerSearchEditPopover.test.tsx +288 -0
- package/src/PowerSearch/PowerSearchEditPopover.tsx +29 -2
- package/src/PowerSearch/PowerSearchValueEditor.test.tsx +111 -1
- package/src/PowerSearch/PowerSearchValueEditor.tsx +124 -10
- package/src/PowerSearch/types.ts +2 -0
- package/src/PowerSearch/usePowerSearchSource.test.ts +82 -2
- package/src/PowerSearch/usePowerSearchSource.ts +13 -3
- package/src/ProgressBar/ProgressBar.doc.mjs +42 -6
- package/src/ProgressBar/ProgressBar.test.tsx +24 -0
- package/src/ProgressBar/ProgressBar.tsx +28 -8
- package/src/Resizable/ResizeHandle.tsx +3 -2
- package/src/SegmentedControl/SegmentedControl.tsx +3 -2
- package/src/SelectableCard/SelectableCard.doc.mjs +3 -0
- package/src/SelectableCard/SelectableCard.tsx +19 -2
- package/src/Selector/Selector.doc.mjs +26 -1
- package/src/Selector/Selector.test.tsx +346 -1
- package/src/Selector/Selector.tsx +148 -21
- package/src/Selector/hooks.ts +17 -2
- package/src/SideNav/SideNav.doc.mjs +6 -6
- package/src/SideNav/SideNav.tsx +4 -2
- package/src/SideNav/SideNavHeading.tsx +12 -12
- package/src/SideNav/SideNavItem.tsx +4 -2
- package/src/Slider/Slider.test.tsx +106 -1
- package/src/Slider/Slider.tsx +55 -3
- package/src/Spinner/Spinner.test.tsx +147 -1
- package/src/Spinner/Spinner.tsx +120 -101
- package/src/StatusDot/StatusDot.doc.mjs +8 -2
- package/src/StatusDot/StatusDot.test.tsx +9 -0
- package/src/StatusDot/StatusDot.tsx +7 -1
- package/src/Stepper/Step.doc.mjs +98 -0
- package/src/Stepper/Step.tsx +1638 -0
- package/src/Stepper/StepStatus.ts +26 -0
- package/src/Stepper/Stepper.doc.mjs +370 -0
- package/src/Stepper/Stepper.test.tsx +1024 -0
- package/src/Stepper/Stepper.tsx +258 -0
- package/src/Stepper/StepperContext.ts +71 -0
- package/src/Stepper/index.ts +18 -0
- package/src/Stepper/stepper.stylex.ts +19 -0
- package/src/Switch/Switch.doc.mjs +2 -0
- package/src/Switch/Switch.test.tsx +10 -0
- package/src/Switch/Switch.tsx +6 -2
- package/src/TabList/Tab.doc.mjs +13 -1
- package/src/TabList/Tab.tsx +67 -7
- package/src/TabList/TabList.doc.mjs +22 -6
- package/src/TabList/TabList.test.tsx +559 -0
- package/src/TabList/TabList.tsx +490 -22
- package/src/TabList/TabListContext.ts +13 -2
- package/src/TabList/TabMenu.tsx +3 -2
- package/src/TabList/index.ts +6 -2
- package/src/Table/BaseTable.tsx +12 -4
- package/src/Table/Table.doc.mjs +9 -2
- package/src/Table/Table.test.tsx +132 -14
- package/src/Table/Table.tsx +3 -8
- package/src/Table/TableBody.doc.mjs +40 -0
- package/src/Table/TableFooter.doc.mjs +40 -0
- package/src/Table/TableHeader.doc.mjs +40 -0
- package/src/Table/TableRow.tsx +16 -5
- package/src/Table/plugins/filtering/useTableFiltering.test.tsx +44 -6
- package/src/Table/plugins/filtering/useTableFiltering.tsx +100 -4
- package/src/Table/plugins/groupedRows/useTableGroupedRows-perf.test.tsx +112 -0
- package/src/Table/plugins/groupedRows/useTableGroupedRows.test.tsx +100 -0
- package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +67 -12
- package/src/Table/plugins/pagination/useTablePagination.test.tsx +34 -4
- package/src/Table/plugins/pagination/useTablePagination.tsx +35 -3
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +9 -2
- package/src/Table/plugins/rowStatus/useTableRowStatus.test.tsx +13 -7
- package/src/Table/plugins/rowStatus/useTableRowStatus.tsx +12 -3
- package/src/Table/plugins/selection/useTableSelection.test.tsx +138 -0
- package/src/Table/plugins/selection/useTableSelection.tsx +63 -7
- package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -2
- package/src/Table/types.ts +22 -4
- package/src/Table/useBaseTablePlugins.ts +5 -0
- package/src/Table/useTableGroupedRows.doc.mjs +5 -4
- package/src/Table/useTablePagination.doc.mjs +7 -0
- package/src/Table/useTableRowStatus.doc.mjs +1 -1
- package/src/Table/useTableSelection.doc.mjs +31 -0
- package/src/Text/Text.test.tsx +67 -1
- package/src/Text/Text.tsx +6 -3
- package/src/TextArea/TextArea.doc.mjs +12 -2
- package/src/TextArea/TextArea.test.tsx +11 -0
- package/src/TextArea/TextArea.tsx +37 -24
- package/src/TextInput/TextInput.doc.mjs +10 -0
- package/src/TextInput/TextInput.tsx +3 -2
- package/src/Thumbnail/Thumbnail.doc.mjs +1 -1
- package/src/TimeInput/TimeInput.tsx +2 -2
- package/src/Timestamp/Timestamp.test.tsx +58 -0
- package/src/Timestamp/Timestamp.tsx +12 -10
- package/src/Toast/Toast.doc.mjs +26 -12
- package/src/Toast/Toast.tsx +28 -4
- package/src/Toast/ToastViewport.test.tsx +536 -8
- package/src/Toast/ToastViewport.tsx +81 -12
- package/src/Token/Token.test.tsx +95 -0
- package/src/Token/Token.tsx +15 -10
- package/src/Token/TokenLink.tsx +14 -5
- package/src/Tokenizer/Tokenizer.doc.mjs +43 -3
- package/src/Tokenizer/Tokenizer.test.tsx +161 -0
- package/src/Tokenizer/Tokenizer.tsx +53 -24
- package/src/Toolbar/Toolbar.doc.mjs +5 -0
- package/src/Tooltip/Tooltip.doc.mjs +5 -0
- package/src/Tooltip/Tooltip.test.tsx +32 -0
- package/src/Tooltip/Tooltip.tsx +5 -0
- package/src/Tooltip/useTooltip.tsx +47 -24
- package/src/TopNav/TopNavHeading.tsx +5 -4
- package/src/TopNav/TopNavMegaMenu.test.tsx +104 -0
- package/src/TopNav/TopNavMegaMenu.tsx +47 -5
- package/src/TopNav/TopNavMenu.test.tsx +133 -1
- package/src/TopNav/TopNavMenu.tsx +38 -7
- package/src/TreeList/TreeList.test.tsx +49 -0
- package/src/TreeList/TreeList.tsx +7 -2
- package/src/Typeahead/BaseTypeahead.doc.mjs +24 -0
- package/src/Typeahead/BaseTypeahead.tsx +181 -39
- package/src/Typeahead/Typeahead.doc.mjs +11 -0
- package/src/Typeahead/Typeahead.test.tsx +203 -0
- package/src/Typeahead/Typeahead.tsx +12 -2
- package/src/Typeahead/TypeaheadItem.test.tsx +43 -0
- package/src/Typeahead/TypeaheadItem.tsx +8 -1
- package/src/hooks/index.ts +2 -0
- package/src/hooks/useAnnounce.doc.mjs +96 -0
- package/src/hooks/useContainerReveal.doc.mjs +2 -2
- package/src/hooks/useDevWarning.doc.mjs +96 -0
- package/src/hooks/useFocusTrap.test.tsx +14 -0
- package/src/hooks/useFocusTrap.ts +62 -111
- package/src/hooks/useFocusTrapEscapeShim.test.tsx +165 -0
- package/src/hooks/useHotkeys.ts +3 -18
- package/src/hooks/useIndicatorFocusRing.doc.mjs +104 -0
- package/src/hooks/useInputStatusIcon.doc.mjs +142 -0
- package/src/hooks/useInteractiveRole.doc.mjs +119 -0
- package/src/hooks/useLongPress.doc.mjs +123 -0
- package/src/hooks/useMergedRefs.doc.mjs +79 -0
- package/src/hooks/useMergedRefs.test.tsx +62 -0
- package/src/hooks/useMergedRefs.ts +36 -0
- package/src/hooks/useTypeahead.doc.mjs +153 -0
- package/src/index.ts +1 -0
- package/src/raw-import.d.ts +14 -0
- package/src/theme/MediaTheme.doc.mjs +5 -5
- package/src/theme/Theme.test.tsx +104 -2
- package/src/theme/Theme.tsx +49 -14
- package/src/theme/defineTheme.test.ts +23 -0
- package/src/theme/derivedVarRegistry.test.ts +26 -3
- package/src/theme/derivedVarRegistry.ts +23 -4
- package/src/theme/generateThemeRules.test.ts +99 -1
- package/src/theme/generateThemeRules.ts +28 -0
- package/src/theme/syntax/tokens.ts +5 -2
- package/src/utils/groupItems.ts +12 -6
- package/src/utils/index.ts +1 -1
- package/src/utils/isApplePlatform.test.ts +61 -0
- package/src/utils/isApplePlatform.ts +37 -0
- package/src/utils/sharedResizeObserver.ts +10 -2
- package/src/utils/timeParser.test.ts +6 -1
- package/src/utils/timeParser.ts +35 -13
- package/src/__tests__/inputWidthContract.test.tsx +0 -69
|
@@ -0,0 +1,635 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file NativeDateField.test.tsx
|
|
5
|
+
* @input Uses vitest, @testing-library/react, DateInput
|
|
6
|
+
* @output Unit tests for the OS-picker surface (`nativePicker`)
|
|
7
|
+
* @position Testing; validates NativeDateField.tsx
|
|
8
|
+
*
|
|
9
|
+
* Every test renders through `DateInput` with a pointer stubbed, so the
|
|
10
|
+
* surface selection in DateInput.tsx is exercised too. `nativePicker`
|
|
11
|
+
* defaults to `'touch'`, so a coarse pointer alone gets the native control.
|
|
12
|
+
*
|
|
13
|
+
* The iOS behaviours these pin — the picker detaching from the field on a
|
|
14
|
+
* programmatic write, React's synthetic change not firing for the picker's
|
|
15
|
+
* edits, `text-overflow` being inert on a flex box — were all measured on a
|
|
16
|
+
* real device and none reproduce in jsdom. Where a test asserts a CSS rule
|
|
17
|
+
* rather than a behaviour, that is why.
|
|
18
|
+
*
|
|
19
|
+
* SYNC: When NativeDateField.tsx changes, update tests to match new behavior
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import {describe, it, expect, vi, beforeEach, afterEach} from 'vitest';
|
|
23
|
+
import {render, screen, fireEvent} from '@testing-library/react';
|
|
24
|
+
import {DateInput} from './DateInput';
|
|
25
|
+
import type * as NativeDateSegments from './nativeDateSegments';
|
|
26
|
+
import {
|
|
27
|
+
hasEditableDateSegments,
|
|
28
|
+
resetDateSegmentProbe,
|
|
29
|
+
} from './nativeDateSegments';
|
|
30
|
+
import {InternationalizationProvider} from '../i18n';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Lets a test say which kind of `<input type="date">` the engine draws.
|
|
34
|
+
* `null` (the default) runs the real probe, so every other test in this file
|
|
35
|
+
* exercises the shipping path: jsdom lays nothing out, so the probe reports
|
|
36
|
+
* `'unknown'` and the coarse pointer resolves it to picker-only.
|
|
37
|
+
*/
|
|
38
|
+
const {segmentState} = vi.hoisted(() => ({
|
|
39
|
+
segmentState: {editable: null as boolean | null},
|
|
40
|
+
}));
|
|
41
|
+
|
|
42
|
+
vi.mock('./nativeDateSegments', async importOriginal => {
|
|
43
|
+
const actual = await importOriginal<typeof NativeDateSegments>();
|
|
44
|
+
return {
|
|
45
|
+
...actual,
|
|
46
|
+
hasEditableDateSegments: (isTouchPointer: boolean) =>
|
|
47
|
+
segmentState.editable ?? actual.hasEditableDateSegments(isTouchPointer),
|
|
48
|
+
};
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const HOVER_CAPABLE = /\(\s*hover\s*:\s*hover\s*\)/;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Astryx's touch picker mounts a month scroller that observes its own size;
|
|
55
|
+
* jsdom ships no ResizeObserver. Only the `nativePicker="never"` test reaches
|
|
56
|
+
* it, but stubbing it for the file keeps that test honest about which surface
|
|
57
|
+
* it got.
|
|
58
|
+
*/
|
|
59
|
+
class MockResizeObserver {
|
|
60
|
+
observe() {}
|
|
61
|
+
unobserve() {}
|
|
62
|
+
disconnect() {}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Point `(pointer: coarse)` at a touch or mouse device. */
|
|
66
|
+
function stubPointer(isCoarse: boolean): void {
|
|
67
|
+
vi.stubGlobal('matchMedia', (query: string) => ({
|
|
68
|
+
matches: /pointer:\s*coarse/.test(query)
|
|
69
|
+
? isCoarse
|
|
70
|
+
: /pointer:\s*fine/.test(query)
|
|
71
|
+
? !isCoarse
|
|
72
|
+
: HOVER_CAPABLE.test(query),
|
|
73
|
+
media: query,
|
|
74
|
+
onchange: null,
|
|
75
|
+
addListener: () => {},
|
|
76
|
+
removeListener: () => {},
|
|
77
|
+
addEventListener: () => {},
|
|
78
|
+
removeEventListener: () => {},
|
|
79
|
+
dispatchEvent: () => false,
|
|
80
|
+
}));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function getInput(): HTMLInputElement {
|
|
84
|
+
const input = document.querySelector('input');
|
|
85
|
+
if (!input) {
|
|
86
|
+
throw new Error('DateInput rendered no input element');
|
|
87
|
+
}
|
|
88
|
+
return input;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** The CSS rules that apply to an element, for the paint-level assertions. */
|
|
92
|
+
function rulesFor(el: Element): string {
|
|
93
|
+
const classes = new Set(el.className.split(/\s+/).filter(Boolean));
|
|
94
|
+
return Array.from(document.styleSheets)
|
|
95
|
+
.flatMap(sheet => {
|
|
96
|
+
try {
|
|
97
|
+
return Array.from(sheet.cssRules);
|
|
98
|
+
} catch {
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
.map(rule => rule.cssText)
|
|
103
|
+
.filter(text => [...classes].some(cls => text.includes(`.${cls}`)))
|
|
104
|
+
.join(' ');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
beforeEach(() => {
|
|
108
|
+
vi.stubGlobal('ResizeObserver', MockResizeObserver);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
afterEach(() => {
|
|
112
|
+
vi.unstubAllGlobals();
|
|
113
|
+
vi.restoreAllMocks();
|
|
114
|
+
segmentState.editable = null;
|
|
115
|
+
resetDateSegmentProbe();
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
describe('DateInput nativePicker', () => {
|
|
119
|
+
// ===========================================================================
|
|
120
|
+
// Which surface renders
|
|
121
|
+
// ===========================================================================
|
|
122
|
+
|
|
123
|
+
it('renders the native control on touch by default', () => {
|
|
124
|
+
stubPointer(true);
|
|
125
|
+
render(<DateInput label="Date" onChange={() => {}} />);
|
|
126
|
+
|
|
127
|
+
expect(getInput()).toHaveAttribute('type', 'date');
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it('keeps the calendar popover on a mouse-driven device', () => {
|
|
131
|
+
stubPointer(false);
|
|
132
|
+
render(<DateInput label="Date" onChange={() => {}} />);
|
|
133
|
+
|
|
134
|
+
const input = getInput();
|
|
135
|
+
expect(input).toHaveAttribute('type', 'text');
|
|
136
|
+
expect(input).toHaveAttribute('role', 'combobox');
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('falls back to Astryx\u2019s touch picker when told never', () => {
|
|
140
|
+
stubPointer(true);
|
|
141
|
+
render(<DateInput label="Date" nativePicker="never" onChange={() => {}} />);
|
|
142
|
+
|
|
143
|
+
const input = getInput();
|
|
144
|
+
expect(input).toHaveAttribute('type', 'text');
|
|
145
|
+
expect(input).toHaveAttribute('role', 'combobox');
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('uses the native control on a mouse device when told always', () => {
|
|
149
|
+
stubPointer(false);
|
|
150
|
+
render(
|
|
151
|
+
<DateInput label="Date" nativePicker="always" onChange={() => {}} />,
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
expect(getInput()).toHaveAttribute('type', 'date');
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('drops the popup ARIA the other surfaces carry', () => {
|
|
158
|
+
// There is no in-page popup to describe: the OS draws the picker.
|
|
159
|
+
stubPointer(true);
|
|
160
|
+
render(<DateInput label="Date" onChange={() => {}} />);
|
|
161
|
+
|
|
162
|
+
const input = getInput();
|
|
163
|
+
expect(input).not.toHaveAttribute('role', 'combobox');
|
|
164
|
+
expect(input).not.toHaveAttribute('aria-expanded');
|
|
165
|
+
expect(input).not.toHaveAttribute('aria-haspopup');
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
// ===========================================================================
|
|
169
|
+
// Value round-trip
|
|
170
|
+
// ===========================================================================
|
|
171
|
+
|
|
172
|
+
it('keeps the control\u2019s own value ISO', () => {
|
|
173
|
+
stubPointer(true);
|
|
174
|
+
render(
|
|
175
|
+
<DateInput
|
|
176
|
+
label="Date"
|
|
177
|
+
value="2026-01-25"
|
|
178
|
+
format="date_long"
|
|
179
|
+
onChange={() => {}}
|
|
180
|
+
/>,
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
// ISO is the only form the control accepts, and what the picker reads and
|
|
184
|
+
// writes; `format` rides on the overlay instead.
|
|
185
|
+
expect(getInput()).toHaveValue('2026-01-25');
|
|
186
|
+
expect(screen.getByText('January 25, 2026')).toBeInTheDocument();
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('fires onChange with the ISO date the control reports', () => {
|
|
190
|
+
stubPointer(true);
|
|
191
|
+
const onChange = vi.fn();
|
|
192
|
+
render(<DateInput label="Date" onChange={onChange} />);
|
|
193
|
+
|
|
194
|
+
fireEvent.change(getInput(), {target: {value: '2026-03-21'}});
|
|
195
|
+
|
|
196
|
+
expect(onChange).toHaveBeenCalledExactlyOnceWith('2026-03-21');
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('fires onChange with undefined when the control is emptied', () => {
|
|
200
|
+
stubPointer(true);
|
|
201
|
+
const onChange = vi.fn();
|
|
202
|
+
render(<DateInput label="Date" value="2026-03-21" onChange={onChange} />);
|
|
203
|
+
|
|
204
|
+
fireEvent.change(getInput(), {target: {value: ''}});
|
|
205
|
+
|
|
206
|
+
expect(onChange).toHaveBeenCalledWith(undefined);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it('commits an edit React\u2019s synthetic change does not see', () => {
|
|
210
|
+
// The iOS failure, reproduced: the picker edits the field and a native
|
|
211
|
+
// `input` event fires, but React's synthetic `onChange` never runs — so
|
|
212
|
+
// React re-renders and writes its stale value back over the picker's.
|
|
213
|
+
// Assigning `.value` first updates React's internal value tracker, which
|
|
214
|
+
// is what makes React skip the synthetic event; the native listener still
|
|
215
|
+
// sees the real one.
|
|
216
|
+
stubPointer(true);
|
|
217
|
+
const onChange = vi.fn();
|
|
218
|
+
render(<DateInput label="Date" value="2026-03-21" onChange={onChange} />);
|
|
219
|
+
|
|
220
|
+
const input = getInput();
|
|
221
|
+
input.value = '2026-03-09';
|
|
222
|
+
input.dispatchEvent(new Event('input', {bubbles: true}));
|
|
223
|
+
|
|
224
|
+
expect(onChange).toHaveBeenCalledExactlyOnceWith('2026-03-09');
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
it('fires one change when both commit paths see the same edit', () => {
|
|
228
|
+
stubPointer(true);
|
|
229
|
+
const onChange = vi.fn();
|
|
230
|
+
render(<DateInput label="Date" value="2026-03-21" onChange={onChange} />);
|
|
231
|
+
|
|
232
|
+
fireEvent.change(getInput(), {target: {value: '2026-03-09'}});
|
|
233
|
+
|
|
234
|
+
expect(onChange).toHaveBeenCalledExactlyOnceWith('2026-03-09');
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
it('does not write to the control while it has focus', () => {
|
|
238
|
+
// The iOS bug this guards: while the picker sheet is open, ANY
|
|
239
|
+
// programmatic write to the field detaches the sheet from it, and the
|
|
240
|
+
// user's pick silently stops reaching the input.
|
|
241
|
+
stubPointer(true);
|
|
242
|
+
const {rerender} = render(
|
|
243
|
+
<DateInput label="Date" value="2026-03-21" onChange={() => {}} />,
|
|
244
|
+
);
|
|
245
|
+
const input = getInput();
|
|
246
|
+
|
|
247
|
+
fireEvent.focus(input);
|
|
248
|
+
rerender(<DateInput label="Date" value="2026-12-25" onChange={() => {}} />);
|
|
249
|
+
|
|
250
|
+
expect(input).toHaveValue('2026-03-21');
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
it('applies an external value once the control loses focus', () => {
|
|
254
|
+
stubPointer(true);
|
|
255
|
+
const {rerender} = render(
|
|
256
|
+
<DateInput label="Date" value="2026-03-21" onChange={() => {}} />,
|
|
257
|
+
);
|
|
258
|
+
const input = getInput();
|
|
259
|
+
|
|
260
|
+
fireEvent.focus(input);
|
|
261
|
+
rerender(<DateInput label="Date" value="2026-12-25" onChange={() => {}} />);
|
|
262
|
+
fireEvent.blur(input);
|
|
263
|
+
|
|
264
|
+
expect(input).toHaveValue('2026-12-25');
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
// ===========================================================================
|
|
268
|
+
// Constraints
|
|
269
|
+
// ===========================================================================
|
|
270
|
+
|
|
271
|
+
it('forwards min and max to the native control', () => {
|
|
272
|
+
stubPointer(true);
|
|
273
|
+
render(
|
|
274
|
+
<DateInput
|
|
275
|
+
label="Date"
|
|
276
|
+
min="2026-01-01"
|
|
277
|
+
max="2026-12-31"
|
|
278
|
+
onChange={() => {}}
|
|
279
|
+
/>,
|
|
280
|
+
);
|
|
281
|
+
|
|
282
|
+
const input = getInput();
|
|
283
|
+
expect(input).toHaveAttribute('min', '2026-01-01');
|
|
284
|
+
expect(input).toHaveAttribute('max', '2026-12-31');
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
it('refuses an out-of-range date and announces it', () => {
|
|
288
|
+
// iOS does not enforce min/max in its picker — it lets the user land on
|
|
289
|
+
// any date — so the refusal has to happen here.
|
|
290
|
+
stubPointer(true);
|
|
291
|
+
const onChange = vi.fn();
|
|
292
|
+
render(
|
|
293
|
+
<DateInput
|
|
294
|
+
label="Date"
|
|
295
|
+
min="2026-03-10"
|
|
296
|
+
max="2026-03-20"
|
|
297
|
+
value="2026-03-15"
|
|
298
|
+
onChange={onChange}
|
|
299
|
+
/>,
|
|
300
|
+
);
|
|
301
|
+
|
|
302
|
+
fireEvent.change(getInput(), {target: {value: '2026-03-25'}});
|
|
303
|
+
|
|
304
|
+
expect(onChange).not.toHaveBeenCalled();
|
|
305
|
+
expect(screen.getByRole('alert')).toHaveTextContent('Invalid date');
|
|
306
|
+
expect(getInput()).toHaveAttribute('aria-invalid', 'true');
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
it('refuses a date dateConstraints rejects', () => {
|
|
310
|
+
stubPointer(true);
|
|
311
|
+
const onChange = vi.fn();
|
|
312
|
+
render(
|
|
313
|
+
<DateInput
|
|
314
|
+
label="Date"
|
|
315
|
+
// 2026-03-22 is a Sunday.
|
|
316
|
+
dateConstraints={[date => date.getDay() !== 0]}
|
|
317
|
+
value="2026-03-23"
|
|
318
|
+
onChange={onChange}
|
|
319
|
+
/>,
|
|
320
|
+
);
|
|
321
|
+
|
|
322
|
+
fireEvent.change(getInput(), {target: {value: '2026-03-22'}});
|
|
323
|
+
|
|
324
|
+
expect(onChange).not.toHaveBeenCalled();
|
|
325
|
+
expect(screen.getByRole('alert')).toHaveTextContent('Invalid date');
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
it('drops the rejection once the field reverts', () => {
|
|
329
|
+
// The refused date is reverted the moment focus leaves, so the field is
|
|
330
|
+
// showing a valid date again. Marking that date invalid would be a lie
|
|
331
|
+
// about data the user never chose.
|
|
332
|
+
stubPointer(true);
|
|
333
|
+
render(
|
|
334
|
+
<DateInput
|
|
335
|
+
label="Date"
|
|
336
|
+
dateConstraints={[date => date.getDay() !== 0]}
|
|
337
|
+
value="2026-03-23"
|
|
338
|
+
onChange={() => {}}
|
|
339
|
+
/>,
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
const input = getInput();
|
|
343
|
+
fireEvent.focus(input);
|
|
344
|
+
fireEvent.change(input, {target: {value: '2026-03-22'}});
|
|
345
|
+
expect(input).toHaveAttribute('aria-invalid', 'true');
|
|
346
|
+
|
|
347
|
+
fireEvent.blur(input);
|
|
348
|
+
|
|
349
|
+
expect(input).toHaveValue('2026-03-23');
|
|
350
|
+
expect(input).not.toHaveAttribute('aria-invalid');
|
|
351
|
+
expect(screen.getByRole('alert')).toHaveTextContent('');
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
// ===========================================================================
|
|
355
|
+
// The text overlay: format, placeholder, paint
|
|
356
|
+
// ===========================================================================
|
|
357
|
+
|
|
358
|
+
it('honours every named format', () => {
|
|
359
|
+
stubPointer(true);
|
|
360
|
+
const {rerender} = render(
|
|
361
|
+
<DateInput
|
|
362
|
+
label="Date"
|
|
363
|
+
value="2026-01-25"
|
|
364
|
+
format="date"
|
|
365
|
+
onChange={() => {}}
|
|
366
|
+
/>,
|
|
367
|
+
);
|
|
368
|
+
expect(screen.getByText('Jan 25, 2026')).toBeInTheDocument();
|
|
369
|
+
|
|
370
|
+
rerender(
|
|
371
|
+
<DateInput
|
|
372
|
+
label="Date"
|
|
373
|
+
value="2026-01-25"
|
|
374
|
+
format="date_weekday"
|
|
375
|
+
onChange={() => {}}
|
|
376
|
+
/>,
|
|
377
|
+
);
|
|
378
|
+
expect(screen.getByText('Sun, Jan 25, 2026')).toBeInTheDocument();
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
it('honours a function format', () => {
|
|
382
|
+
stubPointer(true);
|
|
383
|
+
render(
|
|
384
|
+
<DateInput
|
|
385
|
+
label="Date"
|
|
386
|
+
value="2026-01-25"
|
|
387
|
+
format={iso => `ships ${iso}`}
|
|
388
|
+
onChange={() => {}}
|
|
389
|
+
/>,
|
|
390
|
+
);
|
|
391
|
+
|
|
392
|
+
expect(screen.getByText('ships 2026-01-25')).toBeInTheDocument();
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
it('formats in the provider locale', () => {
|
|
396
|
+
stubPointer(true);
|
|
397
|
+
render(
|
|
398
|
+
<InternationalizationProvider locale="de-DE">
|
|
399
|
+
<DateInput label="Date" value="2026-03-21" onChange={() => {}} />
|
|
400
|
+
</InternationalizationProvider>,
|
|
401
|
+
);
|
|
402
|
+
|
|
403
|
+
expect(screen.getByText('21. März 2026')).toBeInTheDocument();
|
|
404
|
+
expect(getInput()).toHaveValue('2026-03-21');
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
it('keeps painting the value while the picker is open', () => {
|
|
408
|
+
// The OS picker has no segments to reveal, so `format` holds throughout.
|
|
409
|
+
stubPointer(true);
|
|
410
|
+
render(<DateInput label="Date" value="2026-01-25" onChange={() => {}} />);
|
|
411
|
+
|
|
412
|
+
fireEvent.focus(getInput());
|
|
413
|
+
|
|
414
|
+
expect(screen.getByText('January 25, 2026')).toBeInTheDocument();
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
it('shows the placeholder when empty, and drops it when filled', () => {
|
|
418
|
+
stubPointer(true);
|
|
419
|
+
const {rerender} = render(<DateInput label="Date" onChange={() => {}} />);
|
|
420
|
+
expect(screen.getByText('Select a date')).toBeInTheDocument();
|
|
421
|
+
|
|
422
|
+
rerender(<DateInput label="Date" value="2026-01-25" onChange={() => {}} />);
|
|
423
|
+
|
|
424
|
+
expect(screen.queryByText('Select a date')).toBeNull();
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
it('keeps the overlay out of the accessibility tree', () => {
|
|
428
|
+
// The input still holds the value and carries the label, so announcing
|
|
429
|
+
// the overlay too would double-speak.
|
|
430
|
+
stubPointer(true);
|
|
431
|
+
render(<DateInput label="Date" value="2026-01-25" onChange={() => {}} />);
|
|
432
|
+
|
|
433
|
+
expect(screen.getByText('January 25, 2026')).toHaveAttribute(
|
|
434
|
+
'aria-hidden',
|
|
435
|
+
'true',
|
|
436
|
+
);
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
it('hides the engine\u2019s own text under the overlay', () => {
|
|
440
|
+
stubPointer(true);
|
|
441
|
+
render(<DateInput label="Date" value="2026-01-25" onChange={() => {}} />);
|
|
442
|
+
|
|
443
|
+
const rules = rulesFor(getInput());
|
|
444
|
+
// One transparent colour covers Chromium's `::-webkit-datetime-edit` and
|
|
445
|
+
// Firefox's plain text; `-webkit-text-fill-color` is what wins in WebKit.
|
|
446
|
+
expect(rules).toContain('color: transparent');
|
|
447
|
+
expect(rules).toContain('-webkit-text-fill-color: transparent');
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
it('bounds the overlay so a long date cannot paint past it', () => {
|
|
451
|
+
stubPointer(true);
|
|
452
|
+
render(
|
|
453
|
+
<DateInput
|
|
454
|
+
label="Date"
|
|
455
|
+
value="2026-09-30"
|
|
456
|
+
hasClear
|
|
457
|
+
onChange={() => {}}
|
|
458
|
+
/>,
|
|
459
|
+
);
|
|
460
|
+
|
|
461
|
+
const rules = rulesFor(screen.getByText('September 30, 2026'));
|
|
462
|
+
// Without the end inset the overlay is shrink-to-fit and a long date runs
|
|
463
|
+
// over the clear button — measured 24px across it on an iPhone.
|
|
464
|
+
expect(rules).toContain('inset-inline-end: 0');
|
|
465
|
+
// `text-overflow` only applies to a BLOCK container: on a flex one a
|
|
466
|
+
// too-long date hard-clips mid-glyph instead (measured identical to
|
|
467
|
+
// `text-overflow: clip` in WebKit and Chromium). Centring then comes from
|
|
468
|
+
// the line box, so the overlay must carry the input's own leading.
|
|
469
|
+
expect(rules).toContain('display: block');
|
|
470
|
+
expect(rules).toContain('text-overflow: ellipsis');
|
|
471
|
+
expect(rules).toContain('line-height: var(--text-body-leading)');
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
// ===========================================================================
|
|
475
|
+
// Toggle, clear, disabled
|
|
476
|
+
// ===========================================================================
|
|
477
|
+
|
|
478
|
+
it('asks the browser for its picker from the toggle button', () => {
|
|
479
|
+
stubPointer(true);
|
|
480
|
+
render(<DateInput label="Date" onChange={() => {}} />);
|
|
481
|
+
|
|
482
|
+
const input = getInput();
|
|
483
|
+
const showPicker = vi.fn();
|
|
484
|
+
// jsdom implements no picker; attach one so the call is observable.
|
|
485
|
+
(input as HTMLInputElement & {showPicker: () => void}).showPicker =
|
|
486
|
+
showPicker;
|
|
487
|
+
|
|
488
|
+
fireEvent.click(screen.getByLabelText('Open calendar'));
|
|
489
|
+
|
|
490
|
+
expect(showPicker).toHaveBeenCalledTimes(1);
|
|
491
|
+
expect(input).toHaveFocus();
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
it('survives a browser that refuses showPicker', () => {
|
|
495
|
+
// Chrome throws NotAllowedError without transient user activation, and
|
|
496
|
+
// iOS implements no showPicker for type=date at all. Focus is the
|
|
497
|
+
// fallback, and on iOS it is the whole mechanism.
|
|
498
|
+
stubPointer(true);
|
|
499
|
+
render(<DateInput label="Date" onChange={() => {}} />);
|
|
500
|
+
|
|
501
|
+
const input = getInput();
|
|
502
|
+
(input as HTMLInputElement & {showPicker: () => void}).showPicker = () => {
|
|
503
|
+
throw new DOMException('not allowed', 'NotAllowedError');
|
|
504
|
+
};
|
|
505
|
+
|
|
506
|
+
expect(() =>
|
|
507
|
+
fireEvent.click(screen.getByLabelText('Open calendar')),
|
|
508
|
+
).not.toThrow();
|
|
509
|
+
expect(input).toHaveFocus();
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
it('clears the value without taking focus back', () => {
|
|
513
|
+
// Focusing a date control is what raises the OS picker, so reclaiming
|
|
514
|
+
// focus would pop the wheel the clear tap just dismissed.
|
|
515
|
+
stubPointer(true);
|
|
516
|
+
const onChange = vi.fn();
|
|
517
|
+
render(
|
|
518
|
+
<DateInput
|
|
519
|
+
label="Date"
|
|
520
|
+
value="2026-03-21"
|
|
521
|
+
hasClear
|
|
522
|
+
onChange={onChange}
|
|
523
|
+
/>,
|
|
524
|
+
);
|
|
525
|
+
|
|
526
|
+
fireEvent.click(screen.getByLabelText('Clear Date'));
|
|
527
|
+
|
|
528
|
+
expect(onChange).toHaveBeenCalledWith(undefined);
|
|
529
|
+
expect(getInput()).not.toHaveFocus();
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
it('disables the control and its toggle when isDisabled', () => {
|
|
533
|
+
stubPointer(true);
|
|
534
|
+
render(<DateInput label="Date" isDisabled onChange={() => {}} />);
|
|
535
|
+
|
|
536
|
+
expect(getInput()).toBeDisabled();
|
|
537
|
+
expect(screen.getByLabelText('Open calendar')).toBeDisabled();
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
it('ignores a change while disabled', () => {
|
|
541
|
+
stubPointer(true);
|
|
542
|
+
const onChange = vi.fn();
|
|
543
|
+
render(
|
|
544
|
+
<DateInput
|
|
545
|
+
label="Date"
|
|
546
|
+
isDisabled
|
|
547
|
+
disabledMessage="Ask an editor"
|
|
548
|
+
onChange={onChange}
|
|
549
|
+
/>,
|
|
550
|
+
);
|
|
551
|
+
|
|
552
|
+
// With a disabledMessage the field stays focusable via aria-disabled, so
|
|
553
|
+
// the mutation guard is what has to hold.
|
|
554
|
+
fireEvent.change(getInput(), {target: {value: '2026-03-21'}});
|
|
555
|
+
|
|
556
|
+
expect(onChange).not.toHaveBeenCalled();
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
it('keeps the field labelled, required-marked, and ref-forwarded', () => {
|
|
560
|
+
stubPointer(true);
|
|
561
|
+
const ref = vi.fn();
|
|
562
|
+
render(
|
|
563
|
+
<DateInput ref={ref} label="Event date" isRequired onChange={() => {}} />,
|
|
564
|
+
);
|
|
565
|
+
|
|
566
|
+
const input = screen.getByLabelText(/Event date/);
|
|
567
|
+
expect(input).toHaveAttribute('type', 'date');
|
|
568
|
+
expect(input).toHaveAttribute('aria-required', 'true');
|
|
569
|
+
expect(ref).toHaveBeenCalledWith(expect.any(HTMLInputElement));
|
|
570
|
+
});
|
|
571
|
+
|
|
572
|
+
// ===========================================================================
|
|
573
|
+
// Engines that draw editable segments
|
|
574
|
+
//
|
|
575
|
+
// Chrome's touch simulator, a Windows tablet and a ChromeOS convertible all
|
|
576
|
+
// render `<input type="date">` as typable fields while reporting a coarse
|
|
577
|
+
// pointer. See ./nativeDateSegments.
|
|
578
|
+
// ===========================================================================
|
|
579
|
+
|
|
580
|
+
it('reveals the engine’s own segments while an editable control has focus', () => {
|
|
581
|
+
// Measured in Chrome: with the overlay up, typing paints nothing but a
|
|
582
|
+
// selection highlight drifting across the placeholder.
|
|
583
|
+
segmentState.editable = true;
|
|
584
|
+
stubPointer(true);
|
|
585
|
+
render(<DateInput label="Date" value="2026-01-25" onChange={() => {}} />);
|
|
586
|
+
|
|
587
|
+
expect(screen.getByText('January 25, 2026')).toBeInTheDocument();
|
|
588
|
+
|
|
589
|
+
fireEvent.focus(getInput());
|
|
590
|
+
|
|
591
|
+
expect(screen.queryByText('January 25, 2026')).toBeNull();
|
|
592
|
+
// `-webkit-text-fill-color` is what wins inside a date control, and
|
|
593
|
+
// unlike a bare `color:` cannot be confused with the wrapper's
|
|
594
|
+
// `background-color: transparent`.
|
|
595
|
+
expect(rulesFor(getInput())).not.toContain(
|
|
596
|
+
'-webkit-text-fill-color: transparent',
|
|
597
|
+
);
|
|
598
|
+
});
|
|
599
|
+
|
|
600
|
+
it('paints the formatted date again once the segments lose focus', () => {
|
|
601
|
+
segmentState.editable = true;
|
|
602
|
+
stubPointer(true);
|
|
603
|
+
render(<DateInput label="Date" value="2026-01-25" onChange={() => {}} />);
|
|
604
|
+
|
|
605
|
+
fireEvent.focus(getInput());
|
|
606
|
+
fireEvent.blur(getInput());
|
|
607
|
+
|
|
608
|
+
expect(screen.getByText('January 25, 2026')).toBeInTheDocument();
|
|
609
|
+
expect(rulesFor(getInput())).toContain(
|
|
610
|
+
'-webkit-text-fill-color: transparent',
|
|
611
|
+
);
|
|
612
|
+
});
|
|
613
|
+
|
|
614
|
+
it('stands aside for the engine’s placeholder while empty and focused', () => {
|
|
615
|
+
// `mm/dd/yyyy` says which order to type in, which ours cannot.
|
|
616
|
+
segmentState.editable = true;
|
|
617
|
+
stubPointer(true);
|
|
618
|
+
render(<DateInput label="Date" onChange={() => {}} />);
|
|
619
|
+
|
|
620
|
+
expect(screen.getByText('Select a date')).toBeInTheDocument();
|
|
621
|
+
|
|
622
|
+
fireEvent.focus(getInput());
|
|
623
|
+
|
|
624
|
+
expect(screen.queryByText('Select a date')).toBeNull();
|
|
625
|
+
});
|
|
626
|
+
|
|
627
|
+
it('resolves an unprobeable engine with the pointer', () => {
|
|
628
|
+
// jsdom lays nothing out, so neither pseudo can be measured — the same
|
|
629
|
+
// answer Firefox gives, which exposes neither.
|
|
630
|
+
resetDateSegmentProbe();
|
|
631
|
+
|
|
632
|
+
expect(hasEditableDateSegments(true)).toBe(false);
|
|
633
|
+
expect(hasEditableDateSegments(false)).toBe(true);
|
|
634
|
+
});
|
|
635
|
+
});
|