@astryxdesign/core 0.4.6 → 0.4.7-canary.20bae6c
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 +36 -0
- 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/AvatarGroup/AvatarGroup.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroup.js +3 -2
- package/dist/BottomSheet/BottomSheet.d.ts +1 -0
- package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheet.js +54 -15
- package/dist/BottomSheet/BottomSheetEdgeTint.d.ts +6 -0
- package/dist/BottomSheet/BottomSheetEdgeTint.d.ts.map +1 -0
- package/dist/BottomSheet/BottomSheetEdgeTint.js +62 -0
- package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetPanel.js +1 -0
- package/dist/BottomSheet/BottomSheetSwitcher.d.ts +1 -0
- package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetSwitcher.js +13 -6
- package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
- package/dist/BottomSheet/useSheetGestures.js +23 -5
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.js +11 -10
- package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
- package/dist/ButtonGroup/ButtonGroup.js +12 -4
- package/dist/Calendar/Calendar.d.ts +3 -1
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +13 -14
- 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/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +3 -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/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +3 -2
- package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
- package/dist/ClickableCard/ClickableCard.js +3 -3
- 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/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +4 -3
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +3 -2
- package/dist/DateInput/TouchDateField.d.ts.map +1 -1
- package/dist/DateInput/TouchDateField.js +34 -1
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +3 -2
- package/dist/Dialog/Dialog.d.ts +7 -1
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +89 -58
- 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 -2
- package/dist/HoverCard/HoverCard.d.ts +6 -0
- package/dist/HoverCard/HoverCard.d.ts.map +1 -1
- package/dist/HoverCard/useHoverCard.d.ts +5 -0
- package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
- package/dist/HoverCard/useHoverCard.js +67 -25
- 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 +10 -3
- 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/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/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/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 +149 -23
- 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 +15 -1
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +17 -6
- package/dist/MultiSelector/index.d.ts +1 -1
- package/dist/MultiSelector/index.d.ts.map +1 -1
- package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
- package/dist/NavMenu/NavHeadingMenu.js +3 -2
- 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/usePopover.d.ts.map +1 -1
- package/dist/Popover/usePopover.js +20 -17
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +3 -4
- 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 +3 -3
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +5 -0
- package/dist/SideNav/SideNav.d.ts.map +1 -1
- package/dist/SideNav/SideNav.js +4 -3
- 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 +3 -3
- 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 +3 -2
- package/dist/TabList/Tab.d.ts.map +1 -1
- package/dist/TabList/Tab.js +5 -1
- package/dist/TabList/TabList.d.ts.map +1 -1
- package/dist/TabList/TabList.js +3 -3
- package/dist/Table/BaseTable.d.ts.map +1 -1
- package/dist/Table/BaseTable.js +4 -1
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +20 -8
- 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 +19 -5
- 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 -2
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +3 -2
- 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.map +1 -1
- package/dist/Timestamp/Timestamp.js +5 -3
- package/dist/Token/TokenLink.d.ts.map +1 -1
- package/dist/Token/TokenLink.js +2 -2
- 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/TopNavMegaMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMegaMenu.js +3 -3
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +3 -3
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +3 -2
- package/dist/astryx.css +43 -1
- 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 +52 -91
- package/dist/hooks/useHotkeys.d.ts.map +1 -1
- package/dist/hooks/useHotkeys.js +10 -3
- package/dist/hooks/useListFocus.d.ts +5 -2
- package/dist/hooks/useListFocus.d.ts.map +1 -1
- package/dist/hooks/useListFocus.js +12 -6
- 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/utils/timeParser.d.ts +1 -1
- package/dist/utils/timeParser.d.ts.map +1 -1
- package/dist/utils/timeParser.js +26 -12
- package/locales/en.json +27 -7
- package/locales/pseudo.json +15 -0
- package/package.json +8 -3
- 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 +2 -1
- package/src/AvatarGroup/AvatarGroup.tsx +3 -2
- package/src/BottomSheet/BottomSheet.test.tsx +123 -0
- package/src/BottomSheet/BottomSheet.tsx +36 -4
- package/src/BottomSheet/BottomSheetEdgeTint.test.tsx +225 -0
- package/src/BottomSheet/BottomSheetEdgeTint.tsx +82 -0
- package/src/BottomSheet/BottomSheetPanel.test.tsx +66 -0
- package/src/BottomSheet/BottomSheetPanel.tsx +19 -0
- package/src/BottomSheet/BottomSheetSwitcher.tsx +16 -2
- package/src/BottomSheet/useSheetGestures.test.ts +27 -0
- package/src/BottomSheet/useSheetGestures.ts +25 -5
- package/src/Breadcrumbs/BreadcrumbItem.tsx +9 -5
- package/src/Button/Button.doc.mjs +22 -0
- package/src/ButtonGroup/ButtonGroup.doc.mjs +7 -1
- package/src/ButtonGroup/ButtonGroup.test.tsx +185 -1
- package/src/ButtonGroup/ButtonGroup.tsx +11 -3
- package/src/Calendar/Calendar.doc.mjs +4 -3
- package/src/Calendar/Calendar.test.tsx +52 -0
- package/src/Calendar/Calendar.tsx +18 -15
- package/src/Calendar/getInitialFocusDate.test.ts +94 -0
- package/src/Calendar/getInitialFocusDate.ts +93 -0
- package/src/Carousel/Carousel.tsx +3 -2
- 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/CheckboxInput/CheckboxInput.tsx +3 -2
- package/src/ClickableCard/ClickableCard.tsx +3 -2
- package/src/CodeBlock/CodeBlock.doc.mjs +6 -0
- package/src/CommandPalette/CommandPaletteInput.tsx +3 -2
- package/src/CommandPalette/CommandPaletteItem.tsx +3 -2
- package/src/ContextMenu/ContextMenu.doc.mjs +5 -0
- package/src/ContextMenu/ContextMenu.tsx +4 -3
- package/src/DateInput/DateInput.tsx +3 -2
- package/src/DateInput/DateInputTouch.test.tsx +36 -0
- package/src/DateInput/TouchDateField.tsx +35 -1
- package/src/DateTimeInput/DateTimeInput.tsx +2 -2
- package/src/Dialog/Dialog.doc.mjs +8 -3
- package/src/Dialog/Dialog.test.tsx +261 -1
- package/src/Dialog/Dialog.tsx +109 -58
- package/src/DropdownMenu/DropdownMenu.doc.mjs +6 -0
- package/src/Field/Field.doc.mjs +13 -2
- package/src/FileInput/FileInput.tsx +3 -2
- package/src/Heading/Heading.test.tsx +23 -1
- package/src/Heading/Heading.tsx +6 -2
- package/src/HoverCard/HoverCard.doc.mjs +5 -0
- package/src/HoverCard/HoverCard.tsx +6 -0
- package/src/HoverCard/useHoverCard.tsx +81 -30
- package/src/Item/Item.tsx +5 -4
- package/src/Kbd/Kbd.test.tsx +17 -0
- package/src/Kbd/Kbd.tsx +10 -3
- package/src/Layer/LayerDepthContext.tsx +62 -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/useLayerDismissal.test.tsx +469 -0
- package/src/Layer/useLayerDismissal.ts +173 -0
- package/src/Layout/Layout.doc.mjs +2 -2
- 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/Markdown/index.ts +1 -0
- package/src/Markdown/parser.perf.test.ts +71 -1
- package/src/Markdown/parser.test.ts +145 -2
- package/src/Markdown/parser.ts +208 -22
- package/src/MobileNav/MobileNav.tsx +62 -36
- package/src/MoreMenu/MoreMenu.doc.mjs +7 -1
- package/src/MultiSelector/MultiSelector.doc.mjs +27 -0
- package/src/MultiSelector/MultiSelector.test.tsx +105 -0
- package/src/MultiSelector/MultiSelector.tsx +50 -6
- package/src/MultiSelector/index.ts +1 -0
- package/src/NavMenu/NavHeadingMenu.tsx +3 -2
- package/src/NumberInput/NumberInput.doc.mjs +5 -0
- package/src/Outline/Outline.tsx +3 -2
- package/src/OverflowList/OverflowList.tsx +3 -2
- package/src/Overlay/Overlay.tsx +3 -2
- package/src/Popover/Popover.test.tsx +27 -1
- package/src/Popover/usePopover.tsx +31 -28
- package/src/PowerSearch/PowerSearch.doc.mjs +26 -0
- package/src/PowerSearch/PowerSearch.tsx +5 -2
- package/src/Resizable/ResizeHandle.tsx +3 -2
- package/src/SegmentedControl/SegmentedControl.tsx +3 -2
- package/src/SelectableCard/SelectableCard.tsx +3 -2
- package/src/Selector/Selector.doc.mjs +12 -1
- package/src/Selector/Selector.test.tsx +21 -0
- package/src/Selector/Selector.tsx +11 -1
- package/src/SideNav/SideNav.doc.mjs +6 -6
- package/src/SideNav/SideNav.tsx +4 -2
- package/src/SideNav/SideNavItem.tsx +4 -2
- package/src/Slider/Slider.tsx +3 -2
- 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.tsx +3 -2
- package/src/TabList/Tab.tsx +5 -1
- package/src/TabList/TabList.test.tsx +21 -4
- package/src/TabList/TabList.tsx +3 -2
- package/src/Table/BaseTable.tsx +6 -3
- package/src/Table/Table.test.tsx +35 -0
- 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 +17 -8
- 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 +76 -0
- package/src/Table/plugins/selection/useTableSelection.tsx +40 -7
- 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 +23 -1
- package/src/Text/Text.tsx +6 -2
- package/src/TextArea/TextArea.tsx +3 -2
- 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.tsx +4 -2
- package/src/Toast/Toast.doc.mjs +6 -0
- package/src/Token/TokenLink.tsx +2 -2
- package/src/Tokenizer/Tokenizer.doc.mjs +16 -0
- 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/TopNavMegaMenu.tsx +3 -2
- package/src/Typeahead/BaseTypeahead.tsx +3 -2
- package/src/Typeahead/Typeahead.doc.mjs +5 -0
- package/src/Typeahead/Typeahead.tsx +3 -2
- package/src/__tests__/complexComponentContract.test.tsx +81 -0
- package/src/hooks/index.ts +2 -0
- package/src/hooks/useContainerReveal.doc.mjs +2 -2
- package/src/hooks/useFocusTrap.ts +54 -107
- package/src/hooks/useFocusTrapEscapeShim.test.tsx +165 -0
- package/src/hooks/useHotkeys.test.ts +18 -0
- package/src/hooks/useHotkeys.ts +10 -3
- package/src/hooks/useListFocus.doc.mjs +2 -2
- package/src/hooks/useListFocus.test.tsx +65 -3
- package/src/hooks/useListFocus.ts +15 -7
- 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/index.ts +1 -0
- package/src/theme/MediaTheme.doc.mjs +5 -5
- package/src/utils/timeParser.test.ts +6 -1
- package/src/utils/timeParser.ts +35 -13
- package/src/__tests__/inputWidthContract.test.tsx +0 -69
|
@@ -7,7 +7,7 @@ export const docs = {
|
|
|
7
7
|
subComponentOf: 'Chat',
|
|
8
8
|
displayName: 'Chat Message List',
|
|
9
9
|
isHiddenFromOverview: true,
|
|
10
|
-
description: `Presentational message container with density context and infinite scroll support. Provides role="log" with aria-live="polite" for accessibility. A flex spacer pushes messages to the bottom when the list isn't full.`,
|
|
10
|
+
description: `Presentational message container with density context and infinite scroll support. Provides role="log" with aria-live="polite" for accessibility. A flex spacer pushes messages to the bottom when the list isn't full; set align="top" to start messages at the top instead.`,
|
|
11
11
|
props: [
|
|
12
12
|
{
|
|
13
13
|
name: 'children',
|
|
@@ -45,6 +45,12 @@ export const docs = {
|
|
|
45
45
|
type: '0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10',
|
|
46
46
|
description: 'Gap between top-level message rows. Defaults to the selected density; override for LLM event streams or independent rows that need different spacing from density.',
|
|
47
47
|
},
|
|
48
|
+
{
|
|
49
|
+
name: 'align',
|
|
50
|
+
type: "'top' | 'bottom'",
|
|
51
|
+
description: "Vertical alignment when the list is shorter than its container. 'bottom' fills free space with a spacer so short conversations sit above the composer; 'top' omits the spacer so messages start at the top. Only affects a non-full list; overflowing lists scroll identically, preserving auto-scroll-to-bottom.",
|
|
52
|
+
default: "'bottom'",
|
|
53
|
+
},
|
|
48
54
|
{
|
|
49
55
|
name: 'isStreaming',
|
|
50
56
|
type: 'boolean',
|
|
@@ -65,6 +71,7 @@ export const docsZh = {
|
|
|
65
71
|
scrollToTopAction: '用户滚动到顶部时触发的异步操作。用于加载更早的消息。',
|
|
66
72
|
density: '视觉密度,通过上下文传递给子消息。',
|
|
67
73
|
gap: '顶层消息行之间的间距。默认跟随密度;当 LLM 事件流等独立行需要不同间距时可覆盖。',
|
|
74
|
+
align: "列表内容不足一屏时的垂直对齐方式。'bottom' 用占位块填满剩余空间,让简短对话贴近输入框;'top' 省略占位块,让消息从顶部开始。仅影响未填满的列表,溢出后两种模式滚动一致,保持自动滚动到底部。",
|
|
68
75
|
isStreaming: '是否有助手消息正在流式输出。标记日志为 aria-busy,让屏幕阅读器等待并在完成后一次性播报,而不是每个 token 都重复播报。',
|
|
69
76
|
},
|
|
70
77
|
};
|
|
@@ -80,6 +87,7 @@ export const docsDense = {
|
|
|
80
87
|
scrollToTopAction: 'async action at scroll top; load older msgs',
|
|
81
88
|
density: 'visual density; flows to children via context',
|
|
82
89
|
gap: 'top-level row gap; defaults to density spacing; override for independent LLM/tool rows',
|
|
90
|
+
align: "'top'|'bottom' (def bottom); bottom spacer pushes short lists down, top starts at top; overflow scrolls same either way",
|
|
83
91
|
isStreaming: 'assistant streaming? marks log aria-busy so SR announces the completed msg once',
|
|
84
92
|
},
|
|
85
93
|
};
|
|
@@ -83,4 +83,50 @@ describe('ChatMessageList', () => {
|
|
|
83
83
|
);
|
|
84
84
|
expect(screen.getByTestId('chat-list')).toBeTruthy();
|
|
85
85
|
});
|
|
86
|
+
|
|
87
|
+
// With no scrollToTopAction the spacer is the only aria-hidden element in
|
|
88
|
+
// the list, so its presence maps 1:1 to the aria-hidden count.
|
|
89
|
+
it('renders the bottom spacer by default', () => {
|
|
90
|
+
render(
|
|
91
|
+
<ChatMessageList data-testid="list">
|
|
92
|
+
<div>msg</div>
|
|
93
|
+
</ChatMessageList>,
|
|
94
|
+
);
|
|
95
|
+
expect(
|
|
96
|
+
screen.getByTestId('list').querySelectorAll('[aria-hidden]'),
|
|
97
|
+
).toHaveLength(1);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('renders the bottom spacer when align="bottom"', () => {
|
|
101
|
+
render(
|
|
102
|
+
<ChatMessageList align="bottom" data-testid="list">
|
|
103
|
+
<div>msg</div>
|
|
104
|
+
</ChatMessageList>,
|
|
105
|
+
);
|
|
106
|
+
expect(
|
|
107
|
+
screen.getByTestId('list').querySelectorAll('[aria-hidden]'),
|
|
108
|
+
).toHaveLength(1);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('omits the spacer when align="top"', () => {
|
|
112
|
+
render(
|
|
113
|
+
<ChatMessageList align="top" data-testid="list">
|
|
114
|
+
<div>msg</div>
|
|
115
|
+
</ChatMessageList>,
|
|
116
|
+
);
|
|
117
|
+
expect(
|
|
118
|
+
screen.getByTestId('list').querySelectorAll('[aria-hidden]'),
|
|
119
|
+
).toHaveLength(0);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('still renders children when align="top"', () => {
|
|
123
|
+
render(
|
|
124
|
+
<ChatMessageList align="top">
|
|
125
|
+
<ChatMessage sender="assistant">
|
|
126
|
+
<ChatMessageBubble>Hello</ChatMessageBubble>
|
|
127
|
+
</ChatMessage>
|
|
128
|
+
</ChatMessageList>,
|
|
129
|
+
);
|
|
130
|
+
expect(screen.getByText('Hello')).toBeTruthy();
|
|
131
|
+
});
|
|
86
132
|
});
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
*
|
|
11
11
|
* Renders a container with role="log" for chat message histories.
|
|
12
12
|
* Handles density context, configurable gap, empty state,
|
|
13
|
-
* a spacer that pushes messages to the bottom,
|
|
13
|
+
* a configurable spacer (align) that pushes messages to the bottom,
|
|
14
|
+
* and an infinite scroll sentinel.
|
|
14
15
|
*
|
|
15
16
|
* Auto-scroll and the scroll-to-bottom button are owned by
|
|
16
17
|
* ChatLayout. When used standalone (without a layout), the list
|
|
@@ -73,6 +74,24 @@ export interface ChatMessageListProps extends BaseProps<HTMLDivElement> {
|
|
|
73
74
|
*/
|
|
74
75
|
gap?: SpacingStep;
|
|
75
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Vertical alignment of messages when the list is shorter than its
|
|
79
|
+
* container.
|
|
80
|
+
*
|
|
81
|
+
* - `'bottom'` (default): a spacer fills the free space and pushes
|
|
82
|
+
* messages to the bottom, so a short conversation sits just above the
|
|
83
|
+
* composer — the familiar messaging-app layout.
|
|
84
|
+
* - `'top'`: the spacer is omitted, so messages start at the top and grow
|
|
85
|
+
* downward — better for document-style or log-style lists.
|
|
86
|
+
*
|
|
87
|
+
* This only changes the resting position of a non-full list. Once messages
|
|
88
|
+
* overflow the container the spacer collapses to zero in both modes, so
|
|
89
|
+
* ChatLayout auto-scroll-to-bottom behavior is identical either way.
|
|
90
|
+
*
|
|
91
|
+
* @default 'bottom'
|
|
92
|
+
*/
|
|
93
|
+
align?: 'top' | 'bottom';
|
|
94
|
+
|
|
76
95
|
/**
|
|
77
96
|
* Whether an assistant message is actively streaming into the list.
|
|
78
97
|
*
|
|
@@ -183,7 +202,8 @@ const gapStyles = stylex.create({
|
|
|
183
202
|
*
|
|
184
203
|
* Renders messages in a flex column with density-based spacing.
|
|
185
204
|
* Override gap to tune row spacing separately from density.
|
|
186
|
-
*
|
|
205
|
+
* By default a spacer pushes content to the bottom when the list isn't full;
|
|
206
|
+
* set `align='top'` to start messages at the top instead.
|
|
187
207
|
* Supports loading older messages via `scrollToTopAction`.
|
|
188
208
|
*
|
|
189
209
|
* Auto-scroll and the scroll-to-bottom button are owned by
|
|
@@ -204,6 +224,7 @@ export function ChatMessageList({
|
|
|
204
224
|
scrollToTopAction,
|
|
205
225
|
density = 'balanced',
|
|
206
226
|
gap,
|
|
227
|
+
align = 'bottom',
|
|
207
228
|
isStreaming = false,
|
|
208
229
|
xstyle,
|
|
209
230
|
className,
|
|
@@ -291,8 +312,11 @@ export function ChatMessageList({
|
|
|
291
312
|
</div>
|
|
292
313
|
)}
|
|
293
314
|
|
|
294
|
-
{/* Spacer pushes messages to bottom when list isn't full
|
|
295
|
-
|
|
315
|
+
{/* Spacer pushes messages to bottom when the list isn't full.
|
|
316
|
+
Omitted for top alignment so messages start at the top. */}
|
|
317
|
+
{align === 'bottom' && (
|
|
318
|
+
<div {...stylex.props(styles.spacer)} aria-hidden />
|
|
319
|
+
)}
|
|
296
320
|
|
|
297
321
|
{/* Messages or empty state */}
|
|
298
322
|
{hasChildren ? (
|
|
@@ -44,7 +44,7 @@ import type {IconType} from '../Icon';
|
|
|
44
44
|
import type {InputStatus} from '../Field/types';
|
|
45
45
|
import {Spinner} from '../Spinner';
|
|
46
46
|
import {useTooltip} from '../Tooltip';
|
|
47
|
-
import {mergeProps
|
|
47
|
+
import {mergeProps} from '../utils';
|
|
48
48
|
import {indicatorScope} from '../Indicator/indicator.markers.stylex';
|
|
49
49
|
import {useIndicatorFocusRing} from '../hooks/useIndicatorFocusRing';
|
|
50
50
|
import {useResolvedRequired} from '../hooks/useResolvedRequired';
|
|
@@ -52,6 +52,7 @@ import {useIndicator} from '../Indicator';
|
|
|
52
52
|
import {themeProps} from '../utils/themeProps';
|
|
53
53
|
import {CheckboxListContext} from '../CheckboxList/CheckboxListContext';
|
|
54
54
|
|
|
55
|
+
import {useMergedRefs} from '../hooks/useMergedRefs';
|
|
55
56
|
const styles = stylex.create({
|
|
56
57
|
container: {
|
|
57
58
|
display: 'flex',
|
|
@@ -409,7 +410,7 @@ export function CheckboxInput({
|
|
|
409
410
|
{...focusProps}>
|
|
410
411
|
<input
|
|
411
412
|
{...rest}
|
|
412
|
-
ref={
|
|
413
|
+
ref={useMergedRefs(
|
|
413
414
|
ref,
|
|
414
415
|
indeterminateRef,
|
|
415
416
|
disabledMessageTooltip.positionRef,
|
|
@@ -39,7 +39,7 @@ import {
|
|
|
39
39
|
easeVars,
|
|
40
40
|
} from '../theme/tokens.stylex';
|
|
41
41
|
import type {SizeValue, SpacingStep, Elevation} from '../utils/types';
|
|
42
|
-
import {mergeProps
|
|
42
|
+
import {mergeProps} from '../utils';
|
|
43
43
|
import {Card} from '../Card/Card';
|
|
44
44
|
import type {CardVariant} from '../Card/Card';
|
|
45
45
|
import {useClickableContainer} from '../hooks/useClickableContainer';
|
|
@@ -48,6 +48,7 @@ import {useLinkComponent} from '../Link/useLinkComponent';
|
|
|
48
48
|
import {themeProps} from '../utils/themeProps';
|
|
49
49
|
import {focusOutlineProps} from '../utils/focusOutline.stylex';
|
|
50
50
|
|
|
51
|
+
import {useMergedRefs} from '../hooks/useMergedRefs';
|
|
51
52
|
// =============================================================================
|
|
52
53
|
// Styles — only the interactive layer, Card handles everything else
|
|
53
54
|
// =============================================================================
|
|
@@ -297,7 +298,7 @@ export function ClickableCard({
|
|
|
297
298
|
|
|
298
299
|
return (
|
|
299
300
|
<Card
|
|
300
|
-
ref={
|
|
301
|
+
ref={useMergedRefs(ref, containerRef)}
|
|
301
302
|
width={width}
|
|
302
303
|
height={height}
|
|
303
304
|
maxWidth={maxWidth}
|
|
@@ -95,6 +95,12 @@ export const docs = {
|
|
|
95
95
|
type: 'SyntaxThemeDefinition',
|
|
96
96
|
description: 'Per-instance syntax theme override. Shorthand for wrapping the block in <SyntaxTheme theme={...}>. Accepts a preset from @astryxdesign/core/theme/syntax or a theme created with defineSyntaxTheme(). Defaults to the nearest SyntaxTheme ancestor or the theme-level syntax colors.',
|
|
97
97
|
},
|
|
98
|
+
{
|
|
99
|
+
name: 'highlightMode',
|
|
100
|
+
type: "'auto' | 'ranges' | 'spans'",
|
|
101
|
+
description: 'Syntax highlighting rendering mode.',
|
|
102
|
+
default: "'auto'",
|
|
103
|
+
},
|
|
98
104
|
{
|
|
99
105
|
name: 'isCollapsible',
|
|
100
106
|
type: 'boolean',
|
|
@@ -16,7 +16,7 @@ import {useCallback, useEffect, useRef, type ReactNode} from 'react';
|
|
|
16
16
|
import * as stylex from '@stylexjs/stylex';
|
|
17
17
|
import {Icon} from '../Icon';
|
|
18
18
|
import {Spinner} from '../Spinner';
|
|
19
|
-
import {mergeProps
|
|
19
|
+
import {mergeProps} from '../utils';
|
|
20
20
|
import {
|
|
21
21
|
colorVars,
|
|
22
22
|
typeScaleVars,
|
|
@@ -29,6 +29,7 @@ import type {BaseProps} from '../BaseProps';
|
|
|
29
29
|
import {themeProps} from '../utils/themeProps';
|
|
30
30
|
import {useTranslator} from '../i18n';
|
|
31
31
|
|
|
32
|
+
import {useMergedRefs} from '../hooks/useMergedRefs';
|
|
32
33
|
const styles = stylex.create({
|
|
33
34
|
wrapper: {
|
|
34
35
|
display: 'flex',
|
|
@@ -216,7 +217,7 @@ export function CommandPaletteInput({
|
|
|
216
217
|
<Icon icon="search" size="sm" color="inherit" />
|
|
217
218
|
</span>
|
|
218
219
|
<input
|
|
219
|
-
ref={
|
|
220
|
+
ref={useMergedRefs(ref, inputRef)}
|
|
220
221
|
type="text"
|
|
221
222
|
role="combobox"
|
|
222
223
|
aria-expanded={ctx?.isOpen ?? true}
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
import {useCallback, useEffect, useMemo, useRef, type ReactNode} from 'react';
|
|
15
15
|
import * as stylex from '@stylexjs/stylex';
|
|
16
16
|
import type {BaseProps} from '../BaseProps';
|
|
17
|
-
import {mergeProps
|
|
17
|
+
import {mergeProps} from '../utils';
|
|
18
18
|
import {composeEventHandlers} from '../utils/composeEventHandlers';
|
|
19
19
|
import {
|
|
20
20
|
colorVars,
|
|
@@ -27,6 +27,7 @@ import {useCommandPaletteContext} from './CommandPaletteContext';
|
|
|
27
27
|
import {useDialogContext} from '../Dialog/DialogContext';
|
|
28
28
|
import {themeProps} from '../utils/themeProps';
|
|
29
29
|
|
|
30
|
+
import {useMergedRefs} from '../hooks/useMergedRefs';
|
|
30
31
|
const HOVER_HOVER = '@media (hover: hover)';
|
|
31
32
|
|
|
32
33
|
const styles = stylex.create({
|
|
@@ -191,7 +192,7 @@ export function CommandPaletteItem({
|
|
|
191
192
|
|
|
192
193
|
return (
|
|
193
194
|
<div
|
|
194
|
-
ref={
|
|
195
|
+
ref={useMergedRefs(ref, itemRef)}
|
|
195
196
|
{...props}
|
|
196
197
|
id={ctx && itemIndex >= 0 ? ctx.getItemId(itemIndex) : undefined}
|
|
197
198
|
role="option"
|
|
@@ -58,6 +58,11 @@ export const docs = {
|
|
|
58
58
|
description: 'Accessible name for the menu surface, announced when it opens.',
|
|
59
59
|
default: "'Context menu'",
|
|
60
60
|
},
|
|
61
|
+
{
|
|
62
|
+
name: 'onOpenChange',
|
|
63
|
+
type: '(isOpen: boolean) => void',
|
|
64
|
+
description: 'Callback fired when the menu opens or closes.',
|
|
65
|
+
},
|
|
61
66
|
{
|
|
62
67
|
name: 'isDisabled',
|
|
63
68
|
type: 'boolean',
|
|
@@ -63,7 +63,7 @@ import {
|
|
|
63
63
|
easeVars,
|
|
64
64
|
shadowVars,
|
|
65
65
|
} from '../theme/tokens.stylex';
|
|
66
|
-
import {mergeProps,
|
|
66
|
+
import {mergeProps, isImeKeyEvent} from '../utils';
|
|
67
67
|
import type {BaseProps} from '../BaseProps';
|
|
68
68
|
import type {StyleXStyles} from '../theme/types';
|
|
69
69
|
import {themeProps} from '../utils/themeProps';
|
|
@@ -75,6 +75,7 @@ import type {
|
|
|
75
75
|
DropdownMenuSection,
|
|
76
76
|
} from '../DropdownMenu/DropdownMenu';
|
|
77
77
|
|
|
78
|
+
import {useMergedRefs} from '../hooks/useMergedRefs';
|
|
78
79
|
const styles = stylex.create({
|
|
79
80
|
// Trigger wrapper: suppress the iOS long-press callout/selection so the
|
|
80
81
|
// long-press opens our context menu instead of the native text/callout UI.
|
|
@@ -467,7 +468,7 @@ export function ContextMenu({
|
|
|
467
468
|
return (
|
|
468
469
|
<>
|
|
469
470
|
<div
|
|
470
|
-
ref={
|
|
471
|
+
ref={useMergedRefs(ref, triggerRef)}
|
|
471
472
|
{...triggerProps}
|
|
472
473
|
onContextMenu={handleContextMenu}
|
|
473
474
|
{...longPressHandlers}
|
|
@@ -482,7 +483,7 @@ export function ContextMenu({
|
|
|
482
483
|
)}>
|
|
483
484
|
{children}
|
|
484
485
|
<span
|
|
485
|
-
ref={
|
|
486
|
+
ref={useMergedRefs(cursorAnchorRef, layer.ref)}
|
|
486
487
|
aria-hidden="true"
|
|
487
488
|
{...mergeProps(stylex.props(styles.cursorAnchor), {
|
|
488
489
|
style: {
|
|
@@ -161,7 +161,7 @@ export type {
|
|
|
161
161
|
InputStatus as DateInputStatus,
|
|
162
162
|
InputStatusType as DateInputStatusType,
|
|
163
163
|
} from '../Field';
|
|
164
|
-
import {mergeProps,
|
|
164
|
+
import {mergeProps, isFocusDetached} from '../utils';
|
|
165
165
|
import type {BaseProps} from '../BaseProps';
|
|
166
166
|
import type {SizeValue} from '../utils/types';
|
|
167
167
|
import {themeProps} from '../utils/themeProps';
|
|
@@ -169,6 +169,7 @@ import {focusOutlineStyles} from '../utils/focusOutline.stylex';
|
|
|
169
169
|
import {stableClassName} from '../naming';
|
|
170
170
|
import {useTranslator, InternationalizationContext} from '../i18n';
|
|
171
171
|
|
|
172
|
+
import {useMergedRefs} from '../hooks/useMergedRefs';
|
|
172
173
|
export interface DateInputProps extends Omit<
|
|
173
174
|
BaseProps,
|
|
174
175
|
'onChange' | 'defaultValue'
|
|
@@ -739,7 +740,7 @@ function PointerDateField({
|
|
|
739
740
|
/>
|
|
740
741
|
</button>
|
|
741
742
|
<input
|
|
742
|
-
ref={
|
|
743
|
+
ref={useMergedRefs(ref, inputRef)}
|
|
743
744
|
id={id}
|
|
744
745
|
type="text"
|
|
745
746
|
role="combobox"
|
|
@@ -419,6 +419,42 @@ describe('DateInput — field parity', () => {
|
|
|
419
419
|
expect(onChange).toHaveBeenCalledWith(undefined);
|
|
420
420
|
});
|
|
421
421
|
|
|
422
|
+
it('returns focus to the field without letting the page scroll', async () => {
|
|
423
|
+
// Clearing unmounts the clear button, and focusing another element in the
|
|
424
|
+
// same task as that unmount makes iOS Safari scroll the document to the
|
|
425
|
+
// top. Measured on the iOS 26 simulator against the live docsite, field at
|
|
426
|
+
// scrollY 2055: synchronous focus lands at 0, deferred focus stays at
|
|
427
|
+
// 2055. `preventScroll` alone does not fix it, so both halves are
|
|
428
|
+
// asserted: the focus is deferred past the unmount, and it is passed
|
|
429
|
+
// preventScroll. jsdom implements no scrolling, so the guard is asserted
|
|
430
|
+
// at the call.
|
|
431
|
+
vi.useFakeTimers();
|
|
432
|
+
try {
|
|
433
|
+
render(
|
|
434
|
+
<DateInput
|
|
435
|
+
label="Ship date"
|
|
436
|
+
value="2026-03-21"
|
|
437
|
+
hasClear
|
|
438
|
+
onChange={() => {}}
|
|
439
|
+
/>,
|
|
440
|
+
);
|
|
441
|
+
const input = field();
|
|
442
|
+
const focus = vi.spyOn(input, 'focus');
|
|
443
|
+
|
|
444
|
+
fireEvent.click(screen.getByRole('button', {name: /Clear Ship date/}));
|
|
445
|
+
|
|
446
|
+
// Not synchronous — that is the whole point.
|
|
447
|
+
expect(focus).not.toHaveBeenCalled();
|
|
448
|
+
|
|
449
|
+
vi.runAllTimers();
|
|
450
|
+
|
|
451
|
+
expect(focus).toHaveBeenCalledWith({preventScroll: true});
|
|
452
|
+
focus.mockRestore();
|
|
453
|
+
} finally {
|
|
454
|
+
vi.useRealTimers();
|
|
455
|
+
}
|
|
456
|
+
});
|
|
457
|
+
|
|
422
458
|
it('does not open the picker until the field is tapped', () => {
|
|
423
459
|
withLayout(() => {
|
|
424
460
|
render(<DateInput label="Ship date" onChange={() => {}} />);
|
|
@@ -599,6 +599,16 @@ export function TouchDateField({
|
|
|
599
599
|
const [isSheetOpen, setIsSheetOpen] = useState(false);
|
|
600
600
|
const [isWheelOpen, setIsWheelOpen] = useState(false);
|
|
601
601
|
const scrollerHandleRef = useRef<MonthScrollerHandle | null>(null);
|
|
602
|
+
// Pending focus handoff from the clear button; see handleClear.
|
|
603
|
+
const clearFocusTimerRef = useRef<number | null>(null);
|
|
604
|
+
useEffect(
|
|
605
|
+
() => () => {
|
|
606
|
+
if (clearFocusTimerRef.current != null) {
|
|
607
|
+
clearTimeout(clearFocusTimerRef.current);
|
|
608
|
+
}
|
|
609
|
+
},
|
|
610
|
+
[],
|
|
611
|
+
);
|
|
602
612
|
|
|
603
613
|
const today = useMemo(() => plainDateToday(), []);
|
|
604
614
|
const selectedDate = useMemo(
|
|
@@ -708,7 +718,31 @@ export function TouchDateField({
|
|
|
708
718
|
|
|
709
719
|
const handleClear = useCallback(() => {
|
|
710
720
|
fireChange(undefined);
|
|
711
|
-
|
|
721
|
+
// Focus goes back to the field on the NEXT task, not synchronously.
|
|
722
|
+
//
|
|
723
|
+
// Clearing unmounts this button (it only renders while there is a value),
|
|
724
|
+
// and focusing another element in the same task as that unmount makes iOS
|
|
725
|
+
// Safari scroll the whole document to the top — the user is thrown from
|
|
726
|
+
// wherever the field sat to the start of the page. Measured on the iOS 26
|
|
727
|
+
// simulator against the live docsite, field at scrollY 2055: synchronous
|
|
728
|
+
// focus lands at 0, deferred focus stays at 2055.
|
|
729
|
+
//
|
|
730
|
+
// `preventScroll` alone does NOT fix it (verified: still 0) — this is not
|
|
731
|
+
// the browser's ordinary scroll-the-focused-element-into-view step, so the
|
|
732
|
+
// deferral is the load-bearing half. It is kept because the reveal scroll
|
|
733
|
+
// is real too, and unwanted for the same reason: the field the user just
|
|
734
|
+
// tapped is already on screen (+12px on a plain page without it).
|
|
735
|
+
//
|
|
736
|
+
// Skipping the focus entirely would also stop the scroll, but then focus
|
|
737
|
+
// dies with the unmounting button and lands on <body>.
|
|
738
|
+
const field = inputRef.current;
|
|
739
|
+
if (field == null) {
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
clearFocusTimerRef.current = window.setTimeout(() => {
|
|
743
|
+
clearFocusTimerRef.current = null;
|
|
744
|
+
field.focus({preventScroll: true});
|
|
745
|
+
}, 0);
|
|
712
746
|
}, [fireChange]);
|
|
713
747
|
|
|
714
748
|
/**
|
|
@@ -72,7 +72,6 @@ import {
|
|
|
72
72
|
adjustTime,
|
|
73
73
|
isImeKeyEvent,
|
|
74
74
|
mergeProps,
|
|
75
|
-
mergeRefs,
|
|
76
75
|
isFocusDetached,
|
|
77
76
|
} from '../utils';
|
|
78
77
|
import {
|
|
@@ -91,6 +90,7 @@ import {themeProps} from '../utils/themeProps';
|
|
|
91
90
|
import {focusOutlineStyles} from '../utils/focusOutline.stylex';
|
|
92
91
|
import {useTranslator, InternationalizationContext} from '../i18n';
|
|
93
92
|
|
|
93
|
+
import {useMergedRefs} from '../hooks/useMergedRefs';
|
|
94
94
|
export type ISODateTimeString = string & {
|
|
95
95
|
readonly __brand: 'ISODateTimeString';
|
|
96
96
|
};
|
|
@@ -1009,7 +1009,7 @@ export function DateTimeInput({
|
|
|
1009
1009
|
/>
|
|
1010
1010
|
</button>
|
|
1011
1011
|
<input
|
|
1012
|
-
ref={
|
|
1012
|
+
ref={useMergedRefs(ref, dateInputRef)}
|
|
1013
1013
|
id={dateInputId}
|
|
1014
1014
|
type="text"
|
|
1015
1015
|
role="combobox"
|
|
@@ -62,14 +62,14 @@ export const docs = {
|
|
|
62
62
|
{
|
|
63
63
|
name: 'width',
|
|
64
64
|
type: 'number | string',
|
|
65
|
-
description: '
|
|
65
|
+
description: 'Preferred width of the dialog in pixels or any CSS value. Standard dialogs clamp to their container and the dynamic viewport with spacing-token gutters so narrow viewports keep content on screen.',
|
|
66
66
|
default: '400',
|
|
67
67
|
},
|
|
68
68
|
{
|
|
69
69
|
name: 'maxHeight',
|
|
70
70
|
type: 'number | string',
|
|
71
|
-
description: 'Maximum height of the dialog.',
|
|
72
|
-
default: "'
|
|
71
|
+
description: 'Maximum height of the dialog. Defaults to a dynamic viewport value so browser UI changes are reflected where supported.',
|
|
72
|
+
default: "'75dvh'",
|
|
73
73
|
},
|
|
74
74
|
{
|
|
75
75
|
name: 'position',
|
|
@@ -90,6 +90,11 @@ export const docs = {
|
|
|
90
90
|
description: 'Controls dismissal behavior: required disables Escape and backdrop click; form disables backdrop click after interaction; info allows both.',
|
|
91
91
|
default: "'info'",
|
|
92
92
|
},
|
|
93
|
+
{
|
|
94
|
+
name: 'padding',
|
|
95
|
+
type: '0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10',
|
|
96
|
+
description: 'Internal padding of the dialog using the spacing scale step.',
|
|
97
|
+
},
|
|
93
98
|
{
|
|
94
99
|
name: 'isInline',
|
|
95
100
|
type: 'boolean',
|