@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
|
@@ -12,11 +12,20 @@
|
|
|
12
12
|
import {describe, it, expect, vi, afterEach} from 'vitest';
|
|
13
13
|
import {render, act, fireEvent, waitFor} from '@testing-library/react';
|
|
14
14
|
import userEvent from '@testing-library/user-event';
|
|
15
|
-
import
|
|
15
|
+
import * as stylex from '@stylexjs/stylex';
|
|
16
|
+
import {
|
|
17
|
+
useKeepLayerOpenProps,
|
|
18
|
+
useLayer,
|
|
19
|
+
useLayerInternal,
|
|
20
|
+
getPositionTryFallbacks,
|
|
21
|
+
} from './useLayer';
|
|
22
|
+
import {typeScaleVars} from '../theme/tokens.stylex';
|
|
16
23
|
import type {
|
|
17
24
|
LayerPlacement,
|
|
18
25
|
LayerAlignment,
|
|
19
26
|
ContextRenderProps,
|
|
27
|
+
ContextLayerReturn,
|
|
28
|
+
FixedLayerReturn,
|
|
20
29
|
} from './useLayer';
|
|
21
30
|
|
|
22
31
|
function mockCSSStyleDeclaration(
|
|
@@ -500,20 +509,6 @@ describe('useLayer', () => {
|
|
|
500
509
|
});
|
|
501
510
|
|
|
502
511
|
describe('when the Popover API is supported', () => {
|
|
503
|
-
it('declares body type instead of inheriting the host context', () => {
|
|
504
|
-
const {container} = render(
|
|
505
|
-
<div style={{fontSize: '30px', lineHeight: '3'}}>
|
|
506
|
-
<LayerHarness onReady={() => {}} />
|
|
507
|
-
</div>,
|
|
508
|
-
);
|
|
509
|
-
|
|
510
|
-
const layer = container.querySelector('[popover]') as HTMLElement;
|
|
511
|
-
expect(layer).toHaveStyle({
|
|
512
|
-
fontSize: 'var(--text-body-size)',
|
|
513
|
-
lineHeight: 'var(--text-body-leading)',
|
|
514
|
-
});
|
|
515
|
-
});
|
|
516
|
-
|
|
517
512
|
it('calls showPopover/hidePopover on show/hide', () => {
|
|
518
513
|
const showSpy = vi.fn();
|
|
519
514
|
const hideSpy = vi.fn();
|
|
@@ -614,6 +609,66 @@ async function openAndGetStyle(ui: React.ReactElement): Promise<string> {
|
|
|
614
609
|
return popover?.getAttribute('style') ?? '';
|
|
615
610
|
}
|
|
616
611
|
|
|
612
|
+
describe('typography baseline', () => {
|
|
613
|
+
const overrideStyles = stylex.create({
|
|
614
|
+
supporting: {fontSize: typeScaleVars['--text-supporting-size']},
|
|
615
|
+
});
|
|
616
|
+
|
|
617
|
+
function TypographyHarness({
|
|
618
|
+
ambientFontSize,
|
|
619
|
+
xstyle,
|
|
620
|
+
}: {
|
|
621
|
+
ambientFontSize: string;
|
|
622
|
+
xstyle?: ContextRenderProps['xstyle'];
|
|
623
|
+
}) {
|
|
624
|
+
const layer = useLayer({mode: 'context'});
|
|
625
|
+
return (
|
|
626
|
+
<div style={{fontSize: ambientFontSize, lineHeight: '3'}}>
|
|
627
|
+
<button type="button" ref={layer.ref} onClick={layer.show}>
|
|
628
|
+
trigger
|
|
629
|
+
</button>
|
|
630
|
+
{layer.render(<span>content</span>, {xstyle})}
|
|
631
|
+
</div>
|
|
632
|
+
);
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
async function openAndGetType(ui: React.ReactElement) {
|
|
636
|
+
const user = userEvent.setup();
|
|
637
|
+
const {container, getByRole} = render(ui);
|
|
638
|
+
await user.click(getByRole('button', {name: 'trigger'}));
|
|
639
|
+
const el = container.querySelector('[popover]') as HTMLElement;
|
|
640
|
+
const computed = window.getComputedStyle(el);
|
|
641
|
+
return {fontSize: computed.fontSize, lineHeight: computed.lineHeight};
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
// jsdom resolves no var() indirection, so the token reference is what the
|
|
645
|
+
// assertion can see — the point is that a declaration exists at all, since
|
|
646
|
+
// an absent one is exactly what let the ambient size through.
|
|
647
|
+
it.each(['13px', '20px'])(
|
|
648
|
+
'takes the body role rather than the surrounding %s',
|
|
649
|
+
async ambientFontSize => {
|
|
650
|
+
expect(
|
|
651
|
+
await openAndGetType(
|
|
652
|
+
<TypographyHarness ambientFontSize={ambientFontSize} />,
|
|
653
|
+
),
|
|
654
|
+
).toEqual({
|
|
655
|
+
fontSize: 'var(--text-body-size)',
|
|
656
|
+
lineHeight: 'var(--text-body-leading)',
|
|
657
|
+
});
|
|
658
|
+
},
|
|
659
|
+
);
|
|
660
|
+
|
|
661
|
+
it('still lets a consumer xstyle set its own size', async () => {
|
|
662
|
+
const {fontSize} = await openAndGetType(
|
|
663
|
+
<TypographyHarness
|
|
664
|
+
ambientFontSize="13px"
|
|
665
|
+
xstyle={overrideStyles.supporting}
|
|
666
|
+
/>,
|
|
667
|
+
);
|
|
668
|
+
expect(fontSize).toBe('var(--text-supporting-size)');
|
|
669
|
+
});
|
|
670
|
+
});
|
|
671
|
+
|
|
617
672
|
describe('useLayer context positioning', () => {
|
|
618
673
|
// The mapping uses the self-* logical keyword family, so the emitted
|
|
619
674
|
// string is direction-independent by construction: the browser resolves
|
|
@@ -873,3 +928,257 @@ describe('useLayer context positioning', () => {
|
|
|
873
928
|
expect(style).not.toContain('position-anchor');
|
|
874
929
|
});
|
|
875
930
|
});
|
|
931
|
+
|
|
932
|
+
describe('useLayer public return types', () => {
|
|
933
|
+
it('keeps dismissal helpers internal', () => {
|
|
934
|
+
const contextHasKeepOpenProps: 'keepOpenProps' extends keyof ContextLayerReturn
|
|
935
|
+
? true
|
|
936
|
+
: false = false;
|
|
937
|
+
const fixedHasKeepOpenProps: 'keepOpenProps' extends keyof FixedLayerReturn
|
|
938
|
+
? true
|
|
939
|
+
: false = false;
|
|
940
|
+
const contextHasGuard: 'wasJustDismissed' extends keyof ContextLayerReturn
|
|
941
|
+
? true
|
|
942
|
+
: false = false;
|
|
943
|
+
const fixedHasGuard: 'wasJustDismissed' extends keyof FixedLayerReturn
|
|
944
|
+
? true
|
|
945
|
+
: false = false;
|
|
946
|
+
|
|
947
|
+
expect(contextHasKeepOpenProps).toBe(false);
|
|
948
|
+
expect(fixedHasKeepOpenProps).toBe(false);
|
|
949
|
+
expect(contextHasGuard).toBe(false);
|
|
950
|
+
expect(fixedHasGuard).toBe(false);
|
|
951
|
+
});
|
|
952
|
+
});
|
|
953
|
+
|
|
954
|
+
describe('internal keep-open props (controls on the trigger, #5004)', () => {
|
|
955
|
+
function ClearableTriggerHarness() {
|
|
956
|
+
const layer = useLayer({mode: 'context'});
|
|
957
|
+
const keepOpenProps = useKeepLayerOpenProps(layer.id, layer.isOpen);
|
|
958
|
+
return (
|
|
959
|
+
<>
|
|
960
|
+
<button type="button" ref={layer.ref} onClick={layer.show}>
|
|
961
|
+
Trigger
|
|
962
|
+
</button>
|
|
963
|
+
<button type="button" {...keepOpenProps}>
|
|
964
|
+
Clear
|
|
965
|
+
</button>
|
|
966
|
+
{layer.render(<span>Layer content</span>, {placement: 'below'})}
|
|
967
|
+
</>
|
|
968
|
+
);
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
it('names the control an invoker for the duration of the press', async () => {
|
|
972
|
+
const user = userEvent.setup();
|
|
973
|
+
const {container, getByRole} = render(<ClearableTriggerHarness />);
|
|
974
|
+
const clear = getByRole('button', {name: 'Clear'});
|
|
975
|
+
|
|
976
|
+
await user.click(getByRole('button', {name: 'Trigger'}));
|
|
977
|
+
const popover = container.querySelector('[popover]') as HTMLElement;
|
|
978
|
+
|
|
979
|
+
await user.pointer({keys: '[MouseLeft>]', target: clear});
|
|
980
|
+
expect(clear.getAttribute('popovertarget')).toBe(popover.id);
|
|
981
|
+
|
|
982
|
+
await user.pointer({keys: '[/MouseLeft]', target: clear});
|
|
983
|
+
expect(clear).not.toHaveAttribute('popovertarget');
|
|
984
|
+
});
|
|
985
|
+
|
|
986
|
+
it('takes the invoker off when the press ends in pointercancel', async () => {
|
|
987
|
+
const user = userEvent.setup();
|
|
988
|
+
const {container, getByRole} = render(<ClearableTriggerHarness />);
|
|
989
|
+
const clear = getByRole('button', {name: 'Clear'});
|
|
990
|
+
|
|
991
|
+
await user.click(getByRole('button', {name: 'Trigger'}));
|
|
992
|
+
const popover = container.querySelector('[popover]') as HTMLElement;
|
|
993
|
+
|
|
994
|
+
await user.pointer({keys: '[MouseLeft>]', target: clear});
|
|
995
|
+
expect(clear.getAttribute('popovertarget')).toBe(popover.id);
|
|
996
|
+
|
|
997
|
+
// A touch the browser claims — for a scroll, for the platform's long-press
|
|
998
|
+
// menu — ends here, and no pointerup ever arrives.
|
|
999
|
+
await act(async () => {
|
|
1000
|
+
document.dispatchEvent(new Event('pointercancel'));
|
|
1001
|
+
await new Promise(resolve => {
|
|
1002
|
+
window.setTimeout(resolve, 0);
|
|
1003
|
+
});
|
|
1004
|
+
});
|
|
1005
|
+
|
|
1006
|
+
expect(clear).not.toHaveAttribute('popovertarget');
|
|
1007
|
+
});
|
|
1008
|
+
|
|
1009
|
+
it('leaves the control alone while the layer is closed', async () => {
|
|
1010
|
+
const user = userEvent.setup();
|
|
1011
|
+
const {getByRole} = render(<ClearableTriggerHarness />);
|
|
1012
|
+
const clear = getByRole('button', {name: 'Clear'});
|
|
1013
|
+
|
|
1014
|
+
await user.click(clear);
|
|
1015
|
+
|
|
1016
|
+
expect(clear).not.toHaveAttribute('popovertarget');
|
|
1017
|
+
});
|
|
1018
|
+
|
|
1019
|
+
it("cancels the invoker's own toggle so the press cannot close the layer", async () => {
|
|
1020
|
+
const user = userEvent.setup();
|
|
1021
|
+
const {container, getByRole} = render(<ClearableTriggerHarness />);
|
|
1022
|
+
await user.click(getByRole('button', {name: 'Trigger'}));
|
|
1023
|
+
const popover = container.querySelector('[popover]') as HTMLElement;
|
|
1024
|
+
const clear = getByRole('button', {name: 'Clear'});
|
|
1025
|
+
|
|
1026
|
+
const click = new MouseEvent('click', {bubbles: true, cancelable: true});
|
|
1027
|
+
await act(async () => {
|
|
1028
|
+
clear.setAttribute('popovertarget', popover.id);
|
|
1029
|
+
clear.dispatchEvent(click);
|
|
1030
|
+
});
|
|
1031
|
+
|
|
1032
|
+
expect(click.defaultPrevented).toBe(true);
|
|
1033
|
+
expect(clear).not.toHaveAttribute('popovertarget');
|
|
1034
|
+
});
|
|
1035
|
+
});
|
|
1036
|
+
|
|
1037
|
+
describe('wasJustDismissed (light dismiss vs. the trigger click, #5004)', () => {
|
|
1038
|
+
function GuardedTriggerHarness() {
|
|
1039
|
+
const layer = useLayerInternal({mode: 'context'});
|
|
1040
|
+
return (
|
|
1041
|
+
<>
|
|
1042
|
+
<button
|
|
1043
|
+
type="button"
|
|
1044
|
+
ref={layer.ref}
|
|
1045
|
+
onClick={() => {
|
|
1046
|
+
if (layer.wasJustDismissed()) {
|
|
1047
|
+
return;
|
|
1048
|
+
}
|
|
1049
|
+
if (layer.isOpen) {
|
|
1050
|
+
layer.hide();
|
|
1051
|
+
} else {
|
|
1052
|
+
layer.show();
|
|
1053
|
+
}
|
|
1054
|
+
}}>
|
|
1055
|
+
Trigger
|
|
1056
|
+
</button>
|
|
1057
|
+
<span data-testid="state">{layer.isOpen ? 'open' : 'closed'}</span>
|
|
1058
|
+
{layer.render(<span>Layer content</span>, {placement: 'below'})}
|
|
1059
|
+
</>
|
|
1060
|
+
);
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
/**
|
|
1064
|
+
* The browser closing the layer itself: it hides the element and queues a
|
|
1065
|
+
* `toggle` event, which is what reaches React — before the click, on the
|
|
1066
|
+
* engines that lose the race.
|
|
1067
|
+
*/
|
|
1068
|
+
function lightDismiss(container: HTMLElement) {
|
|
1069
|
+
const popover = container.querySelector('[popover]') as HTMLElement;
|
|
1070
|
+
act(() => {
|
|
1071
|
+
popover.dispatchEvent(
|
|
1072
|
+
Object.assign(new Event('toggle'), {
|
|
1073
|
+
oldState: 'open',
|
|
1074
|
+
newState: 'closed',
|
|
1075
|
+
}),
|
|
1076
|
+
);
|
|
1077
|
+
});
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
it('absorbs the trigger click that follows a light dismiss', async () => {
|
|
1081
|
+
const user = userEvent.setup();
|
|
1082
|
+
const {container, getByRole, getByTestId} = render(
|
|
1083
|
+
<GuardedTriggerHarness />,
|
|
1084
|
+
);
|
|
1085
|
+
const trigger = getByRole('button', {name: 'Trigger'});
|
|
1086
|
+
|
|
1087
|
+
await user.click(trigger);
|
|
1088
|
+
expect(getByTestId('state')).toHaveTextContent('open');
|
|
1089
|
+
|
|
1090
|
+
// The next press reaches the browser dismissal before its click.
|
|
1091
|
+
fireEvent.pointerDown(trigger);
|
|
1092
|
+
lightDismiss(container);
|
|
1093
|
+
fireEvent.click(trigger);
|
|
1094
|
+
|
|
1095
|
+
expect(getByTestId('state')).toHaveTextContent('closed');
|
|
1096
|
+
});
|
|
1097
|
+
|
|
1098
|
+
it('acts on a deliberate second press', async () => {
|
|
1099
|
+
const user = userEvent.setup();
|
|
1100
|
+
const {container, getByRole, getByTestId} = render(
|
|
1101
|
+
<GuardedTriggerHarness />,
|
|
1102
|
+
);
|
|
1103
|
+
const trigger = getByRole('button', {name: 'Trigger'});
|
|
1104
|
+
|
|
1105
|
+
await user.click(trigger);
|
|
1106
|
+
fireEvent.pointerDown(trigger);
|
|
1107
|
+
lightDismiss(container);
|
|
1108
|
+
fireEvent.click(trigger);
|
|
1109
|
+
// A press of its own — a new gesture, however soon it lands.
|
|
1110
|
+
await user.click(trigger);
|
|
1111
|
+
|
|
1112
|
+
expect(getByTestId('state')).toHaveTextContent('open');
|
|
1113
|
+
});
|
|
1114
|
+
|
|
1115
|
+
it('leaves a programmatic hide unguarded', async () => {
|
|
1116
|
+
const user = userEvent.setup();
|
|
1117
|
+
const {getByRole, getByTestId} = render(<GuardedTriggerHarness />);
|
|
1118
|
+
const trigger = getByRole('button', {name: 'Trigger'});
|
|
1119
|
+
|
|
1120
|
+
// Three presses with no browser-initiated close between them.
|
|
1121
|
+
await user.click(trigger);
|
|
1122
|
+
await user.click(trigger);
|
|
1123
|
+
await user.click(trigger);
|
|
1124
|
+
|
|
1125
|
+
expect(getByTestId('state')).toHaveTextContent('open');
|
|
1126
|
+
});
|
|
1127
|
+
|
|
1128
|
+
it('acts on a synthesized click after a stopped click-first dismissal', async () => {
|
|
1129
|
+
const user = userEvent.setup();
|
|
1130
|
+
const {container, getByRole, getByTestId} = render(
|
|
1131
|
+
<GuardedTriggerHarness />,
|
|
1132
|
+
);
|
|
1133
|
+
const trigger = getByRole('button', {name: 'Trigger'});
|
|
1134
|
+
|
|
1135
|
+
await user.click(trigger);
|
|
1136
|
+
fireEvent.pointerDown(document.body);
|
|
1137
|
+
document.body.addEventListener('click', event => event.stopPropagation(), {
|
|
1138
|
+
once: true,
|
|
1139
|
+
});
|
|
1140
|
+
fireEvent.click(document.body);
|
|
1141
|
+
lightDismiss(container);
|
|
1142
|
+
expect(getByTestId('state')).toHaveTextContent('closed');
|
|
1143
|
+
|
|
1144
|
+
// Chromium delivers the dismissing click before the queued toggle. A later
|
|
1145
|
+
// bare click is a new activation even though it has no pointerdown.
|
|
1146
|
+
act(() => {
|
|
1147
|
+
trigger.click();
|
|
1148
|
+
});
|
|
1149
|
+
|
|
1150
|
+
expect(getByTestId('state')).toHaveTextContent('open');
|
|
1151
|
+
});
|
|
1152
|
+
|
|
1153
|
+
/** A trigger that calls show()/hide() directly, checking nothing. */
|
|
1154
|
+
function PlainTriggerHarness() {
|
|
1155
|
+
const layer = useLayerInternal({mode: 'context'});
|
|
1156
|
+
return (
|
|
1157
|
+
<>
|
|
1158
|
+
<button
|
|
1159
|
+
type="button"
|
|
1160
|
+
ref={layer.ref}
|
|
1161
|
+
onClick={() => (layer.isOpen ? layer.hide() : layer.show())}>
|
|
1162
|
+
Trigger
|
|
1163
|
+
</button>
|
|
1164
|
+
<span data-testid="state">{layer.isOpen ? 'open' : 'closed'}</span>
|
|
1165
|
+
{layer.render(<span>Layer content</span>, {placement: 'below'})}
|
|
1166
|
+
</>
|
|
1167
|
+
);
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
it('absorbs the click for a trigger that never calls wasJustDismissed', async () => {
|
|
1171
|
+
const user = userEvent.setup();
|
|
1172
|
+
const {container, getByRole, getByTestId} = render(<PlainTriggerHarness />);
|
|
1173
|
+
const trigger = getByRole('button', {name: 'Trigger'});
|
|
1174
|
+
|
|
1175
|
+
await user.click(trigger);
|
|
1176
|
+
expect(getByTestId('state')).toHaveTextContent('open');
|
|
1177
|
+
|
|
1178
|
+
fireEvent.pointerDown(trigger);
|
|
1179
|
+
lightDismiss(container);
|
|
1180
|
+
fireEvent.click(trigger);
|
|
1181
|
+
|
|
1182
|
+
expect(getByTestId('state')).toHaveTextContent('closed');
|
|
1183
|
+
});
|
|
1184
|
+
});
|
package/src/Layer/useLayer.tsx
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
/**
|
|
6
6
|
* @file useLayer.tsx
|
|
7
7
|
* @input Uses React hooks, Popover API, CSS anchor positioning, typography tokens
|
|
8
|
-
* @output Exports useLayer hook
|
|
8
|
+
* @output Exports the public useLayer hook plus internal trigger helpers.
|
|
9
9
|
* @position Core layer utility; used by useHoverCard, useTooltip, etc.
|
|
10
10
|
*
|
|
11
11
|
* SYNC: When modified, update:
|
|
@@ -18,6 +18,7 @@ import React, {
|
|
|
18
18
|
useCallback,
|
|
19
19
|
useEffect,
|
|
20
20
|
useId,
|
|
21
|
+
useMemo,
|
|
21
22
|
useRef,
|
|
22
23
|
useState,
|
|
23
24
|
type ReactNode,
|
|
@@ -27,6 +28,7 @@ import * as stylex from '@stylexjs/stylex';
|
|
|
27
28
|
import type {StyleXStyles} from '@stylexjs/stylex';
|
|
28
29
|
import {createPortal} from 'react-dom';
|
|
29
30
|
import {addAnchorName, removeAnchorName} from './anchorName';
|
|
31
|
+
import {currentGesture, currentGestureHasClicked} from './gestureCounter';
|
|
30
32
|
import {resolveLayerPortalTarget} from './layerHost';
|
|
31
33
|
import {typeScaleVars, typographyVars} from '../theme/tokens.stylex';
|
|
32
34
|
import {overlayPaddingReset} from '../Layout/padding.stylex';
|
|
@@ -72,6 +74,18 @@ const styles = stylex.create({
|
|
|
72
74
|
}),
|
|
73
75
|
});
|
|
74
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Props for a control that sits on the trigger but must not dismiss the layer.
|
|
79
|
+
*/
|
|
80
|
+
interface KeepLayerOpenProps {
|
|
81
|
+
onPointerDown: React.PointerEventHandler<HTMLElement>;
|
|
82
|
+
/**
|
|
83
|
+
* Capture phase, so spreading these props never collides with the control's
|
|
84
|
+
* own `onClick`.
|
|
85
|
+
*/
|
|
86
|
+
onClickCapture: React.MouseEventHandler<HTMLElement>;
|
|
87
|
+
}
|
|
88
|
+
|
|
75
89
|
/**
|
|
76
90
|
* Position placement relative to anchor.
|
|
77
91
|
* Logical: start/end resolve against the popover's own inherited direction
|
|
@@ -326,6 +340,13 @@ export interface FixedLayerReturn {
|
|
|
326
340
|
render: (children: ReactNode, props: FixedRenderProps) => ReactNode;
|
|
327
341
|
}
|
|
328
342
|
|
|
343
|
+
interface InternalLayerFields {
|
|
344
|
+
wasJustDismissed: () => boolean;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
type InternalContextLayerReturn = ContextLayerReturn & InternalLayerFields;
|
|
348
|
+
type InternalFixedLayerReturn = FixedLayerReturn & InternalLayerFields;
|
|
349
|
+
|
|
329
350
|
function toCssLength(value: number | string): string {
|
|
330
351
|
return typeof value === 'number' ? `${value}px` : value;
|
|
331
352
|
}
|
|
@@ -437,6 +458,51 @@ export function getPositionTryFallbacks(
|
|
|
437
458
|
return `${flips}, ${same} span-top, ${same} span-bottom, ${opposite} span-top, ${opposite} span-bottom`;
|
|
438
459
|
}
|
|
439
460
|
|
|
461
|
+
/**
|
|
462
|
+
* Internal props for controls that sit beside an open layer. This stays out of
|
|
463
|
+
* the public useLayer/usePopover return types until the input family adopts it.
|
|
464
|
+
*/
|
|
465
|
+
export function useKeepLayerOpenProps(
|
|
466
|
+
id: string,
|
|
467
|
+
isOpen: boolean,
|
|
468
|
+
): KeepLayerOpenProps {
|
|
469
|
+
const isOpenRef = useRef(isOpen);
|
|
470
|
+
isOpenRef.current = isOpen;
|
|
471
|
+
|
|
472
|
+
return useMemo(
|
|
473
|
+
() => ({
|
|
474
|
+
onPointerDown: (event: React.PointerEvent<HTMLElement>) => {
|
|
475
|
+
if (!isOpenRef.current) {
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
// The browser reads the invoker relationship at both ends of the press.
|
|
479
|
+
const control = event.currentTarget;
|
|
480
|
+
const doc = control.ownerDocument;
|
|
481
|
+
control.setAttribute('popovertarget', id);
|
|
482
|
+
const onPressEnd = () => {
|
|
483
|
+
doc.removeEventListener('pointerup', onPressEnd);
|
|
484
|
+
doc.removeEventListener('pointercancel', onPressEnd);
|
|
485
|
+
// Light dismiss runs as the pointerup default action after listeners.
|
|
486
|
+
doc.defaultView?.setTimeout(() => {
|
|
487
|
+
control.removeAttribute('popovertarget');
|
|
488
|
+
}, 0);
|
|
489
|
+
};
|
|
490
|
+
doc.addEventListener('pointerup', onPressEnd);
|
|
491
|
+
doc.addEventListener('pointercancel', onPressEnd);
|
|
492
|
+
},
|
|
493
|
+
onClickCapture: (event: React.MouseEvent<HTMLElement>) => {
|
|
494
|
+
const control = event.currentTarget;
|
|
495
|
+
if (control.hasAttribute('popovertarget')) {
|
|
496
|
+
// Being an invoker would otherwise toggle the layer shut.
|
|
497
|
+
event.preventDefault();
|
|
498
|
+
control.removeAttribute('popovertarget');
|
|
499
|
+
}
|
|
500
|
+
},
|
|
501
|
+
}),
|
|
502
|
+
[id],
|
|
503
|
+
);
|
|
504
|
+
}
|
|
505
|
+
|
|
440
506
|
/**
|
|
441
507
|
* Core layer hook that handles popover behavior and positioning.
|
|
442
508
|
*
|
|
@@ -451,11 +517,9 @@ export function getPositionTryFallbacks(
|
|
|
451
517
|
* {layer.render(<Content />, { placement: 'above', alignment: 'center' })}
|
|
452
518
|
* ```
|
|
453
519
|
*/
|
|
454
|
-
|
|
455
|
-
export function useLayer(options: FixedLayerOptions): FixedLayerReturn;
|
|
456
|
-
export function useLayer(
|
|
520
|
+
function useLayerImplementation(
|
|
457
521
|
options: ContextLayerOptions | FixedLayerOptions,
|
|
458
|
-
):
|
|
522
|
+
): InternalContextLayerReturn | InternalFixedLayerReturn {
|
|
459
523
|
const {mode, onShow, onHide, lightDismiss = false} = options;
|
|
460
524
|
const lazyMount = mode === 'context' ? (options.lazyMount ?? false) : false;
|
|
461
525
|
const id = useId();
|
|
@@ -485,6 +549,17 @@ export function useLayer(
|
|
|
485
549
|
// stale-closure reads of the previous isOpen value.
|
|
486
550
|
const isOpenRef = useRef(false);
|
|
487
551
|
|
|
552
|
+
// The gesture during which the browser last closed this layer on its own.
|
|
553
|
+
// Read through wasJustDismissed by triggers deciding whether a click is
|
|
554
|
+
// theirs to act on.
|
|
555
|
+
const dismissedByGestureRef = useRef<number | null>(null);
|
|
556
|
+
const forgetDismissalRef = useRef<(() => void) | null>(null);
|
|
557
|
+
|
|
558
|
+
const wasJustDismissed = useCallback(() => {
|
|
559
|
+
const gesture = currentGesture();
|
|
560
|
+
return dismissedByGestureRef.current === gesture;
|
|
561
|
+
}, []);
|
|
562
|
+
|
|
488
563
|
const showPopoverElement = useCallback((popover: HTMLElement) => {
|
|
489
564
|
// Finding infra-4: the Popover API is unsupported on Safari <17 and
|
|
490
565
|
// Firefox <125. On those browsers `showPopover` does not exist, so fall
|
|
@@ -548,6 +623,11 @@ export function useLayer(
|
|
|
548
623
|
}, [mode, lazyMount]);
|
|
549
624
|
|
|
550
625
|
const show = useCallback(() => {
|
|
626
|
+
// Every caller lands here, so this is where the dismissing press is
|
|
627
|
+
// absorbed: opening now would reopen the popup that same press closed.
|
|
628
|
+
if (wasJustDismissed()) {
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
551
631
|
// A context popover left over until React commits a previous hide must not
|
|
552
632
|
// be reopened. The synchronous mount ref is the source of truth.
|
|
553
633
|
const candidate = popoverRef.current;
|
|
@@ -569,12 +649,18 @@ export function useLayer(
|
|
|
569
649
|
requestContextMount,
|
|
570
650
|
showPopoverElement,
|
|
571
651
|
isCurrentContextPopover,
|
|
652
|
+
wasJustDismissed,
|
|
572
653
|
]);
|
|
573
654
|
|
|
574
655
|
const hide = useCallback(() => {
|
|
575
656
|
pendingShowRef.current = false;
|
|
576
657
|
if (isOpenRef.current) {
|
|
577
658
|
const el = popoverRef.current;
|
|
659
|
+
// Clear the open state BEFORE hiding: hidePopover fires `toggle`, and
|
|
660
|
+
// the reconciler below reads this ref to tell the browser's own
|
|
661
|
+
// dismissals from ours.
|
|
662
|
+
openedPopoverRef.current = null;
|
|
663
|
+
isOpenRef.current = false;
|
|
578
664
|
// See finding infra-4 note in `show`: mirror the same guard on hide so
|
|
579
665
|
// unsupported browsers degrade gracefully instead of throwing.
|
|
580
666
|
if (el) {
|
|
@@ -584,8 +670,6 @@ export function useLayer(
|
|
|
584
670
|
el.style.display = 'none';
|
|
585
671
|
}
|
|
586
672
|
}
|
|
587
|
-
openedPopoverRef.current = null;
|
|
588
|
-
isOpenRef.current = false;
|
|
589
673
|
setIsOpen(false);
|
|
590
674
|
onHide?.();
|
|
591
675
|
}
|
|
@@ -610,6 +694,51 @@ export function useLayer(
|
|
|
610
694
|
}
|
|
611
695
|
: undefined;
|
|
612
696
|
|
|
697
|
+
// Arm only when the dismissing gesture's click is still ahead of us. Some
|
|
698
|
+
// engines deliver click first; in that order there is nothing left to absorb.
|
|
699
|
+
const rememberDismissal = useCallback((doc: Document) => {
|
|
700
|
+
forgetDismissalRef.current?.();
|
|
701
|
+
if (currentGestureHasClicked()) {
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
704
|
+
dismissedByGestureRef.current = currentGesture();
|
|
705
|
+
const view = doc.defaultView;
|
|
706
|
+
let forgetTimer: number | null = null;
|
|
707
|
+
const forget = () => {
|
|
708
|
+
dismissedByGestureRef.current = null;
|
|
709
|
+
doc.removeEventListener('click', scheduleForget, true);
|
|
710
|
+
if (forgetTimer !== null) {
|
|
711
|
+
view?.clearTimeout(forgetTimer);
|
|
712
|
+
forgetTimer = null;
|
|
713
|
+
}
|
|
714
|
+
if (forgetDismissalRef.current === forget) {
|
|
715
|
+
forgetDismissalRef.current = null;
|
|
716
|
+
}
|
|
717
|
+
};
|
|
718
|
+
const scheduleForget = () => {
|
|
719
|
+
doc.removeEventListener('click', scheduleForget, true);
|
|
720
|
+
// The next task keeps the dismissal armed through React's click handler.
|
|
721
|
+
if (view) {
|
|
722
|
+
forgetTimer = view.setTimeout(() => {
|
|
723
|
+
forgetTimer = null;
|
|
724
|
+
if (forgetDismissalRef.current === forget) {
|
|
725
|
+
forget();
|
|
726
|
+
}
|
|
727
|
+
}, 0);
|
|
728
|
+
} else {
|
|
729
|
+
forget();
|
|
730
|
+
}
|
|
731
|
+
};
|
|
732
|
+
doc.addEventListener('click', scheduleForget, true);
|
|
733
|
+
forgetDismissalRef.current = forget;
|
|
734
|
+
}, []);
|
|
735
|
+
|
|
736
|
+
useEffect(() => {
|
|
737
|
+
// Install capture-phase gesture tracking before the first interaction.
|
|
738
|
+
currentGesture();
|
|
739
|
+
return () => forgetDismissalRef.current?.();
|
|
740
|
+
}, []);
|
|
741
|
+
|
|
613
742
|
// Reconcile browser-initiated closes (light-dismiss, popover="auto" stack
|
|
614
743
|
// eviction). These are the only cases where the DOM mutates without going
|
|
615
744
|
// through our show/hide — we sync React state back to match.
|
|
@@ -626,12 +755,15 @@ export function useLayer(
|
|
|
626
755
|
if (toggleEvent.newState === 'closed' && isOpenRef.current) {
|
|
627
756
|
openedPopoverRef.current = null;
|
|
628
757
|
isOpenRef.current = false;
|
|
758
|
+
rememberDismissal(
|
|
759
|
+
(e.currentTarget as HTMLElement | null)?.ownerDocument ?? document,
|
|
760
|
+
);
|
|
629
761
|
setIsOpen(false);
|
|
630
762
|
onHide?.();
|
|
631
763
|
clearContextMount();
|
|
632
764
|
}
|
|
633
765
|
},
|
|
634
|
-
[onHide, clearContextMount],
|
|
766
|
+
[onHide, clearContextMount, rememberDismissal],
|
|
635
767
|
);
|
|
636
768
|
|
|
637
769
|
// Ref callback for popover element — sets up the `toggle` listener.
|
|
@@ -872,6 +1004,7 @@ export function useLayer(
|
|
|
872
1004
|
show,
|
|
873
1005
|
hide,
|
|
874
1006
|
isOpen,
|
|
1007
|
+
wasJustDismissed,
|
|
875
1008
|
id,
|
|
876
1009
|
render: renderContext,
|
|
877
1010
|
};
|
|
@@ -882,7 +1015,30 @@ export function useLayer(
|
|
|
882
1015
|
show,
|
|
883
1016
|
hide,
|
|
884
1017
|
isOpen,
|
|
1018
|
+
wasJustDismissed,
|
|
885
1019
|
id,
|
|
886
1020
|
render: renderFixed,
|
|
887
1021
|
};
|
|
888
1022
|
}
|
|
1023
|
+
|
|
1024
|
+
export function useLayer(options: ContextLayerOptions): ContextLayerReturn;
|
|
1025
|
+
export function useLayer(options: FixedLayerOptions): FixedLayerReturn;
|
|
1026
|
+
export function useLayer(
|
|
1027
|
+
options: ContextLayerOptions | FixedLayerOptions,
|
|
1028
|
+
): ContextLayerReturn | FixedLayerReturn {
|
|
1029
|
+
const {wasJustDismissed: _, ...layer} = useLayerImplementation(options);
|
|
1030
|
+
return layer;
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
/** @internal Shared with usePopover; not exported from the package barrel. */
|
|
1034
|
+
export function useLayerInternal(
|
|
1035
|
+
options: ContextLayerOptions,
|
|
1036
|
+
): InternalContextLayerReturn;
|
|
1037
|
+
export function useLayerInternal(
|
|
1038
|
+
options: FixedLayerOptions,
|
|
1039
|
+
): InternalFixedLayerReturn;
|
|
1040
|
+
export function useLayerInternal(
|
|
1041
|
+
options: ContextLayerOptions | FixedLayerOptions,
|
|
1042
|
+
): InternalContextLayerReturn | InternalFixedLayerReturn {
|
|
1043
|
+
return useLayerImplementation(options);
|
|
1044
|
+
}
|