@astryxdesign/core 0.5.2-canary.2da7a39 → 0.5.2-canary.2e51213
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/dist/AppShell/AppShell.d.ts +2 -2
- package/dist/AppShell/AppShell.d.ts.map +1 -1
- package/dist/AppShell/AppShell.js +10 -7
- package/dist/Banner/Banner.d.ts +5 -0
- package/dist/Banner/Banner.d.ts.map +1 -1
- package/dist/Banner/Banner.js +7 -2
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts +3 -2
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.js +22 -15
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +2 -2
- package/dist/Chat/ChatComposer.d.ts +2 -2
- package/dist/Chat/ChatComposer.d.ts.map +1 -1
- package/dist/Chat/ChatComposer.js +21 -2
- package/dist/Chat/ChatToolCalls.d.ts +1 -1
- package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
- package/dist/Chat/ChatToolCalls.js +12 -34
- package/dist/Chat/useChatNewMessages.js +3 -3
- package/dist/CheckboxList/CheckboxListItem.d.ts +5 -3
- package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.d.ts +47 -13
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +269 -162
- package/dist/DateTimeInput/NativeDateSegment.d.ts +24 -0
- package/dist/DateTimeInput/NativeDateSegment.d.ts.map +1 -0
- package/dist/DateTimeInput/NativeDateSegment.js +235 -0
- package/dist/DateTimeInput/NativeTimeSegment.d.ts +30 -0
- package/dist/DateTimeInput/NativeTimeSegment.d.ts.map +1 -0
- package/dist/DateTimeInput/NativeTimeSegment.js +248 -0
- package/dist/DateTimeInput/index.d.ts +1 -1
- package/dist/DateTimeInput/index.d.ts.map +1 -1
- package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts +95 -0
- package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts.map +1 -0
- package/dist/DateTimeInput/nativePickerSegmentStyles.js +103 -0
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +2 -4
- package/dist/Field/Field.d.ts.map +1 -1
- package/dist/Field/Field.js +10 -4
- package/dist/Field/PanelSearchInput.d.ts.map +1 -1
- package/dist/Field/PanelSearchInput.js +3 -5
- package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
- package/dist/FieldStatus/FieldStatus.js +4 -2
- package/dist/Layer/useTouchTrigger.d.ts.map +1 -1
- package/dist/Layer/useTouchTrigger.js +2 -4
- package/dist/Layout/Layout.d.ts +7 -8
- package/dist/Layout/Layout.d.ts.map +1 -1
- package/dist/Layout/Layout.js +7 -8
- package/dist/MultiSelector/MultiSelector.d.ts +11 -1
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +89 -45
- package/dist/RadioList/RadioListItem.d.ts +30 -5
- package/dist/RadioList/RadioListItem.d.ts.map +1 -1
- package/dist/RadioList/RadioListItem.js +17 -4
- package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
- package/dist/Resizable/ResizeHandle.js +102 -44
- package/dist/Resizable/index.d.ts +2 -0
- package/dist/Resizable/index.d.ts.map +1 -1
- package/dist/Resizable/index.js +1 -0
- package/dist/Resizable/useResizable.d.ts +89 -8
- package/dist/Resizable/useResizable.d.ts.map +1 -1
- package/dist/Resizable/useResizable.js +521 -38
- package/dist/Resizable/utils.d.ts +35 -0
- package/dist/Resizable/utils.d.ts.map +1 -0
- package/dist/Resizable/utils.js +27 -0
- package/dist/Selector/Selector.d.ts +10 -0
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +105 -57
- package/dist/Selector/useSelectorPresentation.d.ts +1 -0
- package/dist/Selector/useSelectorPresentation.d.ts.map +1 -1
- package/dist/Selector/useSelectorPresentation.js +17 -2
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +3 -5
- package/dist/Spinner/Spinner.d.ts.map +1 -1
- package/dist/Spinner/Spinner.js +9 -10
- package/dist/Stepper/Step.d.ts +2 -1
- package/dist/Stepper/Step.d.ts.map +1 -1
- package/dist/Stepper/Step.js +75 -11
- package/dist/Stepper/Stepper.d.ts.map +1 -1
- package/dist/Stepper/Stepper.js +1 -0
- package/dist/TabList/TabList.d.ts.map +1 -1
- package/dist/TabList/TabList.js +2 -3
- package/dist/Table/index.d.ts +16 -1
- package/dist/Table/index.d.ts.map +1 -1
- package/dist/Table/index.js +4 -0
- package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
- package/dist/Table/plugins/columnResize/useTableColumnResize.js +8 -9
- package/dist/Table/plugins/rowStatus/index.d.ts +1 -1
- package/dist/Table/plugins/rowStatus/index.d.ts.map +1 -1
- package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts +11 -30
- package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts.map +1 -1
- package/dist/Table/plugins/rowStatus/useTableRowStatus.js +108 -62
- package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
- package/dist/Table/plugins/sortable/useTableSortable.js +9 -1
- package/dist/Text/useTruncation.d.ts +1 -1
- package/dist/Text/useTruncation.d.ts.map +1 -1
- package/dist/Text/useTruncation.js +8 -7
- package/dist/TimeInput/TimeInput.d.ts +16 -1
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +98 -60
- package/dist/TimeInput/index.d.ts +1 -1
- package/dist/TimeInput/index.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.d.ts +2 -2
- package/dist/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +4 -145
- package/dist/Timestamp/formatRelativeTime.d.ts +20 -0
- package/dist/Timestamp/formatRelativeTime.d.ts.map +1 -0
- package/dist/Timestamp/formatRelativeTime.js +81 -0
- package/dist/Toast/ToastViewport.d.ts.map +1 -1
- package/dist/Toast/ToastViewport.js +125 -77
- package/dist/Tokenizer/Tokenizer.d.ts +0 -38
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +94 -26
- package/dist/Tokenizer/useEndLaneReserve.d.ts +31 -0
- package/dist/Tokenizer/useEndLaneReserve.d.ts.map +1 -0
- package/dist/Tokenizer/useEndLaneReserve.js +136 -0
- package/dist/Tooltip/useTooltip.d.ts +1 -1
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +53 -42
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +85 -30
- package/dist/Typeahead/Typeahead.d.ts +0 -21
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +108 -67
- package/dist/Typeahead/busyIndicatorLane.d.ts +62 -0
- package/dist/Typeahead/busyIndicatorLane.d.ts.map +1 -0
- package/dist/Typeahead/busyIndicatorLane.js +98 -0
- package/dist/astryx.css +25 -7
- package/dist/hooks/useFocusReturnVisibility.d.ts.map +1 -1
- package/dist/hooks/useFocusReturnVisibility.js +3 -5
- package/dist/hooks/useIsomorphicLayoutEffect.d.ts +2 -2
- package/dist/hooks/useIsomorphicLayoutEffect.d.ts.map +1 -1
- package/dist/hooks/useOverflow.js +11 -11
- package/dist/hooks/useScrollOverflow.d.ts.map +1 -1
- package/dist/hooks/useScrollOverflow.js +7 -4
- package/dist/theme/defineTheme.d.ts +13 -0
- package/dist/theme/defineTheme.d.ts.map +1 -1
- package/dist/theme/defineTheme.js +7 -0
- package/dist/theme/generateThemeRules.d.ts.map +1 -1
- package/dist/theme/generateThemeRules.js +1 -1
- package/dist/theme/localTokens.d.ts +18 -0
- package/dist/theme/localTokens.d.ts.map +1 -0
- package/dist/theme/localTokens.js +162 -0
- package/dist/utils/interactionModality.d.ts +6 -28
- package/dist/utils/interactionModality.d.ts.map +1 -1
- package/dist/utils/interactionModality.js +72 -37
- package/dist/utils/sharedResizeObserver.d.ts +17 -9
- package/dist/utils/sharedResizeObserver.d.ts.map +1 -1
- package/dist/utils/sharedResizeObserver.js +54 -12
- package/locales/en.json +8 -0
- package/locales/pseudo.json +6 -0
- package/package.json +7 -2
- package/src/AlertDialog/useImperativeAlertDialog.test.tsx +163 -0
- package/src/AppShell/AppShell.doc.mjs +4 -3
- package/src/AppShell/AppShell.test.tsx +21 -0
- package/src/AppShell/AppShell.tsx +12 -7
- package/src/Banner/Banner.doc.mjs +5 -1
- package/src/Banner/Banner.tsx +12 -1
- package/src/BottomSheet/BottomSheet.doc.mjs +31 -0
- package/src/BottomSheet/BottomSheet.spec.md +178 -0
- package/src/Breadcrumbs/BreadcrumbItem.tsx +18 -9
- package/src/Breadcrumbs/Breadcrumbs.doc.mjs +4 -1
- package/src/Breadcrumbs/Breadcrumbs.test.tsx +12 -0
- package/src/Button/Button.doc.mjs +56 -0
- package/src/ButtonGroup/ButtonGroup.doc.mjs +47 -0
- package/src/Calendar/hooks/useCalendarConstraints.test.ts +153 -0
- package/src/Calendar/hooks/useCalendarDays.test.ts +265 -0
- package/src/Calendar/hooks/useCalendarNavigation.test.ts +252 -0
- package/src/Carousel/Carousel.test.tsx +83 -0
- package/src/Carousel/Carousel.tsx +8 -2
- package/src/Chat/ChatComposer.doc.mjs +7 -4
- package/src/Chat/ChatComposer.test.tsx +84 -2
- package/src/Chat/ChatComposer.tsx +45 -3
- package/src/Chat/ChatSendButton.test.tsx +189 -0
- package/src/Chat/ChatToolCalls.doc.mjs +1 -1
- package/src/Chat/ChatToolCalls.test.tsx +33 -1
- package/src/Chat/ChatToolCalls.tsx +13 -34
- package/src/Chat/useChatNewMessages.ts +3 -3
- package/src/Chat/useChatPasteAsToken.test.ts +191 -0
- package/src/CheckboxList/CheckboxList.doc.mjs +172 -31
- package/src/CheckboxList/CheckboxList.spec.md +215 -0
- package/src/CheckboxList/CheckboxList.test.tsx +45 -0
- package/src/CheckboxList/CheckboxListItem.doc.mjs +11 -9
- package/src/CheckboxList/CheckboxListItem.tsx +5 -3
- package/src/Collapsible/useCollapsible.test.tsx +236 -0
- package/src/CommandPalette/CommandPalette.doc.mjs +72 -0
- package/src/CommandPalette/CommandPalette.spec.md +224 -0
- package/src/CommandPalette/CommandPaletteEmpty.test.tsx +101 -0
- package/src/ComplexSelector/ComplexSelector.doc.mjs +42 -0
- package/src/ComplexSelector/ComplexSelector.spec.md +190 -0
- package/src/ContextMenu/ContextMenu.doc.mjs +48 -0
- package/src/ContextMenu/ContextMenu.spec.md +207 -0
- package/src/DateTimeInput/DateTimeInput.doc.mjs +43 -23
- package/src/DateTimeInput/DateTimeInput.tsx +388 -181
- package/src/DateTimeInput/DateTimeInputTouch.test.tsx +10 -2
- package/src/DateTimeInput/NativeDateSegment.tsx +308 -0
- package/src/DateTimeInput/NativePickerSegments.test.tsx +626 -0
- package/src/DateTimeInput/NativeTimeSegment.tsx +331 -0
- package/src/DateTimeInput/index.ts +1 -0
- package/src/DateTimeInput/nativePickerSegmentStyles.ts +120 -0
- package/src/Divider/Divider.doc.mjs +24 -0
- package/src/Divider/Divider.spec.md +157 -0
- package/src/DropdownMenu/DropdownMenu.doc.mjs +104 -0
- package/src/DropdownMenu/DropdownMenu.spec.md +246 -0
- package/src/DropdownMenu/DropdownMenu.tsx +2 -4
- package/src/Field/Field.doc.mjs +1 -0
- package/src/Field/Field.test.tsx +39 -0
- package/src/Field/Field.tsx +18 -1
- package/src/Field/InputClearButton.test.tsx +68 -6
- package/src/Field/PanelSearchInput.tsx +3 -5
- package/src/FieldStatus/FieldStatus.doc.mjs +21 -0
- package/src/FieldStatus/FieldStatus.spec.md +213 -0
- package/src/FieldStatus/FieldStatus.test.tsx +17 -0
- package/src/FieldStatus/FieldStatus.tsx +7 -2
- package/src/Grid/Grid.doc.mjs +19 -0
- package/src/Grid/Grid.spec.md +162 -0
- package/src/Icon/Icon.doc.mjs +196 -48
- package/src/Icon/Icon.spec.md +192 -0
- package/src/IconButton/IconButton.doc.mjs +38 -0
- package/src/Kbd/Kbd.doc.mjs +18 -0
- package/src/Kbd/Kbd.spec.md +142 -0
- package/src/Layer/useTouchTrigger.ts +2 -4
- package/src/Layout/Layout.doc.mjs +57 -17
- package/src/Layout/Layout.spec.md +235 -0
- package/src/Layout/Layout.test.tsx +1 -1
- package/src/Layout/Layout.tsx +7 -8
- package/src/Layout/LayoutHeader.doc.mjs +9 -0
- package/src/Layout/LayoutPanel.doc.mjs +4 -3
- package/src/Lightbox/Lightbox.doc.mjs +149 -33
- package/src/Lightbox/Lightbox.spec.md +198 -0
- package/src/Lightbox/useLightbox.test.tsx +263 -0
- package/src/Markdown/Markdown.doc.mjs +60 -0
- package/src/Markdown/Markdown.spec.md +207 -0
- package/src/MobileNav/MobileNav.doc.mjs +140 -32
- package/src/MobileNav/MobileNav.spec.md +209 -0
- package/src/MoreMenu/MoreMenu.doc.mjs +42 -0
- package/src/MoreMenu/MoreMenu.spec.md +222 -0
- package/src/MultiSelector/MultiSelector.doc.mjs +124 -1
- package/src/MultiSelector/MultiSelector.spec.md +293 -0
- package/src/MultiSelector/MultiSelector.test.tsx +305 -2
- package/src/MultiSelector/MultiSelector.tsx +124 -55
- package/src/NavIcon/NavIcon.doc.mjs +17 -0
- package/src/NavIcon/NavIcon.spec.md +134 -0
- package/src/NavMenu/NavHeadingMenu.spec.md +210 -0
- package/src/NavMenu/NavMenu.doc.mjs +37 -0
- package/src/Outline/Outline.doc.mjs +35 -0
- package/src/Outline/Outline.spec.md +162 -0
- package/src/OverflowList/OverflowList.doc.mjs +24 -0
- package/src/OverflowList/OverflowList.spec.md +157 -0
- package/src/Pagination/Pagination.doc.mjs +74 -0
- package/src/Pagination/Pagination.spec.md +226 -0
- package/src/Popover/Popover.doc.mjs +264 -65
- package/src/Popover/Popover.spec.md +421 -0
- package/src/Popover/usePopover.doc.mjs +208 -33
- package/src/PowerSearch/PowerSearch.spec.md +291 -0
- package/src/PowerSearch/PowerSearchFilterEditor.test.tsx +253 -0
- package/src/PowerSearch/PowerSearchToken.test.tsx +228 -0
- package/src/ProgressBar/ProgressBar.doc.mjs +198 -38
- package/src/ProgressBar/ProgressBar.spec.md +261 -0
- package/src/RadioList/RadioList.test.tsx +136 -2
- package/src/RadioList/RadioListItem.doc.mjs +30 -11
- package/src/RadioList/RadioListItem.tsx +44 -8
- package/src/Resizable/Resizable.doc.mjs +130 -24
- package/src/Resizable/Resizable.spec.md +246 -0
- package/src/Resizable/ResizeHandle.test.tsx +177 -56
- package/src/Resizable/ResizeHandle.tsx +128 -45
- package/src/Resizable/index.ts +2 -0
- package/src/Resizable/shippedDirections.test.ts +462 -0
- package/src/Resizable/useResizable.doc.mjs +124 -29
- package/src/Resizable/useResizable.test.ts +1277 -3
- package/src/Resizable/useResizable.ts +760 -48
- package/src/Resizable/utils.test.ts +74 -0
- package/src/Resizable/utils.ts +35 -0
- package/src/Section/Section.doc.mjs +17 -0
- package/src/Section/Section.spec.md +139 -0
- package/src/SegmentedControl/SegmentedControl.doc.mjs +83 -0
- package/src/SegmentedControl/SegmentedControl.spec.md +152 -0
- package/src/Selector/Selector.doc.mjs +133 -97
- package/src/Selector/Selector.spec.md +300 -0
- package/src/Selector/Selector.test.tsx +318 -1
- package/src/Selector/Selector.tsx +127 -60
- package/src/Selector/useSelectorPresentation.ts +24 -4
- package/src/SideNav/SideNav.test.tsx +3 -3
- package/src/SideNav/SideNavCollapseButton.doc.mjs +8 -0
- package/src/SideNav/SideNavItem.doc.mjs +1 -1
- package/src/Skeleton/Skeleton.doc.mjs +12 -0
- package/src/Skeleton/Skeleton.spec.md +127 -0
- package/src/Slider/Slider.doc.mjs +184 -30
- package/src/Slider/Slider.spec.md +224 -0
- package/src/Slider/Slider.tsx +2 -5
- package/src/Spinner/Spinner.doc.mjs +5 -5
- package/src/Spinner/Spinner.test.tsx +32 -7
- package/src/Spinner/Spinner.tsx +46 -14
- package/src/Stack/Stack.doc.mjs +22 -0
- package/src/Stack/Stack.spec.md +155 -0
- package/src/StatusDot/StatusDot.doc.mjs +17 -0
- package/src/StatusDot/StatusDot.spec.md +138 -0
- package/src/Stepper/Step.doc.mjs +1 -1
- package/src/Stepper/Step.tsx +118 -5
- package/src/Stepper/Stepper.doc.mjs +51 -1
- package/src/Stepper/Stepper.spec.md +245 -0
- package/src/Stepper/Stepper.test.tsx +315 -0
- package/src/Stepper/Stepper.tsx +8 -0
- package/src/Switch/Switch.doc.mjs +40 -0
- package/src/Switch/Switch.spec.md +175 -0
- package/src/TabList/TabList.tsx +2 -3
- package/src/Table/Table.doc.mjs +102 -24
- package/src/Table/Table.perf.test.tsx +51 -1
- package/src/Table/Table.spec.md +325 -0
- package/src/Table/TableHeaderCell.test.tsx +291 -0
- package/src/Table/index.ts +19 -4
- package/src/Table/plugins/columnResize/useTableColumnResize.tsx +8 -12
- package/src/Table/plugins/filtering/useTableFilterState.test.tsx +143 -0
- package/src/Table/plugins/groupedRows/useTableGroupedRows.test.tsx +2 -1
- package/src/Table/plugins/rowStatus/index.ts +1 -4
- package/src/Table/plugins/rowStatus/useTableRowStatus.public.test.ts +92 -0
- package/src/Table/plugins/rowStatus/useTableRowStatus.spec.md +354 -0
- package/src/Table/plugins/rowStatus/useTableRowStatus.test.tsx +431 -56
- package/src/Table/plugins/rowStatus/useTableRowStatus.tsx +155 -84
- package/src/Table/plugins/sortable/useTableSortable.test.tsx +72 -0
- package/src/Table/plugins/sortable/useTableSortable.tsx +18 -1
- package/src/Table/useTableGroupedRows.doc.mjs +2 -2
- package/src/Table/useTableRowStatus.doc.mjs +5 -5
- package/src/Text/Text.doc.mjs +190 -43
- package/src/Text/Text.spec.md +206 -0
- package/src/Text/useTruncation.ts +8 -7
- package/src/TextArea/TextArea.doc.mjs +255 -45
- package/src/TextArea/TextArea.spec.md +205 -0
- package/src/TimeInput/NativeTimeInput.test.tsx +269 -0
- package/src/TimeInput/TimeInput.doc.mjs +47 -23
- package/src/TimeInput/TimeInput.tsx +109 -50
- package/src/TimeInput/index.ts +1 -0
- package/src/Timestamp/Timestamp.doc.mjs +2 -2
- package/src/Timestamp/Timestamp.test.tsx +75 -3
- package/src/Timestamp/Timestamp.tsx +7 -153
- package/src/Timestamp/formatRelativeTime.ts +96 -0
- package/src/Toast/ToastViewport.test.tsx +194 -0
- package/src/Toast/ToastViewport.tsx +136 -58
- package/src/ToggleButton/ToggleButton.doc.mjs +56 -0
- package/src/Tokenizer/Tokenizer.doc.mjs +2 -0
- package/src/Tokenizer/Tokenizer.spec.md +293 -0
- package/src/Tokenizer/Tokenizer.test.tsx +335 -1
- package/src/Tokenizer/Tokenizer.tsx +129 -46
- package/src/Tokenizer/useEndLaneReserve.ts +146 -0
- package/src/Toolbar/Toolbar.doc.mjs +19 -0
- package/src/Toolbar/Toolbar.spec.md +174 -0
- package/src/Tooltip/Tooltip.doc.mjs +17 -0
- package/src/Tooltip/Tooltip.spec.md +142 -0
- package/src/Tooltip/Tooltip.test.tsx +21 -1
- package/src/Tooltip/useTooltip.test.tsx +318 -0
- package/src/Tooltip/useTooltip.tsx +60 -39
- package/src/TreeList/TreeList.doc.mjs +58 -0
- package/src/TreeList/TreeList.spec.md +224 -0
- package/src/Typeahead/BaseTypeahead.tsx +96 -25
- package/src/Typeahead/Typeahead.doc.mjs +89 -1
- package/src/Typeahead/Typeahead.spec.md +257 -0
- package/src/Typeahead/Typeahead.test.tsx +502 -1
- package/src/Typeahead/Typeahead.tsx +187 -69
- package/src/Typeahead/TypeaheadItem.test.tsx +93 -2
- package/src/Typeahead/busyIndicatorLane.tsx +109 -0
- package/src/__tests__/stylexDeclarations.ts +51 -0
- package/src/hooks/useFocusReturnVisibility.ts +3 -5
- package/src/hooks/useOverflow.ts +11 -11
- package/src/hooks/useScrollLock.test.ts +103 -0
- package/src/hooks/useScrollOverflow.ts +7 -4
- package/src/i18n/useTranslator.test.tsx +197 -0
- package/src/theme/defineTheme.test.ts +227 -0
- package/src/theme/defineTheme.ts +30 -0
- package/src/theme/derivedVarRegistry.test.ts +6 -0
- package/src/theme/generateThemeRules.ts +4 -1
- package/src/theme/localTokens.ts +272 -0
- package/src/theme/themingTargets.test.ts +126 -28
- package/src/utils/interactionModality.test.ts +83 -0
- package/src/utils/interactionModality.ts +88 -36
- package/src/utils/sharedResizeObserver.test.ts +124 -5
- package/src/utils/sharedResizeObserver.ts +60 -14
|
@@ -4,11 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @file DateTimeInput.tsx
|
|
7
|
-
* @input Uses React, Field, Calendar, usePopover, useAnnounce, time parsing utilities,
|
|
8
|
-
* @output Exports DateTimeInput component, DateTimeInputProps
|
|
7
|
+
* @input Uses React, Field, Calendar, NativeDateSegment, NativeTimeSegment, TouchDateTimeField, usePopover, useAnnounce, time parsing utilities, StyleX intrinsic flex layout
|
|
8
|
+
* @output Exports DateTimeInput component, DateTimeInputProps, and native picker type
|
|
9
9
|
* @position Core implementation; consumed by index.ts, tested by DateTimeInput.test.tsx
|
|
10
10
|
*
|
|
11
11
|
* SYNC: When modified, update these files to stay in sync:
|
|
12
|
+
* - /packages/core/src/DateTimeInput/NativeDateSegment.tsx (native date surface)
|
|
13
|
+
* - /packages/core/src/DateTimeInput/NativeTimeSegment.tsx (native time surface)
|
|
14
|
+
* - /packages/core/src/DateTimeInput/NativePickerSegments.test.tsx (native surface tests)
|
|
12
15
|
* - /packages/core/src/DateTimeInput/DateTimeInput.doc.mjs (props table, features, implementation notes)
|
|
13
16
|
* - /packages/core/src/DateTimeInput/DateTimeInput.test.tsx (desktop tests for new/changed behavior)
|
|
14
17
|
* - /packages/core/src/DateTimeInput/DateTimeInputTouch.test.tsx (touch-surface tests)
|
|
@@ -40,6 +43,8 @@ import { themeProps } from "../utils/themeProps.js";
|
|
|
40
43
|
import { focusOutlineStyles } from "../utils/focusOutline.stylex.js";
|
|
41
44
|
import { useLocale, useTranslator } from "../i18n/index.js";
|
|
42
45
|
import { useMergedRefs } from "../hooks/useMergedRefs.js";
|
|
46
|
+
import { NativeDateSegment } from "./NativeDateSegment.js";
|
|
47
|
+
import { NativeTimeSegment } from "./NativeTimeSegment.js";
|
|
43
48
|
import { TouchDateTimeField } from "./TouchDateTimeField.js";
|
|
44
49
|
|
|
45
50
|
/** Supported minute increments for arrow-key stepping of the time field. */
|
|
@@ -48,7 +53,7 @@ import { TouchDateTimeField } from "./TouchDateTimeField.js";
|
|
|
48
53
|
* Supported minute cadences for the preset-time dropdown. Every value divides
|
|
49
54
|
* an hour evenly, so each option lands on a round clock time.
|
|
50
55
|
*/
|
|
51
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
56
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
52
57
|
// Two 196px segments plus the 8px gap fit at exactly 400px. Below that,
|
|
53
58
|
// flex wrapping moves each growing segment onto its own full-width row.
|
|
54
59
|
const HORIZONTAL_SEGMENT_BASIS = 196;
|
|
@@ -59,6 +64,10 @@ const styles = {
|
|
|
59
64
|
kOIVth: "x1txdalj",
|
|
60
65
|
$$css: true
|
|
61
66
|
},
|
|
67
|
+
nativeRow: {
|
|
68
|
+
k7Eaqz: "xfb3i0g",
|
|
69
|
+
$$css: true
|
|
70
|
+
},
|
|
62
71
|
iconButton: {
|
|
63
72
|
k1xSpc: "x78zum5",
|
|
64
73
|
kGNEyG: "x6s0dn4",
|
|
@@ -134,6 +143,7 @@ const timeOptionSizeStyles = {
|
|
|
134
143
|
$$css: true
|
|
135
144
|
}
|
|
136
145
|
};
|
|
146
|
+
const TOUCH_POINTER_QUERY = '(pointer: coarse)';
|
|
137
147
|
const sizeStyles = {
|
|
138
148
|
sm: {
|
|
139
149
|
kZKoxP: "x6k0iem",
|
|
@@ -225,6 +235,7 @@ function PointerDateTimeField({
|
|
|
225
235
|
labelTooltip,
|
|
226
236
|
numberOfMonths = 1,
|
|
227
237
|
weekStartsOn,
|
|
238
|
+
nativePicker = 'touch',
|
|
228
239
|
width,
|
|
229
240
|
xstyle,
|
|
230
241
|
className,
|
|
@@ -234,6 +245,12 @@ function PointerDateTimeField({
|
|
|
234
245
|
}) {
|
|
235
246
|
const t = useTranslator();
|
|
236
247
|
const locale = useLocale();
|
|
248
|
+
const isTouch = useMediaQuery(TOUCH_POINTER_QUERY);
|
|
249
|
+
const usesNativePicker = nativePicker === 'always' || nativePicker === 'touch' && isTouch;
|
|
250
|
+
// iOS's native time picker has no seconds wheel, treats step as validation
|
|
251
|
+
// rather than picker cadence, and cannot express our preset-time list. Keep
|
|
252
|
+
// the Astryx time field for those explicit contracts instead of losing them.
|
|
253
|
+
const usesNativeTimePicker = usesNativePicker && !hasSeconds && timeIncrement === 1 && timeOptionInterval === undefined;
|
|
237
254
|
const isEffectivelyRequired = useResolvedRequired({
|
|
238
255
|
isRequired,
|
|
239
256
|
isOptional
|
|
@@ -250,14 +267,20 @@ function PointerDateTimeField({
|
|
|
250
267
|
const descriptionID = useId();
|
|
251
268
|
const statusMessageID = useId();
|
|
252
269
|
const dateInputRef = useRef(null);
|
|
270
|
+
const mergedDateInputRef = useMergedRefs(ref, dateInputRef);
|
|
253
271
|
const timeInputRef = useRef(null);
|
|
254
272
|
const timeContainerRef = useRef(null);
|
|
255
273
|
const calendarRef = useRef(null);
|
|
256
274
|
const lastFiredDateRef = useRef(undefined);
|
|
257
275
|
const [, startTransition] = useTransition();
|
|
258
276
|
const [optimisticValue, setOptimisticValue] = useOptimistic(value);
|
|
259
|
-
const
|
|
260
|
-
const
|
|
277
|
+
const isPendingChange = optimisticValue !== value;
|
|
278
|
+
const isBusy = isLoading || isPendingChange;
|
|
279
|
+
// A native wheel emits several edits while it remains open. Disabling the
|
|
280
|
+
// control after the first optimistic edit detaches the iOS picker, so pending
|
|
281
|
+
// changeAction work stays interactive just like TouchDateTimeField. Explicit
|
|
282
|
+
// loading still disables every surface.
|
|
283
|
+
const isEffectivelyDisabled = isDisabled || isLoading || !usesNativePicker && isPendingChange;
|
|
261
284
|
|
|
262
285
|
// Disabled-reason tooltip. Disabled controls swallow pointer events, so the
|
|
263
286
|
// tooltip listeners attach to the outer row container (which already exists)
|
|
@@ -336,6 +359,17 @@ function PointerDateTimeField({
|
|
|
336
359
|
// --- Time input state ---
|
|
337
360
|
const [timePendingInput, setTimePendingInput] = useState(null);
|
|
338
361
|
const [isTimeFocused, setIsTimeFocused] = useState(false);
|
|
362
|
+
// Native date and time are separate OS pickers. Hold a time chosen before the
|
|
363
|
+
// date exists, then combine it when the date picker commits.
|
|
364
|
+
const [nativeTimeDraft, setNativeTimeDraft] = useState(undefined);
|
|
365
|
+
const previousNativeValueRef = useRef(optimisticValue);
|
|
366
|
+
if (optimisticValue !== previousNativeValueRef.current) {
|
|
367
|
+
previousNativeValueRef.current = optimisticValue;
|
|
368
|
+
if (nativeTimeDraft !== undefined) {
|
|
369
|
+
setNativeTimeDraft(undefined);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
const nativeTimeValue = nativeTimeDraft ?? valueParts.time;
|
|
339
373
|
const formatDisplayTime = hourFormat === '12h' ? formatDisplayTime12h : formatDisplayTime24h;
|
|
340
374
|
const timeDisplayValue = useMemo(() => {
|
|
341
375
|
if (timePendingInput !== null) {
|
|
@@ -371,9 +405,9 @@ function PointerDateTimeField({
|
|
|
371
405
|
// Opt-in: without timeOptionInterval the time field keeps exactly the
|
|
372
406
|
// semantics it shipped with — a plain text input, no combobox role, no
|
|
373
407
|
// second listbox in the accessibility tree.
|
|
374
|
-
const hasTimeOptions = timeOptionInterval !== undefined;
|
|
408
|
+
const hasTimeOptions = !usesNativeTimePicker && timeOptionInterval !== undefined;
|
|
375
409
|
const timeOptions = useMemo(() => {
|
|
376
|
-
if (timeOptionInterval === undefined) {
|
|
410
|
+
if (!hasTimeOptions || timeOptionInterval === undefined) {
|
|
377
411
|
return [];
|
|
378
412
|
}
|
|
379
413
|
const options = [];
|
|
@@ -394,11 +428,11 @@ function PointerDateTimeField({
|
|
|
394
428
|
});
|
|
395
429
|
}
|
|
396
430
|
return options;
|
|
397
|
-
}, [timeOptionInterval, hasSeconds, timeMin, timeMax, formatDisplayTime]);
|
|
431
|
+
}, [hasTimeOptions, timeOptionInterval, hasSeconds, timeMin, timeMax, formatDisplayTime]);
|
|
398
432
|
|
|
399
433
|
// --- Unified change handler ---
|
|
400
434
|
const fireChange = useCallback(newValue => {
|
|
401
|
-
if (
|
|
435
|
+
if (isEffectivelyDisabled) {
|
|
402
436
|
return;
|
|
403
437
|
}
|
|
404
438
|
onChange(newValue);
|
|
@@ -408,7 +442,7 @@ function PointerDateTimeField({
|
|
|
408
442
|
await changeAction(newValue);
|
|
409
443
|
});
|
|
410
444
|
}
|
|
411
|
-
}, [
|
|
445
|
+
}, [isEffectivelyDisabled, onChange, changeAction, startTransition, setOptimisticValue]);
|
|
412
446
|
|
|
413
447
|
// --- Popover ---
|
|
414
448
|
const popover = usePopover({
|
|
@@ -446,7 +480,7 @@ function PointerDateTimeField({
|
|
|
446
480
|
|
|
447
481
|
// --- Date handlers ---
|
|
448
482
|
const handleDateChange = useCallback((newDate, source) => {
|
|
449
|
-
const currentTime = valueParts.time ?? getDefaultTime(hasSeconds);
|
|
483
|
+
const currentTime = valueParts.time ?? nativeTimeDraft ?? getDefaultTime(hasSeconds);
|
|
450
484
|
let effectiveTime = currentTime;
|
|
451
485
|
if (minParts.date && newDate === minParts.date && minParts.time) {
|
|
452
486
|
if (!isTimeInRange(effectiveTime, minParts.time, undefined)) {
|
|
@@ -466,7 +500,34 @@ function PointerDateTimeField({
|
|
|
466
500
|
setDatePendingInput(null);
|
|
467
501
|
popover.hide();
|
|
468
502
|
}
|
|
469
|
-
}, [valueParts.time, hasSeconds, minParts, maxParts, fireChange, popover]);
|
|
503
|
+
}, [valueParts.time, nativeTimeDraft, hasSeconds, minParts, maxParts, fireChange, popover]);
|
|
504
|
+
const handleNativeDateChange = useCallback(newDate => {
|
|
505
|
+
if (newDate === undefined) {
|
|
506
|
+
fireChange(undefined);
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
handleDateChange(newDate, 'input');
|
|
510
|
+
}, [fireChange, handleDateChange]);
|
|
511
|
+
const handleNativeTimeChange = useCallback(newTime => {
|
|
512
|
+
if (newTime === undefined) {
|
|
513
|
+
setNativeTimeDraft(undefined);
|
|
514
|
+
if (optimisticValue !== undefined) {
|
|
515
|
+
fireChange(undefined);
|
|
516
|
+
}
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
if (valueParts.date) {
|
|
520
|
+
const combined = combineDateTime(valueParts.date, newTime);
|
|
521
|
+
if (combined) {
|
|
522
|
+
fireChange(combined);
|
|
523
|
+
}
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
// A datetime cannot be emitted until its date exists, but the OS time
|
|
527
|
+
// picker is independently reachable. Preserve this draft for the date
|
|
528
|
+
// commit instead of making the user's first choice disappear.
|
|
529
|
+
setNativeTimeDraft(newTime);
|
|
530
|
+
}, [fireChange, optimisticValue, valueParts.date]);
|
|
470
531
|
const handleDateInputChange = useCallback(e => {
|
|
471
532
|
// With a disabledMessage the input drops `disabled` for focusability, so
|
|
472
533
|
// guard value mutation explicitly (readOnly also blocks typing).
|
|
@@ -875,9 +936,12 @@ function PointerDateTimeField({
|
|
|
875
936
|
|
|
876
937
|
// --- Clear ---
|
|
877
938
|
const handleClear = useCallback(() => {
|
|
939
|
+
setNativeTimeDraft(undefined);
|
|
878
940
|
fireChange(undefined);
|
|
879
|
-
|
|
880
|
-
|
|
941
|
+
if (!usesNativePicker) {
|
|
942
|
+
dateInputRef.current?.focus();
|
|
943
|
+
}
|
|
944
|
+
}, [fireChange, usesNativePicker]);
|
|
881
945
|
|
|
882
946
|
// Focus time input when clicking wrapper padding/icon
|
|
883
947
|
const {
|
|
@@ -912,81 +976,98 @@ function PointerDateTimeField({
|
|
|
912
976
|
size,
|
|
913
977
|
status: status?.type ?? null,
|
|
914
978
|
disabled: isDisabled ? 'disabled' : null
|
|
915
|
-
}), stylex.props(styles.row, xstyle), className, style),
|
|
979
|
+
}), stylex.props(styles.row, usesNativePicker && styles.nativeRow, xstyle), className, style),
|
|
916
980
|
children: [/*#__PURE__*/_jsxs("div", {
|
|
917
|
-
ref: popover.triggerRef,
|
|
981
|
+
ref: usesNativePicker ? undefined : popover.triggerRef,
|
|
918
982
|
...mergeProps(themeProps('date-time-input-date-segment', {
|
|
919
983
|
size,
|
|
920
984
|
status: status?.type ?? null
|
|
921
985
|
}), stylex.props(inputWrapperStyles.base, sizeStyles[size], styles.dateWrapper, isEffectivelyDisabled && inputWrapperStyles.disabled, status && inputStatusBorderStyles[status.type], status && !isEffectivelyDisabled && inputStatusHoverShadowStyles[status.type], status && inputStatusFocusWithinStyles[status.type])),
|
|
922
|
-
children: [/*#__PURE__*/_jsx(
|
|
923
|
-
type: "button",
|
|
924
|
-
onClick: handleCalendarToggle,
|
|
925
|
-
disabled: isEffectivelyDisabled,
|
|
926
|
-
"aria-label": popover.isOpen ? t('@astryx.dateInput.toggleCalendarClose') : t('@astryx.dateInput.openCalendar'),
|
|
927
|
-
...stylex.props(focusOutlineStyles.focusVisible, styles.iconButton, isEffectivelyDisabled && styles.iconButtonDisabled),
|
|
928
|
-
children: /*#__PURE__*/_jsx(Icon, {
|
|
929
|
-
icon: "calendar",
|
|
930
|
-
size: "sm",
|
|
931
|
-
color: "secondary"
|
|
932
|
-
// Stable theme target on the calendar toggle glyph, so a theme
|
|
933
|
-
// can restyle just this icon (color, size, hover) — and each
|
|
934
|
-
// open/closed state — via `defineTheme`, mirroring
|
|
935
|
-
// `date-input-toggle-icon`. Same-element rules in
|
|
936
|
-
// @layer astryx-theme win over the icon's own base color/size,
|
|
937
|
-
// which a segment-level target could not reach.
|
|
938
|
-
,
|
|
939
|
-
...themeProps('date-time-input-toggle-icon', {
|
|
940
|
-
state: popover.isOpen ? 'expanded' : 'collapsed'
|
|
941
|
-
})
|
|
942
|
-
})
|
|
943
|
-
}), /*#__PURE__*/_jsx("input", {
|
|
944
|
-
ref: useMergedRefs(ref, dateInputRef),
|
|
986
|
+
children: [usesNativePicker ? /*#__PURE__*/_jsx(NativeDateSegment, {
|
|
945
987
|
id: dateInputId,
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
"
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
}
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
988
|
+
inputRef: mergedDateInputRef,
|
|
989
|
+
value: valueParts.date,
|
|
990
|
+
onChange: handleNativeDateChange,
|
|
991
|
+
placeholder: placeholder,
|
|
992
|
+
min: calendarMin,
|
|
993
|
+
max: calendarMax,
|
|
994
|
+
isDateDisabled: isDateDisabled,
|
|
995
|
+
isEffectivelyDisabled: isEffectivelyDisabled,
|
|
996
|
+
hasDisabledMessage: showsDisabledMessage,
|
|
997
|
+
isEffectivelyRequired: isEffectivelyRequired,
|
|
998
|
+
isBusy: isBusy,
|
|
999
|
+
statusType: status?.type,
|
|
1000
|
+
ariaDescribedBy: ariaDescribedBy
|
|
1001
|
+
}) : /*#__PURE__*/_jsxs(_Fragment, {
|
|
1002
|
+
children: [/*#__PURE__*/_jsx("button", {
|
|
1003
|
+
type: "button",
|
|
1004
|
+
onClick: handleCalendarToggle,
|
|
1005
|
+
disabled: isEffectivelyDisabled,
|
|
1006
|
+
"aria-label": popover.isOpen ? t('@astryx.dateInput.toggleCalendarClose') : t('@astryx.dateInput.openCalendar'),
|
|
1007
|
+
...stylex.props(focusOutlineStyles.focusVisible, styles.iconButton, isEffectivelyDisabled && styles.iconButtonDisabled),
|
|
1008
|
+
children: /*#__PURE__*/_jsx(Icon, {
|
|
1009
|
+
icon: "calendar",
|
|
1010
|
+
size: "sm",
|
|
1011
|
+
color: "secondary"
|
|
1012
|
+
// Stable theme target on the calendar toggle glyph, so a theme
|
|
1013
|
+
// can restyle just this icon (color, size, hover) — and each
|
|
1014
|
+
// open/closed state — via `defineTheme`, mirroring
|
|
1015
|
+
// `date-input-toggle-icon`. Same-element rules in
|
|
1016
|
+
// @layer astryx-theme win over the icon's own base color/size,
|
|
1017
|
+
// which a segment-level target could not reach.
|
|
1018
|
+
,
|
|
1019
|
+
...themeProps('date-time-input-toggle-icon', {
|
|
1020
|
+
state: popover.isOpen ? 'expanded' : 'collapsed'
|
|
1021
|
+
})
|
|
1022
|
+
})
|
|
1023
|
+
}), /*#__PURE__*/_jsx("input", {
|
|
1024
|
+
ref: mergedDateInputRef,
|
|
1025
|
+
id: dateInputId,
|
|
1026
|
+
type: "text",
|
|
1027
|
+
role: "combobox",
|
|
1028
|
+
value: dateDisplayValue,
|
|
1029
|
+
onChange: handleDateInputChange,
|
|
1030
|
+
onBlur: handleDateBlur,
|
|
1031
|
+
onClick: handleDateInputClick,
|
|
1032
|
+
onKeyDown: handleDateKeyDown,
|
|
1033
|
+
placeholder: placeholder
|
|
1034
|
+
// With a disabledMessage the input keeps focusability via
|
|
1035
|
+
// aria-disabled so the reason is focus-discoverable; typing is
|
|
1036
|
+
// blocked with readOnly and the mutation guards, and calendar
|
|
1037
|
+
// activation is blocked by the isEffectivelyDisabled guards.
|
|
1038
|
+
,
|
|
1039
|
+
disabled: isEffectivelyDisabled && !showsDisabledMessage,
|
|
1040
|
+
"aria-disabled": showsDisabledMessage ? 'true' : undefined,
|
|
1041
|
+
readOnly: showsDisabledMessage || undefined,
|
|
1042
|
+
"aria-describedby": ariaDescribedBy,
|
|
1043
|
+
"aria-required": isEffectivelyRequired ? 'true' : undefined,
|
|
1044
|
+
"aria-invalid": status?.type === 'error' || !isDateInputValid ? 'true' : undefined,
|
|
1045
|
+
"aria-busy": isBusy || undefined,
|
|
1046
|
+
"aria-expanded": popover.isOpen,
|
|
1047
|
+
"aria-haspopup": "dialog",
|
|
1048
|
+
"aria-controls": popover.isOpen ? popover.id : undefined,
|
|
1049
|
+
"aria-autocomplete": "none",
|
|
1050
|
+
autoComplete: "off",
|
|
1051
|
+
...{
|
|
1052
|
+
0: {
|
|
1053
|
+
className: "x1lliihq x98rzlu xeuugli xc342km xng3xce x1717udv x9ynric xjm74w1 x6pjikd xw6l6zx x1tgivj0 xjbqb8w x1a2a7pz xeyghm5"
|
|
1054
|
+
},
|
|
1055
|
+
2: {
|
|
1056
|
+
className: "x1lliihq x98rzlu xeuugli xc342km xng3xce x1717udv x9ynric xjm74w1 x6pjikd xw6l6zx x1tgivj0 xjbqb8w x1a2a7pz xeyghm5 xt0e3qv"
|
|
1057
|
+
},
|
|
1058
|
+
1: {
|
|
1059
|
+
className: "x1lliihq x98rzlu xeuugli xc342km xng3xce x1717udv x9ynric xjm74w1 x6pjikd xw6l6zx xjbqb8w x1a2a7pz xeyghm5 xv1l7n4"
|
|
1060
|
+
},
|
|
1061
|
+
3: {
|
|
1062
|
+
className: "x1lliihq x98rzlu xeuugli xc342km xng3xce x1717udv x9ynric xjm74w1 x6pjikd xw6l6zx xjbqb8w x1a2a7pz xeyghm5 xt0e3qv xv1l7n4"
|
|
1063
|
+
}
|
|
1064
|
+
}[!!isEffectivelyDisabled << 1 | !!!isDateInputValid << 0]
|
|
1065
|
+
}), /*#__PURE__*/_jsx(VisuallyHidden, {
|
|
1066
|
+
as: "div",
|
|
1067
|
+
role: "alert",
|
|
1068
|
+
"aria-live": "assertive",
|
|
1069
|
+
children: !isDateInputValid ? t('@astryx.dateInput.invalidDate') : ''
|
|
1070
|
+
})]
|
|
990
1071
|
}), hasClear && value !== undefined && !isEffectivelyDisabled && /*#__PURE__*/_jsx(InputClearButton, {
|
|
991
1072
|
label: t('@astryx.dateInput.clear', {
|
|
992
1073
|
label
|
|
@@ -995,10 +1076,10 @@ function PointerDateTimeField({
|
|
|
995
1076
|
}), isBusy && /*#__PURE__*/_jsx(Spinner, {
|
|
996
1077
|
size: "sm"
|
|
997
1078
|
}), statusIcon]
|
|
998
|
-
}), /*#__PURE__*/
|
|
1079
|
+
}), /*#__PURE__*/_jsx("div", {
|
|
999
1080
|
ref: timeContainerRef,
|
|
1000
|
-
onClick: handleTimeWrapperClick,
|
|
1001
|
-
onMouseUp: handleTimeWrapperMouseUp
|
|
1081
|
+
onClick: usesNativeTimePicker ? undefined : handleTimeWrapperClick,
|
|
1082
|
+
onMouseUp: usesNativeTimePicker ? undefined : handleTimeWrapperMouseUp
|
|
1002
1083
|
// On the wrapper, not just the input: clicking the clock icon or the
|
|
1003
1084
|
// padding is routed to the input as a synthetic click, which would
|
|
1004
1085
|
// otherwise open the list mid-gesture and let light dismiss eat it.
|
|
@@ -1008,75 +1089,97 @@ function PointerDateTimeField({
|
|
|
1008
1089
|
size,
|
|
1009
1090
|
status: status?.type ?? null
|
|
1010
1091
|
}), stylex.props(inputWrapperStyles.base, sizeStyles[size], styles.timeWrapper, isEffectivelyDisabled && inputWrapperStyles.disabled, status && inputStatusBorderStyles[status.type], status && !isEffectivelyDisabled && inputStatusHoverShadowStyles[status.type], status && inputStatusFocusWithinStyles[status.type])),
|
|
1011
|
-
children:
|
|
1012
|
-
...{
|
|
1013
|
-
className: "x78zum5 x6s0dn4 xl56j7k x2lah0s"
|
|
1014
|
-
},
|
|
1015
|
-
children: /*#__PURE__*/_jsx(Icon, {
|
|
1016
|
-
icon: "clock",
|
|
1017
|
-
size: "sm",
|
|
1018
|
-
color: "secondary"
|
|
1019
|
-
// Stable theme target on the leading clock glyph, so a theme can
|
|
1020
|
-
// restyle just this icon (color, size) via `defineTheme`. The
|
|
1021
|
-
// time segment has no toggle button — the clock is a static
|
|
1022
|
-
// leading affordance — so this carries no interactive state.
|
|
1023
|
-
,
|
|
1024
|
-
...themeProps('date-time-input-clock-icon')
|
|
1025
|
-
})
|
|
1026
|
-
}), /*#__PURE__*/_jsx("input", {
|
|
1027
|
-
ref: timeInputRef,
|
|
1092
|
+
children: usesNativeTimePicker ? /*#__PURE__*/_jsx(NativeTimeSegment, {
|
|
1028
1093
|
id: timeInputId,
|
|
1029
|
-
|
|
1030
|
-
value:
|
|
1031
|
-
onChange:
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
,
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
"aria-disabled": showsDisabledMessage ? 'true' : undefined,
|
|
1052
|
-
readOnly: showsDisabledMessage || undefined,
|
|
1053
|
-
"aria-label": resolvedTimeLabel,
|
|
1054
|
-
"aria-describedby": ariaDescribedBy,
|
|
1055
|
-
"aria-required": isEffectivelyRequired ? 'true' : undefined,
|
|
1056
|
-
"aria-invalid": status?.type === 'error' || !isTimeInputValid ? 'true' : undefined,
|
|
1057
|
-
"aria-busy": isBusy || undefined,
|
|
1058
|
-
...{
|
|
1059
|
-
0: {
|
|
1060
|
-
className: "x1lliihq x98rzlu xeuugli xc342km xng3xce x1717udv x9ynric xjm74w1 x6pjikd xw6l6zx x1tgivj0 xjbqb8w x1a2a7pz xeyghm5"
|
|
1061
|
-
},
|
|
1062
|
-
2: {
|
|
1063
|
-
className: "x1lliihq x98rzlu xeuugli xc342km xng3xce x1717udv x9ynric xjm74w1 x6pjikd xw6l6zx x1tgivj0 xjbqb8w x1a2a7pz xeyghm5 xt0e3qv"
|
|
1064
|
-
},
|
|
1065
|
-
1: {
|
|
1066
|
-
className: "x1lliihq x98rzlu xeuugli xc342km xng3xce x1717udv x9ynric xjm74w1 x6pjikd xw6l6zx xjbqb8w x1a2a7pz xeyghm5 xv1l7n4"
|
|
1094
|
+
inputRef: timeInputRef,
|
|
1095
|
+
value: nativeTimeValue,
|
|
1096
|
+
onChange: handleNativeTimeChange,
|
|
1097
|
+
placeholder: timePlaceholder,
|
|
1098
|
+
inputLabel: resolvedTimeLabel,
|
|
1099
|
+
openPickerLabel: t('@astryx.dateTimeInput.openTimePicker', {
|
|
1100
|
+
label: resolvedTimeLabel
|
|
1101
|
+
}),
|
|
1102
|
+
iconThemeProps: themeProps('date-time-input-clock-icon'),
|
|
1103
|
+
min: timeMin,
|
|
1104
|
+
max: timeMax,
|
|
1105
|
+
hourFormat: hourFormat,
|
|
1106
|
+
isEffectivelyDisabled: isEffectivelyDisabled,
|
|
1107
|
+
hasDisabledMessage: showsDisabledMessage,
|
|
1108
|
+
isEffectivelyRequired: isEffectivelyRequired,
|
|
1109
|
+
isBusy: isBusy,
|
|
1110
|
+
statusType: status?.type,
|
|
1111
|
+
ariaDescribedBy: ariaDescribedBy
|
|
1112
|
+
}) : /*#__PURE__*/_jsxs(_Fragment, {
|
|
1113
|
+
children: [/*#__PURE__*/_jsx("div", {
|
|
1114
|
+
...{
|
|
1115
|
+
className: "x78zum5 x6s0dn4 xl56j7k x2lah0s"
|
|
1067
1116
|
},
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1117
|
+
children: /*#__PURE__*/_jsx(Icon, {
|
|
1118
|
+
icon: "clock",
|
|
1119
|
+
size: "sm",
|
|
1120
|
+
color: "secondary"
|
|
1121
|
+
// Stable theme target on the leading clock glyph, so a theme can
|
|
1122
|
+
// restyle just this icon (color, size) via `defineTheme`. The
|
|
1123
|
+
// time segment has no toggle button — the clock is a static
|
|
1124
|
+
// leading affordance — so this carries no interactive state.
|
|
1125
|
+
,
|
|
1126
|
+
...themeProps('date-time-input-clock-icon')
|
|
1127
|
+
})
|
|
1128
|
+
}), /*#__PURE__*/_jsx("input", {
|
|
1129
|
+
ref: timeInputRef,
|
|
1130
|
+
id: timeInputId,
|
|
1131
|
+
type: "text",
|
|
1132
|
+
value: timeDisplayValue,
|
|
1133
|
+
onChange: handleTimeInputChange,
|
|
1134
|
+
onFocus: handleTimeFocus,
|
|
1135
|
+
onBlur: handleTimeBlur,
|
|
1136
|
+
onKeyDown: handleTimeKeyDown,
|
|
1137
|
+
onClick: hasTimeOptions ? showTimeOptions : undefined,
|
|
1138
|
+
onPointerDown: hasTimeOptions ? markTimePointerActive : undefined,
|
|
1139
|
+
placeholder: resolvedTimePlaceholder
|
|
1140
|
+
// Combobox semantics appear only with the dropdown opted in, so a
|
|
1141
|
+
// field without it keeps a single combobox on the date half.
|
|
1142
|
+
,
|
|
1143
|
+
role: hasTimeOptions ? 'combobox' : undefined,
|
|
1144
|
+
"aria-expanded": hasTimeOptions ? timePopover.isOpen : undefined,
|
|
1145
|
+
"aria-controls": hasTimeOptions && timePopover.isOpen ? timeListboxId : undefined,
|
|
1146
|
+
"aria-autocomplete": hasTimeOptions ? 'list' : undefined,
|
|
1147
|
+
"aria-activedescendant": hasTimeOptions && timePopover.isOpen && activeTimeIndex >= 0 && activeTimeIndex < timeOptions.length ? timeOptionId(activeTimeIndex) : undefined
|
|
1148
|
+
// With a disabledMessage the input keeps focusability via
|
|
1149
|
+
// aria-disabled so the reason is focus-discoverable; typing is
|
|
1150
|
+
// blocked with readOnly and the mutation guards.
|
|
1151
|
+
,
|
|
1152
|
+
disabled: isEffectivelyDisabled && !showsDisabledMessage,
|
|
1153
|
+
"aria-disabled": showsDisabledMessage ? 'true' : undefined,
|
|
1154
|
+
readOnly: showsDisabledMessage || undefined,
|
|
1155
|
+
"aria-label": resolvedTimeLabel,
|
|
1156
|
+
"aria-describedby": ariaDescribedBy,
|
|
1157
|
+
"aria-required": isEffectivelyRequired ? 'true' : undefined,
|
|
1158
|
+
"aria-invalid": status?.type === 'error' || !isTimeInputValid ? 'true' : undefined,
|
|
1159
|
+
"aria-busy": isBusy || undefined,
|
|
1160
|
+
...{
|
|
1161
|
+
0: {
|
|
1162
|
+
className: "x1lliihq x98rzlu xeuugli xc342km xng3xce x1717udv x9ynric xjm74w1 x6pjikd xw6l6zx x1tgivj0 xjbqb8w x1a2a7pz xeyghm5"
|
|
1163
|
+
},
|
|
1164
|
+
2: {
|
|
1165
|
+
className: "x1lliihq x98rzlu xeuugli xc342km xng3xce x1717udv x9ynric xjm74w1 x6pjikd xw6l6zx x1tgivj0 xjbqb8w x1a2a7pz xeyghm5 xt0e3qv"
|
|
1166
|
+
},
|
|
1167
|
+
1: {
|
|
1168
|
+
className: "x1lliihq x98rzlu xeuugli xc342km xng3xce x1717udv x9ynric xjm74w1 x6pjikd xw6l6zx xjbqb8w x1a2a7pz xeyghm5 xv1l7n4"
|
|
1169
|
+
},
|
|
1170
|
+
3: {
|
|
1171
|
+
className: "x1lliihq x98rzlu xeuugli xc342km xng3xce x1717udv x9ynric xjm74w1 x6pjikd xw6l6zx xjbqb8w x1a2a7pz xeyghm5 xt0e3qv xv1l7n4"
|
|
1172
|
+
}
|
|
1173
|
+
}[!!isEffectivelyDisabled << 1 | !!!isTimeInputValid << 0]
|
|
1174
|
+
}), /*#__PURE__*/_jsx(VisuallyHidden, {
|
|
1175
|
+
as: "div",
|
|
1176
|
+
role: "alert",
|
|
1177
|
+
"aria-live": "assertive",
|
|
1178
|
+
children: !isTimeInputValid ? t('@astryx.timeInput.invalidTime') : ''
|
|
1179
|
+
})]
|
|
1180
|
+
})
|
|
1078
1181
|
})]
|
|
1079
|
-
}), popover.render(/*#__PURE__*/_jsx(Calendar, {
|
|
1182
|
+
}), !usesNativePicker && popover.render(/*#__PURE__*/_jsx(Calendar, {
|
|
1080
1183
|
handleRef: calendarRef,
|
|
1081
1184
|
mode: "single",
|
|
1082
1185
|
value: valueParts.date,
|
|
@@ -1126,20 +1229,24 @@ function PointerDateTimeField({
|
|
|
1126
1229
|
});
|
|
1127
1230
|
}
|
|
1128
1231
|
PointerDateTimeField.displayName = 'PointerDateTimeField';
|
|
1129
|
-
const TOUCH_POINTER_QUERY = '(pointer: coarse)';
|
|
1130
1232
|
|
|
1131
1233
|
/**
|
|
1132
|
-
* A combined date and time picker
|
|
1133
|
-
*
|
|
1134
|
-
*
|
|
1135
|
-
*
|
|
1136
|
-
*
|
|
1234
|
+
* A combined date and time picker whose `nativePicker` prop chooses both
|
|
1235
|
+
* surfaces. Native modes use OS-owned date and time controls in Astryx field
|
|
1236
|
+
* chrome. With `nativePicker="never"`, fine pointers keep the typed fields and
|
|
1237
|
+
* popovers while coarse pointers get Astryx's coordinated Date/Time bottom
|
|
1238
|
+
* sheet.
|
|
1137
1239
|
*/
|
|
1138
|
-
export function DateTimeInput(
|
|
1240
|
+
export function DateTimeInput({
|
|
1241
|
+
nativePicker = 'touch',
|
|
1242
|
+
...props
|
|
1243
|
+
}) {
|
|
1139
1244
|
const isTouch = useMediaQuery(TOUCH_POINTER_QUERY);
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1245
|
+
const usesNativePicker = nativePicker === 'always' || nativePicker === 'touch' && isTouch;
|
|
1246
|
+
return usesNativePicker || !isTouch ? /*#__PURE__*/_jsx(PointerDateTimeField, {
|
|
1247
|
+
...props,
|
|
1248
|
+
nativePicker: nativePicker
|
|
1249
|
+
}) : /*#__PURE__*/_jsx(TouchDateTimeField, {
|
|
1143
1250
|
...props
|
|
1144
1251
|
});
|
|
1145
1252
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { plainDateFromISO, type ISODateString } from '../utils';
|
|
2
|
+
import type { InputStatusType } from '../Field';
|
|
3
|
+
export type NativeDateSegmentProps = {
|
|
4
|
+
id: string;
|
|
5
|
+
inputRef: React.Ref<HTMLInputElement>;
|
|
6
|
+
value?: ISODateString;
|
|
7
|
+
onChange: (value: ISODateString | undefined) => void;
|
|
8
|
+
placeholder: string;
|
|
9
|
+
min?: ISODateString;
|
|
10
|
+
max?: ISODateString;
|
|
11
|
+
isDateDisabled: (date: ReturnType<typeof plainDateFromISO>) => boolean;
|
|
12
|
+
isEffectivelyDisabled: boolean;
|
|
13
|
+
hasDisabledMessage: boolean;
|
|
14
|
+
isEffectivelyRequired: boolean;
|
|
15
|
+
isBusy: boolean;
|
|
16
|
+
statusType?: InputStatusType;
|
|
17
|
+
ariaDescribedBy?: string;
|
|
18
|
+
};
|
|
19
|
+
/** The native date half rendered inside DateTimeInput's date wrapper. */
|
|
20
|
+
export declare function NativeDateSegment({ id, inputRef, value, onChange, placeholder, min, max, isDateDisabled, isEffectivelyDisabled, hasDisabledMessage, isEffectivelyRequired, isBusy, statusType, ariaDescribedBy, }: NativeDateSegmentProps): import("react").JSX.Element;
|
|
21
|
+
export declare namespace NativeDateSegment {
|
|
22
|
+
var displayName: string;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=NativeDateSegment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NativeDateSegment.d.ts","sourceRoot":"","sources":["../../src/DateTimeInput/NativeDateSegment.tsx"],"names":[],"mappings":"AAiCA,OAAO,EAIL,gBAAgB,EAGhB,KAAK,aAAa,EACnB,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,UAAU,CAAC;AAK9C,MAAM,MAAM,sBAAsB,GAAG;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IACtC,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,GAAG,SAAS,KAAK,IAAI,CAAC;IACrD,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,aAAa,CAAC;IACpB,GAAG,CAAC,EAAE,aAAa,CAAC;IACpB,cAAc,EAAE,CAAC,IAAI,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,KAAK,OAAO,CAAC;IACvE,qBAAqB,EAAE,OAAO,CAAC;IAC/B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,yEAAyE;AACzE,wBAAgB,iBAAiB,CAAC,EAChC,EAAE,EACF,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,WAAW,EACX,GAAG,EACH,GAAG,EACH,cAAc,EACd,qBAAqB,EACrB,kBAAkB,EAClB,qBAAqB,EACrB,MAAM,EACN,UAAU,EACV,eAAe,GAChB,EAAE,sBAAsB,+BAiOxB;yBAhPe,iBAAiB"}
|