@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
package/src/Dialog/Dialog.tsx
CHANGED
|
@@ -8,6 +8,13 @@
|
|
|
8
8
|
* @output Exports Dialog component, DialogProps, DialogVariant, DialogPurpose types
|
|
9
9
|
* @position Core implementation; consumed by index.ts, tested by Dialog.test.tsx
|
|
10
10
|
*
|
|
11
|
+
* The standard variant treats `width` as the preferred surface width, then
|
|
12
|
+
* clamps it to the dynamic viewport with spacing-token gutters so narrow
|
|
13
|
+
* viewports keep content and controls on screen without changing the public API.
|
|
14
|
+
* Fullscreen dialogs add safe-area protection to the default padding fallback
|
|
15
|
+
* while preserving explicit prop/theme padding overrides, and fade in without
|
|
16
|
+
* the centered-dialog translate/scale motion.
|
|
17
|
+
*
|
|
11
18
|
* SYNC: When modified, update these files to stay in sync:
|
|
12
19
|
* - /packages/core/src/Dialog/Dialog.doc.mjs (props table, features, implementation notes)
|
|
13
20
|
* - /packages/core/src/Dialog/Dialog.test.tsx (tests for new/changed behavior)
|
|
@@ -27,14 +34,15 @@ import {
|
|
|
27
34
|
import type {BaseProps} from '../BaseProps';
|
|
28
35
|
import * as stylex from '@stylexjs/stylex';
|
|
29
36
|
import {useScrollLock} from '../hooks/useScrollLock';
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
37
|
+
import {LayerDepthProvider} from '../Layer/LayerDepthContext';
|
|
38
|
+
import {useLayerDismissal} from '../Layer/useLayerDismissal';
|
|
32
39
|
import {
|
|
33
40
|
colorVars,
|
|
34
41
|
radiusVars,
|
|
35
42
|
durationVars,
|
|
36
43
|
easeVars,
|
|
37
44
|
shadowVars,
|
|
45
|
+
spacingVars,
|
|
38
46
|
} from '../theme/tokens.stylex';
|
|
39
47
|
import {container} from '../Layout/container.stylex';
|
|
40
48
|
import type {SpacingToken} from '../Layout/container.stylex';
|
|
@@ -47,13 +55,14 @@ import {
|
|
|
47
55
|
overlayPaddingReset,
|
|
48
56
|
} from '../Layout/padding.stylex';
|
|
49
57
|
import type {SpacingStep} from '../utils/types';
|
|
50
|
-
import {mergeProps
|
|
58
|
+
import {mergeProps} from '../utils';
|
|
51
59
|
import {devWarn} from '../utils/devWarning';
|
|
52
60
|
import {DialogContext} from './DialogContext';
|
|
53
61
|
import {themeProps} from '../utils/themeProps';
|
|
54
62
|
import type {DialogVariantMap} from './index';
|
|
55
63
|
import {focusOutlineProps} from '../utils/focusOutline.stylex';
|
|
56
64
|
|
|
65
|
+
import {useMergedRefs} from '../hooks/useMergedRefs';
|
|
57
66
|
/**
|
|
58
67
|
* Calculate a directional translate offset for dialog entry animation.
|
|
59
68
|
* Returns a normalized vector from the trigger element toward the viewport
|
|
@@ -118,6 +127,32 @@ const enterDirectional = stylex.keyframes({
|
|
|
118
127
|
to: {opacity: 1, transform: 'translate(0, 0) scale(1)'},
|
|
119
128
|
});
|
|
120
129
|
|
|
130
|
+
const enterFullscreen = stylex.keyframes({
|
|
131
|
+
from: {opacity: 0},
|
|
132
|
+
to: {opacity: 1},
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
const dialogFullscreenSafeAreaBlockStartPadding = `var(--astryx-dialog-padding-block-start, var(--astryx-dialog-padding, max(${spacingVars['--spacing-4']}, env(safe-area-inset-top, 0px))))`;
|
|
136
|
+
const dialogFullscreenSafeAreaBlockEndPadding = `var(--astryx-dialog-padding-block-end, var(--astryx-dialog-padding, max(${spacingVars['--spacing-4']}, env(safe-area-inset-bottom, 0px))))`;
|
|
137
|
+
const dialogFullscreenSafeAreaInlineStartPaddingLtr = `var(--astryx-dialog-padding-inline-start, var(--astryx-dialog-padding-inline, var(--astryx-dialog-padding, max(${spacingVars['--spacing-4']}, env(safe-area-inset-left, 0px)))))`;
|
|
138
|
+
const dialogFullscreenSafeAreaInlineStartPaddingRtl = `var(--astryx-dialog-padding-inline-start, var(--astryx-dialog-padding-inline, var(--astryx-dialog-padding, max(${spacingVars['--spacing-4']}, env(safe-area-inset-right, 0px)))))`;
|
|
139
|
+
const dialogFullscreenSafeAreaInlineEndPaddingLtr = `var(--astryx-dialog-padding-inline-end, var(--astryx-dialog-padding-inline, var(--astryx-dialog-padding, max(${spacingVars['--spacing-4']}, env(safe-area-inset-right, 0px)))))`;
|
|
140
|
+
const dialogFullscreenSafeAreaInlineEndPaddingRtl = `var(--astryx-dialog-padding-inline-end, var(--astryx-dialog-padding-inline, var(--astryx-dialog-padding, max(${spacingVars['--spacing-4']}, env(safe-area-inset-left, 0px)))))`;
|
|
141
|
+
|
|
142
|
+
/** @internal Verified by Dialog.test.tsx; not re-exported from the package entry point. */
|
|
143
|
+
export const dialogFullscreenSafeAreaPaddingContract = {
|
|
144
|
+
blockStart: dialogFullscreenSafeAreaBlockStartPadding,
|
|
145
|
+
blockEnd: dialogFullscreenSafeAreaBlockEndPadding,
|
|
146
|
+
inlineStart: {
|
|
147
|
+
ltr: dialogFullscreenSafeAreaInlineStartPaddingLtr,
|
|
148
|
+
rtl: dialogFullscreenSafeAreaInlineStartPaddingRtl,
|
|
149
|
+
},
|
|
150
|
+
inlineEnd: {
|
|
151
|
+
ltr: dialogFullscreenSafeAreaInlineEndPaddingLtr,
|
|
152
|
+
rtl: dialogFullscreenSafeAreaInlineEndPaddingRtl,
|
|
153
|
+
},
|
|
154
|
+
} as const;
|
|
155
|
+
|
|
121
156
|
/**
|
|
122
157
|
* Dialog styles using native <dialog> element
|
|
123
158
|
* Uses ::backdrop pseudo-element for overlay
|
|
@@ -171,6 +206,24 @@ const styles = stylex.create({
|
|
|
171
206
|
margin: 0,
|
|
172
207
|
inset: 0,
|
|
173
208
|
},
|
|
209
|
+
fullscreenOpen: {
|
|
210
|
+
animationName: {
|
|
211
|
+
default: enterFullscreen,
|
|
212
|
+
'@media (prefers-reduced-motion: reduce)': 'none',
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
fullscreenSafeArea: {
|
|
216
|
+
paddingBlockStart: dialogFullscreenSafeAreaBlockStartPadding,
|
|
217
|
+
paddingBlockEnd: dialogFullscreenSafeAreaBlockEndPadding,
|
|
218
|
+
paddingInlineStart: {
|
|
219
|
+
default: dialogFullscreenSafeAreaInlineStartPaddingLtr,
|
|
220
|
+
':is([dir="rtl"] *)': dialogFullscreenSafeAreaInlineStartPaddingRtl,
|
|
221
|
+
},
|
|
222
|
+
paddingInlineEnd: {
|
|
223
|
+
default: dialogFullscreenSafeAreaInlineEndPaddingLtr,
|
|
224
|
+
':is([dir="rtl"] *)': dialogFullscreenSafeAreaInlineEndPaddingRtl,
|
|
225
|
+
},
|
|
226
|
+
},
|
|
174
227
|
inner: {
|
|
175
228
|
display: 'flex',
|
|
176
229
|
flexDirection: 'column',
|
|
@@ -194,12 +247,30 @@ const styles = stylex.create({
|
|
|
194
247
|
},
|
|
195
248
|
});
|
|
196
249
|
|
|
197
|
-
|
|
250
|
+
const STANDARD_DIALOG_VIEWPORT_GUTTER = spacingVars['--spacing-4'];
|
|
251
|
+
const STANDARD_DIALOG_VIEWPORT_MAX_WIDTH = `calc(100dvw - ${STANDARD_DIALOG_VIEWPORT_GUTTER} - ${STANDARD_DIALOG_VIEWPORT_GUTTER})`;
|
|
252
|
+
const STANDARD_DIALOG_MAX_WIDTH = `min(100%, ${STANDARD_DIALOG_VIEWPORT_MAX_WIDTH})`;
|
|
253
|
+
|
|
254
|
+
function formatSizeValue(value: number | string): string {
|
|
255
|
+
return typeof value === 'number' ? `${value}px` : value;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function resolveDialogSizing(
|
|
259
|
+
width: number | string,
|
|
260
|
+
maxHeight: number | string,
|
|
261
|
+
) {
|
|
262
|
+
return {
|
|
263
|
+
width: formatSizeValue(width),
|
|
264
|
+
maxWidth: STANDARD_DIALOG_MAX_WIDTH,
|
|
265
|
+
maxHeight: formatSizeValue(maxHeight),
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
|
|
198
269
|
const dynamicStyles = stylex.create({
|
|
199
|
-
sizing: (width:
|
|
200
|
-
width
|
|
201
|
-
maxWidth
|
|
202
|
-
maxHeight
|
|
270
|
+
sizing: (width: string, maxWidth: string, maxHeight: string) => ({
|
|
271
|
+
width,
|
|
272
|
+
maxWidth,
|
|
273
|
+
maxHeight,
|
|
203
274
|
}),
|
|
204
275
|
position: (
|
|
205
276
|
top: string,
|
|
@@ -288,7 +359,7 @@ export interface DialogProps extends BaseProps<HTMLDialogElement> {
|
|
|
288
359
|
* The actual height will be the height of its content.
|
|
289
360
|
* Numbers are treated as pixels, strings are used as-is.
|
|
290
361
|
* Ignored when variant is 'fullscreen'.
|
|
291
|
-
* @default '
|
|
362
|
+
* @default '75dvh'
|
|
292
363
|
*/
|
|
293
364
|
maxHeight?: number | string;
|
|
294
365
|
|
|
@@ -356,7 +427,7 @@ export function Dialog({
|
|
|
356
427
|
isInline = false,
|
|
357
428
|
onOpenChange,
|
|
358
429
|
width = 400,
|
|
359
|
-
maxHeight = '
|
|
430
|
+
maxHeight = '75dvh',
|
|
360
431
|
position,
|
|
361
432
|
variant = 'standard',
|
|
362
433
|
purpose = 'info',
|
|
@@ -374,6 +445,9 @@ export function Dialog({
|
|
|
374
445
|
const paddingToken = spacingStepToToken[effectivePadding] as SpacingToken;
|
|
375
446
|
|
|
376
447
|
const isFullscreen = variant === 'fullscreen';
|
|
448
|
+
const standardSizing = isFullscreen
|
|
449
|
+
? null
|
|
450
|
+
: resolveDialogSizing(width, maxHeight);
|
|
377
451
|
|
|
378
452
|
// Default accessible name: publish a title id through DialogContext so a
|
|
379
453
|
// DialogHeader applies it to its heading (mirrors AlertDialog's explicit
|
|
@@ -415,6 +489,8 @@ export function Dialog({
|
|
|
415
489
|
[titleId, hasConsumerName],
|
|
416
490
|
);
|
|
417
491
|
|
|
492
|
+
const mergedDialogRef = useMergedRefs(ref, attachDialog);
|
|
493
|
+
|
|
418
494
|
// Capture the element that was focused when the dialog opened,
|
|
419
495
|
// for directional animation origin and focus restoration on close.
|
|
420
496
|
const triggerElementRef = useRef<HTMLElement | null>(null);
|
|
@@ -474,34 +550,24 @@ export function Dialog({
|
|
|
474
550
|
// Skip for inline rendering — no modal overlay to compensate for.
|
|
475
551
|
useScrollLock(isOpen && !isInline);
|
|
476
552
|
|
|
477
|
-
//
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
event.preventDefault();
|
|
496
|
-
if (allowEscape) {
|
|
497
|
-
onOpenChange(false);
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
};
|
|
501
|
-
|
|
502
|
-
dialog.addEventListener('keydown', handleKeyDown);
|
|
503
|
-
return () => dialog.removeEventListener('keydown', handleKeyDown);
|
|
504
|
-
}, [isOpen, isInline, allowEscape, onOpenChange]);
|
|
553
|
+
// Join the shared layer dismissal stack. The stack owns the Escape listener
|
|
554
|
+
// and routes each press to the top-most layer, so this dialog does not listen
|
|
555
|
+
// itself — that is what stops a modal opened from inside another modal (or a
|
|
556
|
+
// popover opened inside this one) from closing two layers on one press.
|
|
557
|
+
//
|
|
558
|
+
// A `required` dialog registers as `block`: it must not be dismissed, and the
|
|
559
|
+
// press must not fall through and dismiss a layer behind it either.
|
|
560
|
+
//
|
|
561
|
+
// Inline mode opts out — it renders dialog content in normal flow, with
|
|
562
|
+
// nothing layered over anything.
|
|
563
|
+
const {shouldDismissOnCloseRequest} = useLayerDismissal({
|
|
564
|
+
isActive: isOpen,
|
|
565
|
+
isEnabled: !isInline,
|
|
566
|
+
escapeBehavior: allowEscape ? 'close' : 'block',
|
|
567
|
+
onDismiss: () => {
|
|
568
|
+
onOpenChange(false);
|
|
569
|
+
},
|
|
570
|
+
});
|
|
505
571
|
|
|
506
572
|
// Dev-time guardrail: an open modal should always have an accessible name.
|
|
507
573
|
// The header-title check reads the DOM, so this stays in an effect; the ref
|
|
@@ -537,12 +603,18 @@ export function Dialog({
|
|
|
537
603
|
}
|
|
538
604
|
};
|
|
539
605
|
|
|
540
|
-
//
|
|
606
|
+
// The native `cancel` event is the browser's own close-watcher firing: an
|
|
607
|
+
// Android back gesture, or a close request the stack never saw a press for.
|
|
608
|
+
// Escape presses the stack owns never arrive here — it preventDefault()s
|
|
609
|
+
// those, which suppresses the close watcher.
|
|
610
|
+
//
|
|
611
|
+
// Always preventDefault so the browser cannot close a controlled <dialog>
|
|
612
|
+
// behind React's back, then answer the request with the stack's own rules:
|
|
613
|
+
// only the top-most layer dismisses, a `required` dialog swallows it, and
|
|
614
|
+
// nothing dismisses while an IME composition is in progress.
|
|
541
615
|
const handleCancel = (event: React.SyntheticEvent<HTMLDialogElement>) => {
|
|
542
616
|
event.preventDefault();
|
|
543
|
-
|
|
544
|
-
// itself on the same Escape press.
|
|
545
|
-
if (hasActiveFocusTrapEscape()) {
|
|
617
|
+
if (!shouldDismissOnCloseRequest()) {
|
|
546
618
|
return;
|
|
547
619
|
}
|
|
548
620
|
if (allowEscape) {
|
|
@@ -550,7 +622,6 @@ export function Dialog({
|
|
|
550
622
|
}
|
|
551
623
|
};
|
|
552
624
|
|
|
553
|
-
// Shared inner content wrapper
|
|
554
625
|
const innerContent = (
|
|
555
626
|
<div
|
|
556
627
|
{...stylex.props(
|
|
@@ -559,22 +630,14 @@ export function Dialog({
|
|
|
559
630
|
useThemeDefault
|
|
560
631
|
? {
|
|
561
632
|
useThemeDefault: 'dialog',
|
|
562
|
-
maxHeight:
|
|
563
|
-
? undefined
|
|
564
|
-
: typeof maxHeight === 'number'
|
|
565
|
-
? `${maxHeight}px`
|
|
566
|
-
: maxHeight,
|
|
633
|
+
maxHeight: standardSizing?.maxHeight,
|
|
567
634
|
}
|
|
568
635
|
: {
|
|
569
636
|
paddingInnerX: paddingToken,
|
|
570
637
|
paddingInnerY: paddingToken,
|
|
571
638
|
paddingOuterX: paddingToken,
|
|
572
639
|
paddingOuterY: paddingToken,
|
|
573
|
-
maxHeight:
|
|
574
|
-
? undefined
|
|
575
|
-
: typeof maxHeight === 'number'
|
|
576
|
-
? `${maxHeight}px`
|
|
577
|
-
: maxHeight,
|
|
640
|
+
maxHeight: standardSizing?.maxHeight,
|
|
578
641
|
},
|
|
579
642
|
),
|
|
580
643
|
!useThemeDefault &&
|
|
@@ -589,6 +652,7 @@ export function Dialog({
|
|
|
589
652
|
!useThemeDefault &&
|
|
590
653
|
effectivePadding !== 4 &&
|
|
591
654
|
containerPaddingBlockEndVarStyles[effectivePadding],
|
|
655
|
+
isFullscreen && useThemeDefault && styles.fullscreenSafeArea,
|
|
592
656
|
)}>
|
|
593
657
|
<DialogContext value={dialogContextValue}>{children}</DialogContext>
|
|
594
658
|
</div>
|
|
@@ -612,7 +676,12 @@ export function Dialog({
|
|
|
612
676
|
stylex.props(
|
|
613
677
|
styles.inlineWrapper,
|
|
614
678
|
overlayPaddingReset.reset,
|
|
615
|
-
|
|
679
|
+
standardSizing &&
|
|
680
|
+
dynamicStyles.sizing(
|
|
681
|
+
standardSizing.width,
|
|
682
|
+
standardSizing.maxWidth,
|
|
683
|
+
standardSizing.maxHeight,
|
|
684
|
+
),
|
|
616
685
|
isFullscreen && styles.fullscreen,
|
|
617
686
|
xstyle,
|
|
618
687
|
),
|
|
@@ -623,7 +692,7 @@ export function Dialog({
|
|
|
623
692
|
(props as Record<string, unknown>)['data-testid'] as
|
|
624
693
|
string | undefined
|
|
625
694
|
}>
|
|
626
|
-
{innerContent}
|
|
695
|
+
<LayerDepthProvider>{innerContent}</LayerDepthProvider>
|
|
627
696
|
</div>
|
|
628
697
|
);
|
|
629
698
|
}
|
|
@@ -632,7 +701,7 @@ export function Dialog({
|
|
|
632
701
|
|
|
633
702
|
return (
|
|
634
703
|
<dialog
|
|
635
|
-
ref={
|
|
704
|
+
ref={mergedDialogRef}
|
|
636
705
|
{...safeProps}
|
|
637
706
|
{...mergeProps(
|
|
638
707
|
themeProps('dialog', {variant}),
|
|
@@ -641,7 +710,12 @@ export function Dialog({
|
|
|
641
710
|
overlayPaddingReset.reset,
|
|
642
711
|
isOpen && styles.open,
|
|
643
712
|
styles.backdrop,
|
|
644
|
-
|
|
713
|
+
standardSizing &&
|
|
714
|
+
dynamicStyles.sizing(
|
|
715
|
+
standardSizing.width,
|
|
716
|
+
standardSizing.maxWidth,
|
|
717
|
+
standardSizing.maxHeight,
|
|
718
|
+
),
|
|
645
719
|
hasPosition &&
|
|
646
720
|
(() => {
|
|
647
721
|
const o = resolveDialogPositionOffsets(position);
|
|
@@ -653,6 +727,7 @@ export function Dialog({
|
|
|
653
727
|
);
|
|
654
728
|
})(),
|
|
655
729
|
isFullscreen && styles.fullscreen,
|
|
730
|
+
isFullscreen && isOpen && styles.fullscreenOpen,
|
|
656
731
|
xstyle,
|
|
657
732
|
),
|
|
658
733
|
className,
|
|
@@ -665,7 +740,7 @@ export function Dialog({
|
|
|
665
740
|
// imperatively in `attachDialog`; a consumer-provided aria-labelledby
|
|
666
741
|
// flows through {...safeProps} above and wins.
|
|
667
742
|
{...(purpose === 'required' ? {role: 'alertdialog'} : undefined)}>
|
|
668
|
-
{innerContent}
|
|
743
|
+
<LayerDepthProvider>{innerContent}</LayerDepthProvider>
|
|
669
744
|
</dialog>
|
|
670
745
|
);
|
|
671
746
|
}
|
|
@@ -89,6 +89,12 @@ export const docs = {
|
|
|
89
89
|
type: '() => void',
|
|
90
90
|
description: 'Callback fired when the trigger button is clicked.',
|
|
91
91
|
},
|
|
92
|
+
{
|
|
93
|
+
name: 'placement',
|
|
94
|
+
type: "'above' | 'below' | 'start' | 'end'",
|
|
95
|
+
description: 'Position placement for the menu popover relative to the trigger button.',
|
|
96
|
+
default: "'below'",
|
|
97
|
+
},
|
|
92
98
|
{
|
|
93
99
|
name: 'hasChevron',
|
|
94
100
|
type: 'boolean',
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import {describe, it, expect, vi, beforeEach} from 'vitest';
|
|
13
|
-
import {render, screen, fireEvent, waitFor} from '@testing-library/react';
|
|
13
|
+
import {render, screen, fireEvent, waitFor, act} from '@testing-library/react';
|
|
14
14
|
import userEvent from '@testing-library/user-event';
|
|
15
15
|
import {useState} from 'react';
|
|
16
16
|
import {DropdownMenu} from './DropdownMenu';
|
|
@@ -315,10 +315,7 @@ describe('DropdownMenu', () => {
|
|
|
315
315
|
});
|
|
316
316
|
|
|
317
317
|
describe('DropdownMenu light-dismiss race', () => {
|
|
318
|
-
|
|
319
|
-
// Reproduces the iOS Safari race: pointerdown fires light-dismiss before
|
|
320
|
-
// the subsequent click on the trigger; without the guard, the click would
|
|
321
|
-
// immediately re-open the menu in the same tap.
|
|
318
|
+
function openMenu() {
|
|
322
319
|
render(
|
|
323
320
|
<DropdownMenu
|
|
324
321
|
button={{label: 'Actions'}}
|
|
@@ -326,13 +323,50 @@ describe('DropdownMenu light-dismiss race', () => {
|
|
|
326
323
|
data-testid="astryx-dropdown-menu"
|
|
327
324
|
/>,
|
|
328
325
|
);
|
|
329
|
-
|
|
330
326
|
const trigger = screen.getByTestId('astryx-dropdown-menu');
|
|
331
|
-
fireEvent.
|
|
332
|
-
fireEvent.click(trigger);
|
|
333
|
-
fireEvent.click(trigger); // would re-open without guard
|
|
327
|
+
fireEvent.pointerDown(trigger);
|
|
328
|
+
fireEvent.click(trigger);
|
|
334
329
|
expect(HTMLElement.prototype.showPopover).toHaveBeenCalledTimes(1);
|
|
335
|
-
|
|
330
|
+
return trigger;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* The browser dismisses the menu on pointerup and queues the `toggle` event;
|
|
335
|
+
* on the engines that lose the race it reaches React before the trigger's
|
|
336
|
+
* own click, which then reads a closed menu.
|
|
337
|
+
*/
|
|
338
|
+
function lightDismiss() {
|
|
339
|
+
const popover = document.querySelector('[popover]') as HTMLElement;
|
|
340
|
+
act(() => {
|
|
341
|
+
popover.dispatchEvent(
|
|
342
|
+
Object.assign(new Event('toggle'), {
|
|
343
|
+
oldState: 'open',
|
|
344
|
+
newState: 'closed',
|
|
345
|
+
}),
|
|
346
|
+
);
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
it('does not re-open when the trigger click follows its own light dismiss', () => {
|
|
351
|
+
const trigger = openMenu();
|
|
352
|
+
|
|
353
|
+
fireEvent.pointerDown(trigger);
|
|
354
|
+
lightDismiss();
|
|
355
|
+
fireEvent.click(trigger);
|
|
356
|
+
|
|
357
|
+
expect(HTMLElement.prototype.showPopover).toHaveBeenCalledTimes(1);
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
it('re-opens on a press of its own after a light dismiss', () => {
|
|
361
|
+
const trigger = openMenu();
|
|
362
|
+
|
|
363
|
+
fireEvent.pointerDown(trigger);
|
|
364
|
+
lightDismiss();
|
|
365
|
+
fireEvent.click(trigger);
|
|
366
|
+
fireEvent.pointerDown(trigger);
|
|
367
|
+
fireEvent.click(trigger);
|
|
368
|
+
|
|
369
|
+
expect(HTMLElement.prototype.showPopover).toHaveBeenCalledTimes(2);
|
|
336
370
|
});
|
|
337
371
|
});
|
|
338
372
|
|
|
@@ -37,7 +37,7 @@ import React, {
|
|
|
37
37
|
type ReactNode,
|
|
38
38
|
} from 'react';
|
|
39
39
|
import * as stylex from '@stylexjs/stylex';
|
|
40
|
-
import {
|
|
40
|
+
import {usePopoverInternal} from '../Popover/usePopover';
|
|
41
41
|
import {Button, type ButtonProps} from '../Button';
|
|
42
42
|
import {Icon} from '../Icon';
|
|
43
43
|
|
|
@@ -261,14 +261,8 @@ export function DropdownMenu({
|
|
|
261
261
|
const isControlled = controlledIsOpen !== undefined;
|
|
262
262
|
const isOpen = isControlled ? controlledIsOpen : internalIsOpen;
|
|
263
263
|
|
|
264
|
-
// Track when the menu was last hidden so a near-simultaneous trigger
|
|
265
|
-
// click — e.g. on iOS Safari where pointerdown fires light-dismiss
|
|
266
|
-
// before the trigger's click event — can't immediately re-open it.
|
|
267
|
-
const lastHideTimeRef = useRef(0);
|
|
268
|
-
|
|
269
264
|
// Close menu + return focus to trigger
|
|
270
265
|
const handleLayerHide = useCallback(() => {
|
|
271
|
-
lastHideTimeRef.current = Date.now();
|
|
272
266
|
onOpenChange?.(false);
|
|
273
267
|
if (!isControlled) {
|
|
274
268
|
setInternalIsOpen(false);
|
|
@@ -294,7 +288,7 @@ export function DropdownMenu({
|
|
|
294
288
|
}
|
|
295
289
|
}, [isControlled, onOpenChange]);
|
|
296
290
|
|
|
297
|
-
const popover =
|
|
291
|
+
const popover = usePopoverInternal({
|
|
298
292
|
onHide: handleLayerHide,
|
|
299
293
|
onShow: handleLayerShow,
|
|
300
294
|
hasLightDismiss: true,
|
|
@@ -422,11 +416,8 @@ export function DropdownMenu({
|
|
|
422
416
|
|
|
423
417
|
const handleButtonClick = useCallback(
|
|
424
418
|
(e: React.MouseEvent<HTMLButtonElement>) => {
|
|
425
|
-
//
|
|
426
|
-
|
|
427
|
-
// otherwise immediately re-open it. Short-circuit within the guard
|
|
428
|
-
// window.
|
|
429
|
-
if (Date.now() - lastHideTimeRef.current < 50) {
|
|
419
|
+
// The click that light-dismissed the menu is not a request to reopen it.
|
|
420
|
+
if (popover.wasJustDismissed()) {
|
|
430
421
|
return;
|
|
431
422
|
}
|
|
432
423
|
onClick?.();
|
|
@@ -701,11 +701,14 @@ describe('DropdownMenuSubMenu theming slots', () => {
|
|
|
701
701
|
name: /Move to/,
|
|
702
702
|
hidden: true,
|
|
703
703
|
});
|
|
704
|
-
// The indicator-icon slot
|
|
705
|
-
//
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
704
|
+
// The indicator-icon slot sits on the chevron glyph itself (the element
|
|
705
|
+
// that carries the icon size), so a theme can restyle its size/color
|
|
706
|
+
// directly.
|
|
707
|
+
const indicator = trigger.querySelector(
|
|
708
|
+
'.astryx-dropdown-menu-indicator-icon',
|
|
709
|
+
);
|
|
710
|
+
expect(indicator).toBeInTheDocument();
|
|
711
|
+
expect(indicator).toHaveClass('astryx-icon');
|
|
709
712
|
});
|
|
710
713
|
});
|
|
711
714
|
|
|
@@ -476,20 +476,17 @@ export function DropdownMenuSubMenu(
|
|
|
476
476
|
);
|
|
477
477
|
|
|
478
478
|
const endAffordance = hasSpinner ? (
|
|
479
|
-
<span
|
|
480
|
-
{...mergeProps(
|
|
481
|
-
themeProps('dropdown-menu-indicator-icon'),
|
|
482
|
-
stylex.props(triggerStyles.caret),
|
|
483
|
-
)}>
|
|
479
|
+
<span {...stylex.props(triggerStyles.caret)}>
|
|
484
480
|
<Spinner size="sm" />
|
|
485
481
|
</span>
|
|
486
482
|
) : (
|
|
487
|
-
<span
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
483
|
+
<span {...stylex.props(triggerStyles.caret)}>
|
|
484
|
+
<Icon
|
|
485
|
+
icon="chevronRight"
|
|
486
|
+
size="sm"
|
|
487
|
+
color="secondary"
|
|
488
|
+
{...themeProps('dropdown-menu-indicator-icon')}
|
|
489
|
+
/>
|
|
493
490
|
</span>
|
|
494
491
|
);
|
|
495
492
|
|
package/src/Field/Field.doc.mjs
CHANGED
|
@@ -39,8 +39,8 @@ export const docs = {
|
|
|
39
39
|
],
|
|
40
40
|
vars: [
|
|
41
41
|
{name: '--_field-radius', description: 'Border radius of input fields', default: 'var(--radius-element)', private: true},
|
|
42
|
-
{name: '--_input-clear-hit-inset', description: 'Outset of the clear (\u2715) button\
|
|
43
|
-
{name: '--_input-clear-hit-content', description: 'Whether the clear (\u2715) button\
|
|
42
|
+
{name: '--_input-clear-hit-inset', description: 'Outset of the clear (\u2715) button\'s invisible hit area, applied to a ::after overlay. 0 on a fine pointer; negative on a coarse one, which grows the 20px button to the 24px touch target without changing what is drawn.', default: '0px', private: true},
|
|
43
|
+
{name: '--_input-clear-hit-content', description: 'Whether the clear (\u2715) button\'s invisible hit overlay exists. `none` on a fine pointer, so no ::after is generated and hover still reaches the glyph; `""` on a coarse one, where the overlay provides the 24px touch target.', default: 'none', private: true},
|
|
44
44
|
],
|
|
45
45
|
derived: [
|
|
46
46
|
{property: 'borderRadius', vars: ['--_field-radius']},
|
|
@@ -60,6 +60,17 @@ export const docs = {
|
|
|
60
60
|
description: 'ID for the input element (used for the label htmlFor attribute).',
|
|
61
61
|
required: true,
|
|
62
62
|
},
|
|
63
|
+
{
|
|
64
|
+
name: 'labelID',
|
|
65
|
+
type: 'string',
|
|
66
|
+
description: 'ID applied to the label element itself for group accessibility.',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: 'isGroupLabel',
|
|
70
|
+
type: 'boolean',
|
|
71
|
+
description: 'Renders the label as a span for control groups (radiogroup, checkbox list).',
|
|
72
|
+
default: 'false',
|
|
73
|
+
},
|
|
63
74
|
{
|
|
64
75
|
name: 'children',
|
|
65
76
|
type: 'ReactNode',
|
|
@@ -15,6 +15,7 @@ import userEvent from '@testing-library/user-event';
|
|
|
15
15
|
import {TestIcon} from '../__tests__/TestIcon';
|
|
16
16
|
import {InternationalizationProvider} from '../i18n';
|
|
17
17
|
import {FieldLabel} from './FieldLabel';
|
|
18
|
+
import {themeProps} from '../utils/themeProps';
|
|
18
19
|
|
|
19
20
|
describe('FieldLabel', () => {
|
|
20
21
|
it('renders label text', () => {
|
|
@@ -197,4 +198,32 @@ describe('FieldLabel', () => {
|
|
|
197
198
|
expect(description.closest('label')).toBeNull();
|
|
198
199
|
});
|
|
199
200
|
});
|
|
201
|
+
|
|
202
|
+
describe('a control can name its own label target', () => {
|
|
203
|
+
it('composes a passed target onto the field-label one', () => {
|
|
204
|
+
// How CheckboxInput and Switch reach their label: the control spreads
|
|
205
|
+
// its own themeProps in, and both classes end up on the same element,
|
|
206
|
+
// so a theme can style every label or just this kind.
|
|
207
|
+
render(
|
|
208
|
+
<FieldLabel
|
|
209
|
+
{...themeProps('checkbox-label')}
|
|
210
|
+
label="Notify me"
|
|
211
|
+
inputID="notify-input"
|
|
212
|
+
/>,
|
|
213
|
+
);
|
|
214
|
+
const label = screen.getByText('Notify me').closest('label');
|
|
215
|
+
expect(label).toHaveClass('astryx-field-label');
|
|
216
|
+
expect(label).toHaveClass('astryx-checkbox-label');
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it('describes no placement of its own', () => {
|
|
220
|
+
// The label cannot know how its caller arranged it, so it says nothing:
|
|
221
|
+
// a `data-layout` here would be a claim that is wrong for at least one
|
|
222
|
+
// caller (Field's horizontal-labels puts a label beside its control),
|
|
223
|
+
// and a consumer could set it untruthfully.
|
|
224
|
+
render(<FieldLabel label="Email" inputID="email-input" />);
|
|
225
|
+
const label = screen.getByText('Email').closest('label');
|
|
226
|
+
expect(label).not.toHaveAttribute('data-layout');
|
|
227
|
+
});
|
|
228
|
+
});
|
|
200
229
|
});
|
package/src/Field/FieldLabel.tsx
CHANGED
|
@@ -285,6 +285,13 @@ export function FieldLabel({
|
|
|
285
285
|
htmlFor={isGroupLabel ? undefined : inputID}
|
|
286
286
|
{...rest}
|
|
287
287
|
{...mergeProps(
|
|
288
|
+
// A control that knows what kind of label this is passes its own
|
|
289
|
+
// target down (CheckboxInput's `checkbox-label`, Switch's
|
|
290
|
+
// `switch-label`); it arrives as `className` and composes onto this
|
|
291
|
+
// one. The label itself does not describe its own placement — it
|
|
292
|
+
// cannot know it, and any encoding it guessed would be wrong for a
|
|
293
|
+
// caller that arranges labels differently (Field's
|
|
294
|
+
// `horizontal-labels`).
|
|
288
295
|
themeProps('field-label'),
|
|
289
296
|
stylex.props(
|
|
290
297
|
styles.label,
|
|
@@ -15,7 +15,7 @@ import {readFileSync} from 'node:fs';
|
|
|
15
15
|
import path from 'node:path';
|
|
16
16
|
import {describe, it, expect, vi} from 'vitest';
|
|
17
17
|
import {render, screen, fireEvent} from '@testing-library/react';
|
|
18
|
-
import {InputClearButton} from './InputClearButton';
|
|
18
|
+
import {InputClearButton, type InputClearButtonProps} from './InputClearButton';
|
|
19
19
|
import {Icon} from '../Icon';
|
|
20
20
|
import {defineTheme} from '../theme/defineTheme';
|
|
21
21
|
import {generateThemeCSS} from '../theme/generateThemeRules';
|
|
@@ -67,6 +67,20 @@ const getGlyph = (): HTMLElement => {
|
|
|
67
67
|
return icon as HTMLElement;
|
|
68
68
|
};
|
|
69
69
|
|
|
70
|
+
describe('InputClearButton public props', () => {
|
|
71
|
+
it('keep popup invoker handlers internal', () => {
|
|
72
|
+
const hasPointerDown: 'onPointerDown' extends keyof InputClearButtonProps
|
|
73
|
+
? true
|
|
74
|
+
: false = false;
|
|
75
|
+
const hasClickCapture: 'onClickCapture' extends keyof InputClearButtonProps
|
|
76
|
+
? true
|
|
77
|
+
: false = false;
|
|
78
|
+
|
|
79
|
+
expect(hasPointerDown).toBe(false);
|
|
80
|
+
expect(hasClickCapture).toBe(false);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
70
84
|
describe('InputClearButton', () => {
|
|
71
85
|
it('renders a real button with the given accessible label', () => {
|
|
72
86
|
render(<InputClearButton label="Clear" onClick={() => {}} />);
|