@astryxdesign/core 0.4.5 → 0.4.6-canary.cea9ecd
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 +134 -0
- package/dist/Avatar/Avatar.d.ts +10 -5
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +139 -30
- package/dist/Avatar/AvatarStatusDot.d.ts +2 -1
- package/dist/Avatar/AvatarStatusDot.d.ts.map +1 -1
- package/dist/Avatar/AvatarStatusDot.js +30 -4
- package/dist/Avatar/AvatarStatusLabelContext.d.ts +39 -0
- package/dist/Avatar/AvatarStatusLabelContext.d.ts.map +1 -0
- package/dist/Avatar/AvatarStatusLabelContext.js +41 -0
- package/dist/AvatarGroup/AvatarGroup.d.ts +3 -1
- package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.js +15 -9
- package/dist/Blockquote/Blockquote.d.ts +4 -3
- package/dist/Blockquote/Blockquote.d.ts.map +1 -1
- package/dist/Blockquote/Blockquote.js +9 -10
- package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetPanel.js +21 -5
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.js +47 -34
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +7 -7
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +21 -12
- package/dist/Calendar/hooks/useCalendarNavigation.d.ts.map +1 -1
- package/dist/Calendar/hooks/useCalendarNavigation.js +8 -4
- package/dist/Calendar/styles.d.ts +2 -2
- package/dist/Calendar/styles.d.ts.map +1 -1
- package/dist/Calendar/styles.js +5 -5
- package/dist/Center/Center.d.ts +23 -1
- package/dist/Center/Center.d.ts.map +1 -1
- package/dist/Center/Center.js +12 -6
- package/dist/Chat/ChatComposer.d.ts.map +1 -1
- package/dist/Chat/ChatComposer.js +3 -3
- package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
- package/dist/Chat/ChatComposerDrawer.js +2 -2
- package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
- package/dist/Chat/ChatToolCalls.js +2 -2
- package/dist/Chat/useChatDictation.d.ts +1 -1
- package/dist/Chat/useChatDictation.d.ts.map +1 -1
- package/dist/Chat/useSpeechRecognition.d.ts +1 -1
- package/dist/Chat/useSpeechRecognition.d.ts.map +1 -1
- package/dist/Chat/useSpeechRecognition.js +4 -3
- package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
- package/dist/Chat/useTriggerMenu.js +2 -2
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +2 -2
- package/dist/Citation/Citation.d.ts.map +1 -1
- package/dist/Citation/Citation.js +5 -5
- package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
- package/dist/ClickableCard/ClickableCard.js +4 -4
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +1 -1
- package/dist/Collapsible/Collapsible.d.ts.map +1 -1
- package/dist/Collapsible/Collapsible.js +2 -2
- package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteItem.js +3 -3
- package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
- package/dist/ComplexSelector/ComplexSelector.js +6 -6
- package/dist/DateInput/DateInput.d.ts +31 -2
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +90 -22
- package/dist/DateInput/MonthScroller.d.ts +35 -0
- package/dist/DateInput/MonthScroller.d.ts.map +1 -0
- package/dist/DateInput/MonthScroller.js +658 -0
- package/dist/DateInput/MonthYearWheels.d.ts +24 -0
- package/dist/DateInput/MonthYearWheels.d.ts.map +1 -0
- package/dist/DateInput/MonthYearWheels.js +114 -0
- package/dist/DateInput/TouchDateField.d.ts +10 -0
- package/dist/DateInput/TouchDateField.d.ts.map +1 -0
- package/dist/DateInput/TouchDateField.js +810 -0
- package/dist/DateInput/Wheel.d.ts +41 -0
- package/dist/DateInput/Wheel.d.ts.map +1 -0
- package/dist/DateInput/Wheel.js +315 -0
- package/dist/DateInput/monthGeometry.d.ts +65 -0
- package/dist/DateInput/monthGeometry.d.ts.map +1 -0
- package/dist/DateInput/monthGeometry.js +98 -0
- package/dist/DateInput/tokens.stylex.d.ts +63 -0
- package/dist/DateInput/tokens.stylex.d.ts.map +1 -0
- package/dist/DateInput/tokens.stylex.js +74 -0
- package/dist/DateInput/useOwnScrollGesture.d.ts +41 -0
- package/dist/DateInput/useOwnScrollGesture.d.ts.map +1 -0
- package/dist/DateInput/useOwnScrollGesture.js +202 -0
- package/dist/DateInput/usePointerDragScroll.d.ts +15 -0
- package/dist/DateInput/usePointerDragScroll.d.ts.map +1 -0
- package/dist/DateInput/usePointerDragScroll.js +216 -0
- package/dist/DateInput/useScrollSettle.d.ts +26 -0
- package/dist/DateInput/useScrollSettle.d.ts.map +1 -0
- package/dist/DateInput/useScrollSettle.js +149 -0
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +17 -14
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +17 -14
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +3 -3
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +2 -2
- package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuItem.js +2 -2
- package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuRadioItem.js +2 -2
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuSubMenu.js +2 -2
- package/dist/Field/FieldLabel.d.ts.map +1 -1
- package/dist/Field/FieldLabel.js +4 -4
- package/dist/Field/InputClearButton.d.ts.map +1 -1
- package/dist/Field/InputClearButton.js +6 -0
- package/dist/Field/inputStyles.stylex.d.ts +1 -1
- package/dist/Field/inputStyles.stylex.d.ts.map +1 -1
- package/dist/Field/inputStyles.stylex.js +5 -5
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +6 -6
- package/dist/HoverCard/HoverCard.d.ts +13 -3
- package/dist/HoverCard/HoverCard.d.ts.map +1 -1
- package/dist/HoverCard/HoverCard.js +2 -0
- package/dist/HoverCard/index.d.ts +1 -1
- package/dist/HoverCard/index.d.ts.map +1 -1
- package/dist/HoverCard/useHoverCard.d.ts +17 -2
- package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
- package/dist/HoverCard/useHoverCard.js +78 -9
- package/dist/InputGroup/InputGroup.js +1 -1
- package/dist/Item/Item.d.ts +9 -1
- package/dist/Item/Item.d.ts.map +1 -1
- package/dist/Item/Item.js +52 -14
- package/dist/Layer/index.d.ts +4 -2
- package/dist/Layer/index.d.ts.map +1 -1
- package/dist/Layer/index.js +2 -0
- package/dist/Layer/useLayer.d.ts.map +1 -1
- package/dist/Layer/useLayer.js +3 -2
- package/dist/Layer/useTouchTrigger.d.ts +113 -0
- package/dist/Layer/useTouchTrigger.d.ts.map +1 -0
- package/dist/Layer/useTouchTrigger.js +241 -0
- package/dist/Layout/container.stylex.d.ts +4 -2
- package/dist/Layout/container.stylex.d.ts.map +1 -1
- package/dist/Layout/container.stylex.js +19 -11
- package/dist/Layout/index.d.ts +1 -0
- package/dist/Layout/index.d.ts.map +1 -1
- package/dist/Layout/index.js +4 -0
- package/dist/Layout/padding.stylex.d.ts +315 -12
- package/dist/Layout/padding.stylex.d.ts.map +1 -1
- package/dist/Layout/padding.stylex.js +389 -12
- package/dist/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/Lightbox/Lightbox.js +5 -4
- package/dist/Link/Link.d.ts.map +1 -1
- package/dist/Link/Link.js +6 -6
- package/dist/MetadataList/MetadataList.d.ts.map +1 -1
- package/dist/MetadataList/MetadataList.js +1 -1
- package/dist/MobileNav/MobileNav.d.ts +1 -0
- package/dist/MobileNav/MobileNav.d.ts.map +1 -1
- package/dist/MobileNav/MobileNav.js +24 -6
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +8 -8
- package/dist/NavItem/navItemStyles.stylex.d.ts +4 -4
- package/dist/NavItem/navItemStyles.stylex.d.ts.map +1 -1
- package/dist/NavItem/navItemStyles.stylex.js +4 -4
- package/dist/NavMenu/NavHeadingMenuItem.d.ts.map +1 -1
- package/dist/NavMenu/NavHeadingMenuItem.js +3 -3
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +36 -8
- package/dist/Outline/Outline.d.ts.map +1 -1
- package/dist/Outline/Outline.js +3 -3
- package/dist/Pagination/Pagination.d.ts.map +1 -1
- package/dist/Pagination/Pagination.js +2 -2
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +11 -12
- package/dist/PowerSearch/PowerSearchToken.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchToken.js +3 -1
- package/dist/PowerSearch/formatFilterValue.d.ts +11 -2
- package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
- package/dist/PowerSearch/formatFilterValue.js +23 -8
- package/dist/RadioList/RadioListItem.d.ts +2 -2
- package/dist/RadioList/RadioListItem.d.ts.map +1 -1
- package/dist/RadioList/RadioListItem.js +70 -40
- package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
- package/dist/Resizable/ResizeHandle.js +7 -7
- package/dist/Section/Section.d.ts +36 -1
- package/dist/Section/Section.d.ts.map +1 -1
- package/dist/Section/Section.js +12 -2
- package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.js +7 -2
- package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
- package/dist/SelectableCard/SelectableCard.js +3 -3
- package/dist/Selector/Selector.d.ts +26 -1
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +93 -20
- package/dist/Selector/SelectorOption.d.ts +14 -1
- package/dist/Selector/SelectorOption.d.ts.map +1 -1
- package/dist/Selector/SelectorOption.js +6 -0
- package/dist/Selector/SelectorRowLayoutContext.d.ts +8 -0
- package/dist/Selector/SelectorRowLayoutContext.d.ts.map +1 -0
- package/dist/Selector/SelectorRowLayoutContext.js +27 -0
- package/dist/Selector/types.d.ts +1 -0
- package/dist/Selector/types.d.ts.map +1 -1
- package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
- package/dist/SideNav/SideNavHeading.js +4 -4
- package/dist/SideNav/SideNavItem.d.ts.map +1 -1
- package/dist/SideNav/SideNavItem.js +3 -3
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +7 -7
- package/dist/Stack/Stack.d.ts +23 -1
- package/dist/Stack/Stack.d.ts.map +1 -1
- package/dist/Stack/Stack.js +12 -6
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +2 -2
- package/dist/TabList/Tab.d.ts.map +1 -1
- package/dist/TabList/Tab.js +1 -1
- package/dist/TabList/TabMenu.d.ts.map +1 -1
- package/dist/TabList/TabMenu.js +3 -3
- package/dist/Table/TableRow.js +4 -4
- package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
- package/dist/Table/plugins/columnResize/useTableColumnResize.js +1 -1
- package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
- package/dist/Table/plugins/filtering/useTableFiltering.js +2 -2
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +2 -2
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +2 -2
- package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
- package/dist/Table/plugins/sortable/useTableSortable.js +1 -1
- package/dist/Table/plugins/sortable/useTableSortableState.d.ts +5 -3
- package/dist/Table/plugins/sortable/useTableSortableState.d.ts.map +1 -1
- package/dist/Table/plugins/sortable/useTableSortableState.js +12 -9
- package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -1
- package/dist/Table/plugins/tree/useTableTreeData.js +3 -3
- package/dist/TextArea/TextArea.js +1 -1
- package/dist/TextInput/TextInput.js +1 -1
- package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
- package/dist/Thumbnail/Thumbnail.js +3 -3
- package/dist/TimeInput/TimeInput.js +2 -2
- package/dist/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +6 -4
- package/dist/Timestamp/formatInstant.d.ts +3 -2
- package/dist/Timestamp/formatInstant.d.ts.map +1 -1
- package/dist/Timestamp/formatInstant.js +8 -8
- package/dist/Timestamp/tooltipEntries.d.ts +2 -1
- package/dist/Timestamp/tooltipEntries.d.ts.map +1 -1
- package/dist/Timestamp/tooltipEntries.js +5 -3
- package/dist/Toast/Toast.d.ts +4 -3
- package/dist/Toast/Toast.d.ts.map +1 -1
- package/dist/Toast/Toast.js +10 -7
- package/dist/Token/Token.d.ts.map +1 -1
- package/dist/Token/Token.js +6 -6
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +1 -1
- package/dist/Tooltip/Tooltip.d.ts +16 -3
- package/dist/Tooltip/Tooltip.d.ts.map +1 -1
- package/dist/Tooltip/Tooltip.js +2 -0
- package/dist/Tooltip/index.d.ts +1 -1
- package/dist/Tooltip/index.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.d.ts +21 -2
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +71 -13
- package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
- package/dist/TopNav/TopNavHeading.js +4 -4
- package/dist/TopNav/TopNavItem.d.ts.map +1 -1
- package/dist/TopNav/TopNavItem.js +3 -3
- package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMegaMenu.js +2 -2
- package/dist/TopNav/TopNavMegaMenuItem.d.ts.map +1 -1
- package/dist/TopNav/TopNavMegaMenuItem.js +2 -2
- package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMenu.js +4 -4
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +7 -7
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +2 -2
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +1 -1
- package/dist/astryx.css +124 -62
- package/dist/hooks/containerReveal.stylex.d.ts.map +1 -1
- package/dist/hooks/containerReveal.stylex.js +18 -18
- package/dist/hooks/scrollbarGutter.d.ts +28 -0
- package/dist/hooks/scrollbarGutter.d.ts.map +1 -0
- package/dist/hooks/scrollbarGutter.js +103 -0
- package/dist/hooks/useAutoMediaMode.d.ts +31 -0
- package/dist/hooks/useAutoMediaMode.d.ts.map +1 -0
- package/dist/hooks/useAutoMediaMode.js +201 -0
- package/dist/hooks/useInputStatusIcon.d.ts.map +1 -1
- package/dist/hooks/useInputStatusIcon.js +1 -1
- 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/useScrollLock.d.ts +4 -0
- package/dist/hooks/useScrollLock.d.ts.map +1 -1
- package/dist/hooks/useScrollLock.js +13 -1
- package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
- package/dist/i18n/InternationalizationContext.js +2 -0
- package/dist/i18n/index.d.ts +6 -0
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/i18n/index.js +6 -0
- package/dist/i18n/useCollator.d.ts +12 -0
- package/dist/i18n/useCollator.d.ts.map +1 -0
- package/dist/i18n/useCollator.js +40 -0
- package/dist/i18n/useLocale.d.ts +3 -0
- package/dist/i18n/useLocale.d.ts.map +1 -0
- package/dist/i18n/useLocale.js +31 -0
- package/dist/theme/MediaTheme.d.ts +25 -5
- package/dist/theme/MediaTheme.d.ts.map +1 -1
- package/dist/theme/MediaTheme.js +31 -6
- package/dist/theme/defineTheme.d.ts +5 -0
- package/dist/theme/defineTheme.d.ts.map +1 -1
- package/dist/theme/defineTheme.js +5 -0
- package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
- package/dist/theme/derivedVarRegistry.js +7 -0
- package/dist/theme/generateThemeRules.d.ts.map +1 -1
- package/dist/theme/generateThemeRules.js +66 -5
- package/dist/theme/index.d.ts +1 -1
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/syntax/index.d.ts +6 -0
- package/dist/theme/syntax/index.d.ts.map +1 -1
- package/dist/theme/syntax/index.js +7 -2
- package/dist/utils/dateParser.d.ts +4 -3
- package/dist/utils/dateParser.d.ts.map +1 -1
- package/dist/utils/dateParser.js +8 -8
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/plainDate.d.ts +5 -2
- package/dist/utils/plainDate.d.ts.map +1 -1
- package/dist/utils/plainDate.js +20 -4
- package/locales/en.json +28 -0
- package/locales/pseudo.json +21 -0
- package/package.json +3 -3
- package/src/Avatar/Avatar.doc.mjs +10 -6
- package/src/Avatar/Avatar.test.tsx +219 -1
- package/src/Avatar/Avatar.tsx +179 -37
- package/src/Avatar/AvatarStatusDot.tsx +30 -4
- package/src/Avatar/AvatarStatusLabelContext.ts +47 -0
- package/src/AvatarGroup/AvatarGroup.doc.mjs +10 -6
- package/src/AvatarGroup/AvatarGroup.test.tsx +62 -0
- package/src/AvatarGroup/AvatarGroup.tsx +3 -1
- package/src/AvatarGroup/AvatarGroupOverflow.tsx +31 -8
- package/src/Banner/Banner.doc.mjs +2 -0
- package/src/Blockquote/Blockquote.doc.mjs +30 -7
- package/src/Blockquote/Blockquote.test.tsx +34 -3
- package/src/Blockquote/Blockquote.tsx +11 -9
- package/src/BottomSheet/BottomSheet.doc.mjs +3 -3
- package/src/BottomSheet/BottomSheet.test.tsx +24 -0
- package/src/BottomSheet/BottomSheetPanel.test.tsx +91 -0
- package/src/BottomSheet/BottomSheetPanel.tsx +58 -3
- package/src/Breadcrumbs/BreadcrumbItem.tsx +36 -23
- package/src/Breadcrumbs/Breadcrumbs.doc.mjs +26 -2
- package/src/Breadcrumbs/Breadcrumbs.test.tsx +31 -0
- package/src/Button/Button.tsx +12 -9
- package/src/Calendar/Calendar.tsx +15 -9
- package/src/Calendar/hooks/useCalendarNavigation.ts +6 -4
- package/src/Calendar/styles.ts +8 -5
- package/src/Center/Center.doc.mjs +48 -0
- package/src/Center/Center.test.tsx +158 -0
- package/src/Center/Center.tsx +50 -9
- package/src/Chat/ChatComposer.tsx +11 -5
- package/src/Chat/ChatComposerDrawer.tsx +4 -1
- package/src/Chat/ChatToolCalls.tsx +13 -4
- package/src/Chat/{useChatDictation.test.ts → useChatDictation.test.tsx} +29 -14
- package/src/Chat/useChatDictation.ts +1 -1
- package/src/Chat/useSpeechRecognition.ts +5 -3
- package/src/Chat/useTriggerMenu.tsx +4 -1
- package/src/CheckboxInput/CheckboxInput.tsx +5 -2
- package/src/Citation/Citation.test.tsx +6 -1
- package/src/Citation/Citation.tsx +11 -5
- package/src/ClickableCard/ClickableCard.tsx +7 -4
- package/src/CodeBlock/CodeBlock.tsx +4 -1
- package/src/Collapsible/Collapsible.tsx +5 -2
- package/src/CommandPalette/CommandPaletteItem.tsx +6 -3
- package/src/ComplexSelector/ComplexSelector.doc.mjs +10 -0
- package/src/ComplexSelector/ComplexSelector.tsx +14 -7
- package/src/DateInput/DateInput.test.tsx +17 -1
- package/src/DateInput/DateInput.tsx +93 -21
- package/src/DateInput/DateInputTouch.test.tsx +2582 -0
- package/src/DateInput/MonthScroller.tsx +878 -0
- package/src/DateInput/MonthYearWheels.tsx +147 -0
- package/src/DateInput/TouchDateField.tsx +1223 -0
- package/src/DateInput/Wheel.tsx +473 -0
- package/src/DateInput/monthGeometry.ts +118 -0
- package/src/DateInput/tokens.stylex.ts +99 -0
- package/src/DateInput/useOwnScrollGesture.ts +227 -0
- package/src/DateInput/usePointerDragScroll.ts +220 -0
- package/src/DateInput/useScrollSettle.ts +164 -0
- package/src/DateRangeInput/DateRangeInput.doc.mjs +1 -1
- package/src/DateRangeInput/DateRangeInput.tsx +31 -13
- package/src/DateTimeInput/DateTimeInput.tsx +25 -9
- package/src/Dialog/Dialog.test.tsx +24 -0
- package/src/Dialog/Dialog.tsx +3 -0
- package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +5 -2
- package/src/DropdownMenu/DropdownMenuItem.tsx +5 -2
- package/src/DropdownMenu/DropdownMenuRadioItem.tsx +5 -2
- package/src/DropdownMenu/DropdownMenuSubMenu.tsx +5 -2
- package/src/Field/Field.doc.mjs +2 -0
- package/src/Field/FieldLabel.tsx +9 -3
- package/src/Field/InputClearButton.test.tsx +110 -3
- package/src/Field/InputClearButton.tsx +38 -0
- package/src/Field/inputStyles.stylex.ts +17 -13
- package/src/FileInput/FileInput.tsx +15 -8
- package/src/FormLayout/FormLayout.doc.mjs +1 -1
- package/src/HoverCard/HoverCard.doc.mjs +18 -0
- package/src/HoverCard/HoverCard.test.tsx +189 -0
- package/src/HoverCard/HoverCard.tsx +22 -2
- package/src/HoverCard/index.ts +1 -0
- package/src/HoverCard/useHoverCard.doc.mjs +2 -0
- package/src/HoverCard/useHoverCard.tsx +103 -7
- package/src/InputGroup/InputGroup.tsx +1 -1
- package/src/Item/Item.doc.mjs +1 -0
- package/src/Item/Item.test.tsx +50 -0
- package/src/Item/Item.tsx +54 -6
- package/src/Layer/index.ts +10 -0
- package/src/Layer/useLayer.tsx +13 -2
- package/src/Layer/useTouchTrigger.test.ts +70 -0
- package/src/Layer/useTouchTrigger.ts +366 -0
- package/src/Layout/Layout.doc.mjs +18 -0
- package/src/Layout/container.stylex.ts +11 -3
- package/src/Layout/index.ts +4 -0
- package/src/Layout/overlayPaddingReset.test.tsx +222 -0
- package/src/Layout/padding.stylex.ts +192 -12
- package/src/Lightbox/Lightbox.tsx +11 -3
- package/src/Link/Link.tsx +9 -6
- package/src/MetadataList/MetadataList.tsx +4 -1
- package/src/MobileNav/MobileNav.tsx +61 -5
- package/src/MobileNav/MobileNavEntryAnimation.test.tsx +212 -0
- package/src/MobileNav/MobileNavScrollbarGutter.test.tsx +109 -0
- package/src/MultiSelector/MultiSelector.test.tsx +1 -1
- package/src/MultiSelector/MultiSelector.tsx +26 -10
- package/src/NavItem/navItemStyles.stylex.ts +7 -4
- package/src/NavMenu/NavHeadingMenuItem.tsx +6 -3
- package/src/NumberInput/NumberInput.doc.mjs +24 -0
- package/src/NumberInput/NumberInput.test.tsx +138 -0
- package/src/NumberInput/NumberInput.tsx +47 -8
- package/src/Outline/Outline.tsx +5 -2
- package/src/Pagination/Pagination.tsx +5 -2
- package/src/Popover/Popover.test.tsx +27 -1
- package/src/PowerSearch/PowerSearch.tsx +17 -8
- package/src/PowerSearch/PowerSearchToken.tsx +3 -0
- package/src/PowerSearch/formatFilterValue.test.ts +22 -2
- package/src/PowerSearch/formatFilterValue.ts +31 -6
- package/src/RadioList/RadioList.doc.mjs +1 -1
- package/src/RadioList/RadioList.test.tsx +170 -2
- package/src/RadioList/RadioListItem.tsx +88 -53
- package/src/Resizable/ResizeHandle.test.tsx +22 -0
- package/src/Resizable/ResizeHandle.tsx +25 -7
- package/src/Section/Section.doc.mjs +55 -0
- package/src/Section/Section.test.tsx +201 -4
- package/src/Section/Section.tsx +69 -0
- package/src/SegmentedControl/SegmentedControl.test.tsx +31 -0
- package/src/SegmentedControl/SegmentedControlItem.tsx +15 -3
- package/src/SelectableCard/SelectableCard.tsx +6 -3
- package/src/Selector/Selector.doc.mjs +16 -2
- package/src/Selector/Selector.test.tsx +525 -1
- package/src/Selector/Selector.tsx +180 -25
- package/src/Selector/SelectorOption.doc.mjs +7 -0
- package/src/Selector/SelectorOption.tsx +21 -0
- package/src/Selector/SelectorRowLayoutContext.ts +32 -0
- package/src/Selector/types.ts +4 -4
- package/src/SideNav/SideNavHeading.tsx +14 -5
- package/src/SideNav/SideNavItem.tsx +9 -3
- package/src/Slider/Slider.tsx +25 -6
- package/src/Stack/Stack.doc.mjs +72 -0
- package/src/Stack/Stack.test.tsx +156 -0
- package/src/Stack/Stack.tsx +50 -8
- package/src/Switch/Switch.tsx +5 -2
- package/src/TabList/Tab.tsx +4 -1
- package/src/TabList/TabMenu.tsx +9 -3
- package/src/Table/TableRow.tsx +4 -4
- package/src/Table/plugins/columnResize/useTableColumnResize.tsx +6 -2
- package/src/Table/plugins/filtering/useTableFiltering.tsx +4 -1
- package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +10 -3
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +6 -3
- package/src/Table/plugins/sortable/useTableSortable.tsx +4 -1
- package/src/Table/plugins/sortable/useTableSortableState.test.tsx +34 -0
- package/src/Table/plugins/sortable/useTableSortableState.tsx +26 -23
- package/src/Table/plugins/tree/useTableTreeData.tsx +10 -4
- package/src/TextArea/TextArea.doc.mjs +1 -1
- package/src/TextArea/TextArea.tsx +1 -1
- package/src/TextInput/TextInput.tsx +1 -1
- package/src/Thumbnail/Thumbnail.tsx +9 -3
- package/src/TimeInput/TimeInput.tsx +1 -1
- package/src/Timestamp/Timestamp.test.tsx +27 -7
- package/src/Timestamp/Timestamp.tsx +8 -4
- package/src/Timestamp/formatInstant.ts +9 -7
- package/src/Timestamp/tooltipEntries.test.ts +11 -6
- package/src/Timestamp/tooltipEntries.ts +6 -2
- package/src/Toast/Toast.tsx +9 -7
- package/src/Token/Token.tsx +14 -5
- package/src/Tokenizer/Tokenizer.tsx +4 -1
- package/src/Tooltip/Tooltip.doc.mjs +18 -0
- package/src/Tooltip/Tooltip.test.tsx +254 -1
- package/src/Tooltip/Tooltip.tsx +22 -2
- package/src/Tooltip/index.ts +1 -0
- package/src/Tooltip/useTooltip.doc.mjs +2 -0
- package/src/Tooltip/useTooltip.tsx +99 -21
- package/src/TopNav/TopNavHeading.tsx +13 -4
- package/src/TopNav/TopNavItem.tsx +6 -3
- package/src/TopNav/TopNavMegaMenu.tsx +5 -2
- package/src/TopNav/TopNavMegaMenuItem.tsx +5 -2
- package/src/TopNav/TopNavMenu.tsx +10 -4
- package/src/TreeList/TreeListItem.tsx +22 -7
- package/src/Typeahead/BaseTypeahead.tsx +5 -2
- package/src/Typeahead/Typeahead.tsx +4 -1
- package/src/hooks/containerReveal.stylex.ts +54 -18
- package/src/hooks/scrollbarGutter.test.ts +167 -0
- package/src/hooks/scrollbarGutter.ts +121 -0
- package/src/hooks/useAutoMediaMode.test.ts +109 -0
- package/src/hooks/useAutoMediaMode.ts +233 -0
- package/src/hooks/useInputStatusIcon.tsx +4 -1
- 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/useScrollLock.doc.mjs +4 -4
- package/src/hooks/useScrollLock.test.ts +73 -0
- package/src/hooks/useScrollLock.ts +14 -0
- package/src/i18n/InternationalizationContext.ts +2 -0
- package/src/i18n/__tests__/e2e-powersearch.test.tsx +37 -1
- package/src/i18n/__tests__/useCollator.test.tsx +115 -0
- package/src/i18n/__tests__/useLocale.test.tsx +52 -0
- package/src/i18n/index.ts +6 -0
- package/src/i18n/useCollator.doc.mjs +84 -0
- package/src/i18n/useCollator.ts +44 -0
- package/src/i18n/useLocale.doc.mjs +70 -0
- package/src/i18n/useLocale.ts +34 -0
- package/src/i18n/useTranslator.doc.mjs +1 -1
- package/src/reset.css +9 -2
- package/src/reset.test.ts +22 -0
- package/src/theme/MediaTheme.doc.mjs +23 -4
- package/src/theme/MediaTheme.dom.test.tsx +97 -0
- package/src/theme/MediaTheme.tsx +42 -7
- package/src/theme/defineTheme.test.ts +9 -3
- package/src/theme/defineTheme.ts +5 -0
- package/src/theme/derivedVarRegistry.test.ts +19 -5
- package/src/theme/derivedVarRegistry.ts +4 -0
- package/src/theme/generateThemeRules.test.ts +118 -0
- package/src/theme/generateThemeRules.ts +83 -5
- package/src/theme/index.ts +1 -1
- package/src/theme/syntax/index.ts +6 -2
- package/src/theme/syntax/serverSafeSyntax.test.ts +68 -0
- package/src/utils/dateParser.test.ts +20 -0
- package/src/utils/dateParser.ts +14 -7
- package/src/utils/index.ts +2 -0
- package/src/utils/plainDate.test.ts +6 -0
- package/src/utils/plainDate.ts +21 -4
|
@@ -0,0 +1,810 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @file TouchDateField.tsx
|
|
7
|
+
* @input Uses React, Field, BottomSheet, Button, Icon, Calendar hooks, MonthScroller, MonthYearWheels
|
|
8
|
+
* @output Exports TouchDateField — the touch surface behind DateInput
|
|
9
|
+
* @position Internal component; consumed by DateInput.tsx
|
|
10
|
+
*
|
|
11
|
+
* The touch half of `DateInput`, holding `DateInput`'s whole prop
|
|
12
|
+
* contract so the two are interchangeable. Everything field-shaped —
|
|
13
|
+
* `Field` wrapper, status treatment, optimistic `changeAction`, the
|
|
14
|
+
* disabled-reason tooltip, `InputGroup` membership — behaves exactly as it
|
|
15
|
+
* does on the desktop control; only the picker differs.
|
|
16
|
+
*
|
|
17
|
+
* ## The closed field is deliberately the same control
|
|
18
|
+
*
|
|
19
|
+
* It is a real `<input>`, not a button: same element, same `role="combobox"`,
|
|
20
|
+
* same border, same clear button, so `ref` (typed `Ref<HTMLInputElement>` by
|
|
21
|
+
* `DateInputProps`) is honestly a reference to an input, the label's `for`
|
|
22
|
+
* names it natively, and the switch between surfaces moves nothing on screen.
|
|
23
|
+
*
|
|
24
|
+
* It just cannot be typed into: `readOnly` blocks entry, and `inputMode="none"`
|
|
25
|
+
* stops the virtual keyboard from opening over the sheet. Text entry is the
|
|
26
|
+
* one part of the desktop control that has no place here — the keyboard it
|
|
27
|
+
* summons would cover the picker it is meant to fill in.
|
|
28
|
+
*
|
|
29
|
+
* ## Three ideas in the picker
|
|
30
|
+
*
|
|
31
|
+
* 1. One month per screen. Every pane is exactly the height of the scrollport
|
|
32
|
+
* and snaps to its start, so the picker is a fixed height and there is no
|
|
33
|
+
* resting position showing half of two months. See MonthScroller.
|
|
34
|
+
* 2. Swiping is the month control, and the arrows are the backup. A flick
|
|
35
|
+
* reaches a neighbouring month in the direction you already think of it;
|
|
36
|
+
* the pair of arrows in the header's trailing corner is there for a
|
|
37
|
+
* deliberate single step, and for anyone not swiping at all.
|
|
38
|
+
* 3. The title is the escape hatch. Tap it and the same box becomes a month
|
|
39
|
+
* wheel and a year wheel — a flick each to reach 2019 instead of forty.
|
|
40
|
+
*
|
|
41
|
+
* SYNC: When modified, update these files to stay in sync:
|
|
42
|
+
* - /packages/core/src/DateInput/DateInput.tsx
|
|
43
|
+
* - /packages/core/src/DateInput/DateInput.doc.mjs
|
|
44
|
+
* - /packages/core/src/DateInput/DateInputTouch.test.tsx
|
|
45
|
+
*/
|
|
46
|
+
import { useCallback, useEffect, useId, useMemo, useOptimistic, useRef, useState, useTransition } from 'react';
|
|
47
|
+
import * as stylex from '@stylexjs/stylex';
|
|
48
|
+
import { BottomSheet } from "../BottomSheet/index.js";
|
|
49
|
+
import { Button } from "../Button/index.js";
|
|
50
|
+
import { useCalendarConstraints } from "../Calendar/index.js";
|
|
51
|
+
import { Field, InputClearButton, inputWrapperStyles, inputStatusBorderStyles, inputStatusHoverShadowStyles, inputStatusFocusWithinStyles } from "../Field/index.js";
|
|
52
|
+
import { useInputStatusIcon } from "../hooks/index.js";
|
|
53
|
+
import { useResolvedRequired } from "../hooks/useResolvedRequired.js";
|
|
54
|
+
import { Icon } from "../Icon/index.js";
|
|
55
|
+
import { IconButton } from "../IconButton/index.js";
|
|
56
|
+
import { useTranslator } from "../i18n/index.js";
|
|
57
|
+
import { useInputGroup } from "../InputGroup/index.js";
|
|
58
|
+
import { groupStyles } from "../InputGroup/groupStyles.js";
|
|
59
|
+
import { stableClassName } from "../naming.js";
|
|
60
|
+
import { useSize } from "../SizeContext/index.js";
|
|
61
|
+
import { Spinner } from "../Spinner/index.js";
|
|
62
|
+
import "../theme/tokens.stylex.js";
|
|
63
|
+
import { colorVars, spacingVars, radiusVars, sizeVars, borderVars, fontWeightVars, typeScaleVars, typographyVars, durationVars, easeVars } from "../theme/tokens.stylex.js";
|
|
64
|
+
import { useTooltip } from "../Tooltip/index.js";
|
|
65
|
+
import { VisuallyHidden } from "../VisuallyHidden/index.js";
|
|
66
|
+
import { focusOutlineStyles, getInputARIA, isImeKeyEvent, mergeProps, mergeRefs, rtlStyles, themeProps, formatSharedDate, plainDateFromISO, plainDateToday, plainDateFormat, DATE_FORMAT_MONTH_YEAR, DATE_FORMAT_WEEKDAY_ONLY } from "../utils/index.js";
|
|
67
|
+
import { normalizeDayOfWeek } from "../utils/dateTypes.js";
|
|
68
|
+
import { MonthScroller } from "./MonthScroller.js";
|
|
69
|
+
import { MonthYearWheels } from "./MonthYearWheels.js";
|
|
70
|
+
import { DEFAULT_MONTH_REACH, clampIndex, fromMonthIndex, monthIndexOf } from "./monthGeometry.js";
|
|
71
|
+
import "./tokens.stylex.js";
|
|
72
|
+
import { dateInputTouchSizes, dateInputTouchGeometry } from "./tokens.stylex.js";
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The comfortable minimum tap target on both iOS and Android. Applied as a
|
|
76
|
+
* FLOOR under the size prop rather than replacing it: `size` still means what
|
|
77
|
+
* it means, it just cannot produce a control a thumb misses.
|
|
78
|
+
*/
|
|
79
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
80
|
+
const TOUCH_TARGET = dateInputTouchSizes.daySize;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* The whole surface swap, in one leg.
|
|
84
|
+
*
|
|
85
|
+
* It used to be two: the outgoing surface faded out, then the incoming one
|
|
86
|
+
* faded in, 110ms each. The sequencing existed for one reason — the wheels'
|
|
87
|
+
* panel was transparent, so overlapping the two put the wheels' translucent
|
|
88
|
+
* selection band over the calendar grid and tinted a band-shaped strip of it,
|
|
89
|
+
* which read as "the grey area animates differently from the content".
|
|
90
|
+
*
|
|
91
|
+
* Giving the wheels an opaque background removes the reason. Nothing shows
|
|
92
|
+
* through them, so they can simply fade in ON TOP of a calendar that does not
|
|
93
|
+
* move at all — no empty middle, no outgoing animation, and one duration
|
|
94
|
+
* instead of a wait plus a fade.
|
|
95
|
+
*
|
|
96
|
+
* `--duration-fast` rather than a literal now that this is a whole duration
|
|
97
|
+
* and not half of one.
|
|
98
|
+
*/
|
|
99
|
+
const SWAP_DURATION = durationVars['--duration-fast'];
|
|
100
|
+
const sizeStyles = {
|
|
101
|
+
sm: {
|
|
102
|
+
kZKoxP: "x6k0iem",
|
|
103
|
+
k7Eaqz: "xfb3i0g",
|
|
104
|
+
kAzted: "xygd9yz",
|
|
105
|
+
$$css: true
|
|
106
|
+
},
|
|
107
|
+
md: {
|
|
108
|
+
kZKoxP: "x1ueg155",
|
|
109
|
+
k7Eaqz: "xfb3i0g",
|
|
110
|
+
kAzted: "xygd9yz",
|
|
111
|
+
$$css: true
|
|
112
|
+
},
|
|
113
|
+
lg: {
|
|
114
|
+
kZKoxP: "xssyfek",
|
|
115
|
+
k7Eaqz: "xfb3i0g",
|
|
116
|
+
kAzted: "xygd9yz",
|
|
117
|
+
$$css: true
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
const styles = {
|
|
121
|
+
wrapper: {
|
|
122
|
+
kOIVth: "x1txdalj",
|
|
123
|
+
$$css: true
|
|
124
|
+
},
|
|
125
|
+
iconButton: {
|
|
126
|
+
k1xSpc: "x78zum5",
|
|
127
|
+
kGNEyG: "x6s0dn4",
|
|
128
|
+
kjj79g: "xl56j7k",
|
|
129
|
+
kmVPX3: "x1717udv",
|
|
130
|
+
kogj98: "x1ghz6dp",
|
|
131
|
+
kMzoRj: "xc342km",
|
|
132
|
+
ksu8eU: "xng3xce",
|
|
133
|
+
kWkggS: "xjbqb8w",
|
|
134
|
+
kkrTdU: "x1ypdohk x16khyan",
|
|
135
|
+
kaIpWk: "xh6dtrn",
|
|
136
|
+
$$css: true
|
|
137
|
+
},
|
|
138
|
+
iconButtonDisabled: {
|
|
139
|
+
kkrTdU: "xt0e3qv",
|
|
140
|
+
$$css: true
|
|
141
|
+
},
|
|
142
|
+
monthArrowUnavailable: {
|
|
143
|
+
k33iCy: "xlshs6z",
|
|
144
|
+
$$css: true
|
|
145
|
+
},
|
|
146
|
+
monthArrow: {
|
|
147
|
+
kAzted: "xygd9yz",
|
|
148
|
+
k7Eaqz: "xngvp7v",
|
|
149
|
+
$$css: true
|
|
150
|
+
},
|
|
151
|
+
monthArrowIcon: {
|
|
152
|
+
k1xSpc: "x3nfvp2",
|
|
153
|
+
$$css: true
|
|
154
|
+
},
|
|
155
|
+
title: {
|
|
156
|
+
k1xSpc: "x78zum5",
|
|
157
|
+
kGNEyG: "x6s0dn4",
|
|
158
|
+
kOIVth: "xzye2dw",
|
|
159
|
+
kZKoxP: "x5yr21d",
|
|
160
|
+
kg3NbH: "xf314gf",
|
|
161
|
+
keTefX: "x1s1akpx",
|
|
162
|
+
kMzoRj: "xc342km",
|
|
163
|
+
ksu8eU: "xng3xce",
|
|
164
|
+
kaIpWk: "xh6dtrn",
|
|
165
|
+
kWkggS: "xjbqb8w xyxi2l3 x150ydqw xoevpu5",
|
|
166
|
+
kMwMTN: "x1tgivj0",
|
|
167
|
+
kGuDYH: "x18juvz8",
|
|
168
|
+
k63SB2: "x2mo6ok",
|
|
169
|
+
kkrTdU: "x1ypdohk x16khyan",
|
|
170
|
+
khDVqt: "xuxw1ft",
|
|
171
|
+
$$css: true
|
|
172
|
+
},
|
|
173
|
+
titleChevron: {
|
|
174
|
+
k1xSpc: "x3nfvp2",
|
|
175
|
+
k1ekBW: "x11xpdln",
|
|
176
|
+
kIyJzY: "xuedmi6",
|
|
177
|
+
kAMwcw: "xlr8y92",
|
|
178
|
+
k6CgDc: "xzg1mie",
|
|
179
|
+
$$css: true
|
|
180
|
+
},
|
|
181
|
+
titleChevronOpen: {
|
|
182
|
+
k3aq6I: "x19jd1h0",
|
|
183
|
+
$$css: true
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* The touch surface. Takes `DateInput`'s props verbatim; see
|
|
189
|
+
* {@link DateInput} for when it is chosen over the desktop control.
|
|
190
|
+
*/
|
|
191
|
+
export function TouchDateField({
|
|
192
|
+
label,
|
|
193
|
+
isLabelHidden = false,
|
|
194
|
+
description,
|
|
195
|
+
isOptional = false,
|
|
196
|
+
isRequired = false,
|
|
197
|
+
isDisabled = false,
|
|
198
|
+
disabledMessage,
|
|
199
|
+
value,
|
|
200
|
+
onChange,
|
|
201
|
+
changeAction,
|
|
202
|
+
isLoading = false,
|
|
203
|
+
min,
|
|
204
|
+
max,
|
|
205
|
+
dateConstraints,
|
|
206
|
+
placeholder: placeholderFromProps,
|
|
207
|
+
size: sizeProp,
|
|
208
|
+
status,
|
|
209
|
+
statusVariant = 'attached',
|
|
210
|
+
labelTooltip,
|
|
211
|
+
hasClear = false,
|
|
212
|
+
// Desktop-only: the scroller is a single continuously paged column, so a
|
|
213
|
+
// second month would be the month already one flick away. Accepted (the
|
|
214
|
+
// prop types are shared) and ignored.
|
|
215
|
+
numberOfMonths: _numberOfMonths,
|
|
216
|
+
weekStartsOn: weekStartsOnProp = 0,
|
|
217
|
+
format = 'date_long',
|
|
218
|
+
width,
|
|
219
|
+
xstyle,
|
|
220
|
+
className,
|
|
221
|
+
style,
|
|
222
|
+
ref,
|
|
223
|
+
...rest
|
|
224
|
+
}) {
|
|
225
|
+
const t = useTranslator();
|
|
226
|
+
const isEffectivelyRequired = useResolvedRequired({
|
|
227
|
+
isRequired,
|
|
228
|
+
isOptional
|
|
229
|
+
});
|
|
230
|
+
const placeholder = placeholderFromProps ?? t('@astryx.dateInput.placeholder');
|
|
231
|
+
const size = useSize(sizeProp, 'md');
|
|
232
|
+
const weekStartsOn = normalizeDayOfWeek(weekStartsOnProp);
|
|
233
|
+
const id = useId();
|
|
234
|
+
const inputLabelID = useId();
|
|
235
|
+
const descriptionID = useId();
|
|
236
|
+
const statusMessageID = useId();
|
|
237
|
+
const inputRef = useRef(null);
|
|
238
|
+
const inputGroup = useInputGroup();
|
|
239
|
+
const [, startTransition] = useTransition();
|
|
240
|
+
const [optimisticValue, setOptimisticValue] = useOptimistic(value);
|
|
241
|
+
const isBusy = isLoading || optimisticValue !== value;
|
|
242
|
+
const isEffectivelyDisabled = isDisabled || isBusy;
|
|
243
|
+
|
|
244
|
+
// Disabled-reason tooltip, same contract as DateInput: a disabled control
|
|
245
|
+
// swallows pointer events, so the listeners attach to the wrapper and the
|
|
246
|
+
// input stays focusable via aria-disabled rather than the disabled
|
|
247
|
+
// attribute. Only the persistent disabled state surfaces a reason, never
|
|
248
|
+
// the transient busy one.
|
|
249
|
+
const showsDisabledMessage = isDisabled && !!disabledMessage;
|
|
250
|
+
const disabledMessageTooltip = useTooltip({
|
|
251
|
+
placement: 'above',
|
|
252
|
+
focusTrigger: 'always',
|
|
253
|
+
isEnabled: showsDisabledMessage
|
|
254
|
+
});
|
|
255
|
+
const {
|
|
256
|
+
isDateDisabled
|
|
257
|
+
} = useCalendarConstraints({
|
|
258
|
+
min,
|
|
259
|
+
max,
|
|
260
|
+
dateConstraints
|
|
261
|
+
});
|
|
262
|
+
const {
|
|
263
|
+
statusIcon,
|
|
264
|
+
describedBy: statusTooltipDescribedBy
|
|
265
|
+
} = useInputStatusIcon({
|
|
266
|
+
status,
|
|
267
|
+
statusVariant,
|
|
268
|
+
isInGroup: !!inputGroup
|
|
269
|
+
});
|
|
270
|
+
const {
|
|
271
|
+
ariaLabelledBy,
|
|
272
|
+
ariaDescribedBy
|
|
273
|
+
} = getInputARIA(inputLabelID, [description ? descriptionID : null, statusVariant !== 'tooltip' && status?.message ? statusMessageID : null, statusTooltipDescribedBy, showsDisabledMessage ? disabledMessageTooltip.describedBy : null], inputGroup);
|
|
274
|
+
const [isSheetOpen, setIsSheetOpen] = useState(false);
|
|
275
|
+
const [isWheelOpen, setIsWheelOpen] = useState(false);
|
|
276
|
+
const scrollerHandleRef = useRef(null);
|
|
277
|
+
const today = useMemo(() => plainDateToday(), []);
|
|
278
|
+
const selectedDate = useMemo(() => optimisticValue != null && /^\d{4}-\d{2}-\d{2}$/.test(optimisticValue) ? plainDateFromISO(optimisticValue) : null, [optimisticValue]);
|
|
279
|
+
|
|
280
|
+
// The reachable range. Explicit bounds win; otherwise the scroller reaches a
|
|
281
|
+
// century in each direction from wherever it opened. Anchored once, in a
|
|
282
|
+
// state initializer: recomputing it as the selection moves would shift every
|
|
283
|
+
// pane's scroll offset under the user mid-gesture.
|
|
284
|
+
const [anchorMonthIndex] = useState(() => monthIndexOf(value != null && /^\d{4}-\d{2}-\d{2}$/.test(value) ? plainDateFromISO(value) : plainDateToday()));
|
|
285
|
+
const minMonthIndex = min != null ? monthIndexOf(plainDateFromISO(min)) : anchorMonthIndex - DEFAULT_MONTH_REACH;
|
|
286
|
+
const maxMonthIndex = max != null ? monthIndexOf(plainDateFromISO(max)) : anchorMonthIndex + DEFAULT_MONTH_REACH;
|
|
287
|
+
const [monthIndex, setMonthIndex] = useState(() => clampIndex(anchorMonthIndex, minMonthIndex, maxMonthIndex));
|
|
288
|
+
const {
|
|
289
|
+
year,
|
|
290
|
+
month
|
|
291
|
+
} = fromMonthIndex(monthIndex);
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Three-letter weekday names — "Sun", not Calendar's "Su".
|
|
295
|
+
*
|
|
296
|
+
* The sheet is full width and the columns are ~51px, so there is room for
|
|
297
|
+
* the form people actually read, and a picker operated by thumb should not
|
|
298
|
+
* make anyone decode "Tu" against "Th".
|
|
299
|
+
*
|
|
300
|
+
* This is CLDR's `abbreviated` width, which `Intl` produces natively — no
|
|
301
|
+
* truncation, so the 28 non-English locales stay correct rather than being
|
|
302
|
+
* sliced to three characters. (Verified against the CLDR tables for all 30
|
|
303
|
+
* locales in the catalog.) Calendar's 2-letter row is CLDR's *short* width,
|
|
304
|
+
* which `Intl` cannot express, which is exactly why that surface needs a
|
|
305
|
+
* generated table and this one does not.
|
|
306
|
+
*
|
|
307
|
+
* Built here rather than taken from `useCalendarDays`, which supplies the
|
|
308
|
+
* short form for Calendar's own header. The rotation matches: day 4 of
|
|
309
|
+
* January 1970 was a Sunday, so offsetting from it by `weekStartsOn` walks
|
|
310
|
+
* the week in the same order the panes lay out their columns.
|
|
311
|
+
*/
|
|
312
|
+
const dayNames = useMemo(() => Array.from({
|
|
313
|
+
length: 7
|
|
314
|
+
}, (_, offset) => plainDateFormat({
|
|
315
|
+
year: 1970,
|
|
316
|
+
month: 1,
|
|
317
|
+
day: 4 + (weekStartsOn + offset) % 7
|
|
318
|
+
}, DATE_FORMAT_WEEKDAY_ONLY)), [weekStartsOn]);
|
|
319
|
+
const monthYearLabel = plainDateFormat({
|
|
320
|
+
year,
|
|
321
|
+
month,
|
|
322
|
+
day: 1
|
|
323
|
+
}, DATE_FORMAT_MONTH_YEAR);
|
|
324
|
+
|
|
325
|
+
// Formats the committed value only. A function format is called with the ISO
|
|
326
|
+
// value; a named one reuses Timestamp's shared date mapping, so the same
|
|
327
|
+
// literal renders the same shape here and on the desktop control.
|
|
328
|
+
const displayValue = optimisticValue != null && /^\d{4}-\d{2}-\d{2}$/.test(optimisticValue) ? typeof format === 'function' ? format(optimisticValue) : formatSharedDate(plainDateFromISO(optimisticValue), format) : '';
|
|
329
|
+
const fireChange = useCallback(newValue => {
|
|
330
|
+
if (isBusy) {
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
onChange?.(newValue);
|
|
334
|
+
if (changeAction) {
|
|
335
|
+
startTransition(async () => {
|
|
336
|
+
setOptimisticValue(newValue);
|
|
337
|
+
await changeAction(newValue);
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
}, [isBusy, onChange, changeAction, startTransition, setOptimisticValue]);
|
|
341
|
+
const openSheet = useCallback(() => {
|
|
342
|
+
if (!isEffectivelyDisabled) {
|
|
343
|
+
// Always onto the calendar, whatever was showing last time. The wheels
|
|
344
|
+
// are a detour taken to reach a far month, not a mode to be left in:
|
|
345
|
+
// reopening into them would answer a question the user has not asked
|
|
346
|
+
// yet, and hide the dates they came back for behind another tap.
|
|
347
|
+
setIsWheelOpen(false);
|
|
348
|
+
setIsSheetOpen(true);
|
|
349
|
+
}
|
|
350
|
+
}, [isEffectivelyDisabled]);
|
|
351
|
+
const handleClear = useCallback(() => {
|
|
352
|
+
fireChange(undefined);
|
|
353
|
+
inputRef.current?.focus();
|
|
354
|
+
}, [fireChange]);
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Put the picker back to how it opens: no date, current month.
|
|
358
|
+
*
|
|
359
|
+
* Two things, because clearing a date and then being left staring at the
|
|
360
|
+
* month of the date you just cleared is a half-finished action — the
|
|
361
|
+
* calendar should look the way it does before anything is chosen.
|
|
362
|
+
*
|
|
363
|
+
* "If possible" is load-bearing: a range can exclude the current month
|
|
364
|
+
* entirely (a booking window starting next quarter), and there is no
|
|
365
|
+
* honest place to go in that case. `clampIndex` would silently land on the
|
|
366
|
+
* nearest edge, which is a different month presented as if it were today's,
|
|
367
|
+
* so the move is skipped instead and the calendar stays where it is. The
|
|
368
|
+
* value is still cleared either way — that half never depends on the range.
|
|
369
|
+
*/
|
|
370
|
+
const handleResetInSheet = useCallback(() => {
|
|
371
|
+
fireChange(undefined);
|
|
372
|
+
const currentMonth = monthIndexOf(today);
|
|
373
|
+
if (currentMonth < minMonthIndex || currentMonth > maxMonthIndex) {
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
if (currentMonth === monthIndex) {
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
setMonthIndex(currentMonth);
|
|
380
|
+
scrollerHandleRef.current?.scrollToMonth(currentMonth, 'smooth');
|
|
381
|
+
}, [fireChange, today, monthIndex, minMonthIndex, maxMonthIndex]);
|
|
382
|
+
|
|
383
|
+
// Selection commits on the tap and leaves the sheet up, so a mistake can be
|
|
384
|
+
// corrected in place and a nearby date reconsidered without reopening.
|
|
385
|
+
// Dismissal is the footer's Done (and the handle, the scrim, Escape) — none
|
|
386
|
+
// of which commit anything, because this already has.
|
|
387
|
+
const handleSelect = useCallback(next => {
|
|
388
|
+
fireChange(next);
|
|
389
|
+
}, [fireChange]);
|
|
390
|
+
|
|
391
|
+
// Whether there is anywhere to step. An arrow with nowhere to go is hidden
|
|
392
|
+
// rather than disabled: a disabled control still says "this is a thing you
|
|
393
|
+
// could do", and at the end of a range it is not — the range is the whole
|
|
394
|
+
// truth, and there is no state the user can reach where it becomes
|
|
395
|
+
// available. A greyed chevron sitting there permanently reads as broken.
|
|
396
|
+
const canStepBack = monthIndex > minMonthIndex;
|
|
397
|
+
const canStepForward = monthIndex < maxMonthIndex;
|
|
398
|
+
|
|
399
|
+
// One month either way, clamped to the reachable range. Goes through the
|
|
400
|
+
// same scrollToMonth the swipe settles on, so the arrows and the gesture
|
|
401
|
+
// cannot disagree about where a month rests.
|
|
402
|
+
const stepMonth = useCallback(delta => {
|
|
403
|
+
const target = clampIndex(monthIndex + delta, minMonthIndex, maxMonthIndex);
|
|
404
|
+
if (target === monthIndex) {
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
setMonthIndex(target);
|
|
408
|
+
scrollerHandleRef.current?.scrollToMonth(target, 'smooth');
|
|
409
|
+
}, [monthIndex, minMonthIndex, maxMonthIndex]);
|
|
410
|
+
|
|
411
|
+
// A wheel commit steers the scroller immediately, even though it is behind
|
|
412
|
+
// the wheels: it keeps its layout box while hidden, so by the time the
|
|
413
|
+
// wheels close it is already resting on the new month.
|
|
414
|
+
const handleWheelChange = useCallback(next => {
|
|
415
|
+
setMonthIndex(next);
|
|
416
|
+
scrollerHandleRef.current?.scrollToMonth(next, 'auto');
|
|
417
|
+
}, []);
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* The calendar reports the month it has scrolled to — but only while it is
|
|
421
|
+
* the surface being scrolled.
|
|
422
|
+
*
|
|
423
|
+
* While the wheels are up the wheels are the source of truth, and the
|
|
424
|
+
* calendar is being STEERED by them: a wheel commit calls `scrollToMonth`
|
|
425
|
+
* above, the calendar scrolls, and it would report that month straight back
|
|
426
|
+
* here. That closes a cycle — wheel commits, calendar echoes, the echo moves
|
|
427
|
+
* the wheel's selected row, the wheel is repositioned onto it, and the
|
|
428
|
+
* resulting scroll reads as another commit.
|
|
429
|
+
*
|
|
430
|
+
* Whether that cycle converges depends on how precisely a browser reports
|
|
431
|
+
* "scrolling stopped", which is not something to rely on. With `scrollend`
|
|
432
|
+
* (Chrome) it settles at once; on iOS below Safari 26 there is no
|
|
433
|
+
* `scrollend` and momentum runs on for a second or more after the finger
|
|
434
|
+
* lifts, so each lap committed the next month along and the value climbed
|
|
435
|
+
* on its own. Ignoring the echo removes the cycle instead of damping it.
|
|
436
|
+
*/
|
|
437
|
+
const handleVisibleMonthChange = useCallback(next => {
|
|
438
|
+
if (isWheelOpen) {
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
setMonthIndex(next);
|
|
442
|
+
}, [isWheelOpen]);
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* Put the calendar back where it belongs when the wheels close.
|
|
446
|
+
*
|
|
447
|
+
* The wheels steer it while it is hidden, and a hidden scroller is not a
|
|
448
|
+
* reliable place to leave a scroll position: `visibility: hidden` keeps the
|
|
449
|
+
* layout box, but iOS re-snaps the scroller when it becomes visible again,
|
|
450
|
+
* and it does not necessarily re-snap to the pane we put it on. That fires
|
|
451
|
+
* a scroll at the exact moment reports start being trusted again — which is
|
|
452
|
+
* why the month drifted on the way back to the dates.
|
|
453
|
+
*
|
|
454
|
+
* Re-asserting is cheap when nothing moved (the scroller is already there,
|
|
455
|
+
* so nothing scrolls) and exactly right when something did. `scrollToMonth`
|
|
456
|
+
* marks the target as steered, so this correction does not report itself
|
|
457
|
+
* back either.
|
|
458
|
+
*/
|
|
459
|
+
// Read through a ref so this effect depends on the surface change alone.
|
|
460
|
+
// Listing `monthIndex` would re-run it on every month the user swipes to,
|
|
461
|
+
// yanking the scroller back mid-gesture.
|
|
462
|
+
const monthIndexRef = useRef(monthIndex);
|
|
463
|
+
monthIndexRef.current = monthIndex;
|
|
464
|
+
useEffect(() => {
|
|
465
|
+
if (isWheelOpen) {
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
scrollerHandleRef.current?.scrollToMonth(monthIndexRef.current, 'auto');
|
|
469
|
+
}, [isWheelOpen]);
|
|
470
|
+
|
|
471
|
+
// APG combobox keys. The field takes no text, so every printable key is
|
|
472
|
+
// free — but only the documented openers are wired, so a stray keystroke
|
|
473
|
+
// does not pop a sheet.
|
|
474
|
+
const handleInputKeyDown = useCallback(event => {
|
|
475
|
+
// Same guard core's pointer surface carries. This field is readOnly and
|
|
476
|
+
// takes no composition of its own, but an IME sitting over it still
|
|
477
|
+
// sends its committing Enter here first — and opening a date sheet on
|
|
478
|
+
// the keystroke that finishes a Korean syllable is the same wrong
|
|
479
|
+
// answer. See utils/ime.ts.
|
|
480
|
+
if (isImeKeyEvent(event.nativeEvent)) {
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
if (event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ' || event.key === 'Spacebar') {
|
|
484
|
+
event.preventDefault();
|
|
485
|
+
openSheet();
|
|
486
|
+
}
|
|
487
|
+
}, [openSheet]);
|
|
488
|
+
const surface = /*#__PURE__*/_jsxs("div", {
|
|
489
|
+
...{
|
|
490
|
+
className: "x78zum5 xdt5ytf xh8yej3"
|
|
491
|
+
},
|
|
492
|
+
children: [/*#__PURE__*/_jsxs("div", {
|
|
493
|
+
...{
|
|
494
|
+
className: "x78zum5 x6s0dn4 x1qughib x1txdalj xssyfek"
|
|
495
|
+
},
|
|
496
|
+
children: [/*#__PURE__*/_jsxs("button", {
|
|
497
|
+
type: "button",
|
|
498
|
+
onClick: () => setIsWheelOpen(open => !open),
|
|
499
|
+
"aria-expanded": isWheelOpen
|
|
500
|
+
// One string, not a template: the comma and the word order are
|
|
501
|
+
// the translator's to choose, not English's.
|
|
502
|
+
,
|
|
503
|
+
"aria-label": t('@astryx.dateInput.chooseMonthYear', {
|
|
504
|
+
monthYear: monthYearLabel
|
|
505
|
+
})
|
|
506
|
+
// A `data-` hook rather than a theme target. `themeProps` would
|
|
507
|
+
// publish `astryx-date-input-touch-title` as a themeable selector,
|
|
508
|
+
// and this is internal structure of the sheet — the field and its
|
|
509
|
+
// toggle icon are the documented targets, and nothing has asked to
|
|
510
|
+
// restyle the header button. Adding a target later is additive;
|
|
511
|
+
// withdrawing one is not.
|
|
512
|
+
,
|
|
513
|
+
"data-title": "month-year",
|
|
514
|
+
...stylex.props(styles.title, focusOutlineStyles.focusVisible),
|
|
515
|
+
children: [/*#__PURE__*/_jsx("span", {
|
|
516
|
+
children: monthYearLabel
|
|
517
|
+
}), /*#__PURE__*/_jsx(Icon, {
|
|
518
|
+
icon: "chevronDown",
|
|
519
|
+
size: "sm",
|
|
520
|
+
color: "secondary"
|
|
521
|
+
// The transform rides on the Icon itself, not a wrapper span, so
|
|
522
|
+
// the element a theme can target is the element that moves.
|
|
523
|
+
,
|
|
524
|
+
xstyle: [styles.titleChevron, isWheelOpen && styles.titleChevronOpen]
|
|
525
|
+
})]
|
|
526
|
+
}), /*#__PURE__*/_jsxs("span", {
|
|
527
|
+
"data-arrows": "months"
|
|
528
|
+
// `inert` as well as the hidden styling: the fade keeps them
|
|
529
|
+
// `visible` until it finishes, and a control that is on its way out
|
|
530
|
+
// should not answer a click or a Tab in the meantime.
|
|
531
|
+
,
|
|
532
|
+
inert: isWheelOpen ? true : undefined,
|
|
533
|
+
...{
|
|
534
|
+
0: {
|
|
535
|
+
className: "x78zum5 x6s0dn4 x1lsbc85 xvc5jky x1jl3cmp xuedmi6 xcj1dhv xzg1mie"
|
|
536
|
+
},
|
|
537
|
+
1: {
|
|
538
|
+
className: "x78zum5 x6s0dn4 x1lsbc85 xvc5jky x1jl3cmp xuedmi6 xcj1dhv xzg1mie xlshs6z xg01cxk x47corl"
|
|
539
|
+
}
|
|
540
|
+
}[!!isWheelOpen << 0],
|
|
541
|
+
children: [/*#__PURE__*/_jsx(IconButton, {
|
|
542
|
+
variant: "ghost",
|
|
543
|
+
size: "sm",
|
|
544
|
+
xstyle: [styles.monthArrow, !canStepBack && styles.monthArrowUnavailable],
|
|
545
|
+
isDisabled: !canStepBack,
|
|
546
|
+
onClick: () => stepMonth(-1),
|
|
547
|
+
label: t('@astryx.calendar.previousMonth'),
|
|
548
|
+
icon: /*#__PURE__*/_jsx("span", {
|
|
549
|
+
...stylex.props(styles.monthArrowIcon, rtlStyles.mirror),
|
|
550
|
+
children: /*#__PURE__*/_jsx(Icon, {
|
|
551
|
+
icon: "chevronLeft",
|
|
552
|
+
size: "sm",
|
|
553
|
+
color: "inherit"
|
|
554
|
+
})
|
|
555
|
+
})
|
|
556
|
+
}), /*#__PURE__*/_jsx(IconButton, {
|
|
557
|
+
variant: "ghost",
|
|
558
|
+
size: "sm",
|
|
559
|
+
xstyle: [styles.monthArrow, !canStepForward && styles.monthArrowUnavailable],
|
|
560
|
+
isDisabled: !canStepForward,
|
|
561
|
+
onClick: () => stepMonth(1),
|
|
562
|
+
label: t('@astryx.calendar.nextMonth'),
|
|
563
|
+
icon: /*#__PURE__*/_jsx("span", {
|
|
564
|
+
...stylex.props(styles.monthArrowIcon, rtlStyles.mirror),
|
|
565
|
+
children: /*#__PURE__*/_jsx(Icon, {
|
|
566
|
+
icon: "chevronRight",
|
|
567
|
+
size: "sm",
|
|
568
|
+
color: "inherit"
|
|
569
|
+
})
|
|
570
|
+
})
|
|
571
|
+
})]
|
|
572
|
+
})]
|
|
573
|
+
}), /*#__PURE__*/_jsx("div", {
|
|
574
|
+
"aria-hidden": "true",
|
|
575
|
+
...{
|
|
576
|
+
0: {
|
|
577
|
+
className: "xrvj5dj x1mzazjb x6k0iem x6s0dn4 x1jl3cmp xuedmi6 xcj1dhv xzg1mie"
|
|
578
|
+
},
|
|
579
|
+
1: {
|
|
580
|
+
className: "xrvj5dj x1mzazjb x6k0iem x6s0dn4 x1jl3cmp xuedmi6 xcj1dhv xzg1mie xlshs6z xg01cxk"
|
|
581
|
+
}
|
|
582
|
+
}[!!isWheelOpen << 0],
|
|
583
|
+
children: dayNames.map(name => /*#__PURE__*/_jsx("div", {
|
|
584
|
+
...{
|
|
585
|
+
className: "x2b8uid x141an7d x1sodnla xv1l7n4"
|
|
586
|
+
},
|
|
587
|
+
children: name
|
|
588
|
+
}, name))
|
|
589
|
+
}), /*#__PURE__*/_jsxs("div", {
|
|
590
|
+
...{
|
|
591
|
+
className: "xrvj5dj xm8gem x1n2onr6"
|
|
592
|
+
},
|
|
593
|
+
children: [/*#__PURE__*/_jsx("div", {
|
|
594
|
+
"data-panel": "calendar"
|
|
595
|
+
// `inert` as well as the hidden styling: the panel keeps its layout
|
|
596
|
+
// box (so the scroller holds its position and the wheels can steer
|
|
597
|
+
// it), which means without this it would still be tabbable behind
|
|
598
|
+
// the layer on top.
|
|
599
|
+
,
|
|
600
|
+
inert: isWheelOpen ? true : undefined,
|
|
601
|
+
...{
|
|
602
|
+
0: {
|
|
603
|
+
className: "x15r89dc xeuugli x74b7sa xuedmi6 xzg1mie"
|
|
604
|
+
},
|
|
605
|
+
1: {
|
|
606
|
+
className: "x15r89dc xeuugli x74b7sa xuedmi6 xzg1mie xlshs6z x47corl"
|
|
607
|
+
}
|
|
608
|
+
}[!!isWheelOpen << 0],
|
|
609
|
+
children: /*#__PURE__*/_jsx(MonthScroller, {
|
|
610
|
+
handleRef: scrollerHandleRef,
|
|
611
|
+
minMonthIndex: minMonthIndex,
|
|
612
|
+
maxMonthIndex: maxMonthIndex,
|
|
613
|
+
initialMonthIndex: monthIndex,
|
|
614
|
+
onVisibleMonthChange: handleVisibleMonthChange,
|
|
615
|
+
selectedDate: selectedDate,
|
|
616
|
+
today: today,
|
|
617
|
+
isDateDisabled: isDateDisabled,
|
|
618
|
+
weekStartsOn: weekStartsOn,
|
|
619
|
+
onSelect: handleSelect
|
|
620
|
+
}, `${minMonthIndex}:${maxMonthIndex}`)
|
|
621
|
+
}), /*#__PURE__*/_jsx("div", {
|
|
622
|
+
"data-panel": "wheels",
|
|
623
|
+
inert: isWheelOpen ? undefined : true,
|
|
624
|
+
...{
|
|
625
|
+
0: {
|
|
626
|
+
className: "x15r89dc xeuugli x10xzikg xc8icb0 x1jl3cmp xuedmi6 xcj1dhv xzg1mie"
|
|
627
|
+
},
|
|
628
|
+
1: {
|
|
629
|
+
className: "x15r89dc xeuugli x10xzikg xc8icb0 x1jl3cmp xuedmi6 xcj1dhv xzg1mie xlshs6z xg01cxk x47corl"
|
|
630
|
+
}
|
|
631
|
+
}[!!!isWheelOpen << 0],
|
|
632
|
+
children: /*#__PURE__*/_jsx(MonthYearWheels, {
|
|
633
|
+
monthIndex: monthIndex,
|
|
634
|
+
minMonthIndex: minMonthIndex,
|
|
635
|
+
maxMonthIndex: maxMonthIndex,
|
|
636
|
+
onChange: handleWheelChange,
|
|
637
|
+
monthLabel: t('@astryx.dateInput.monthWheel'),
|
|
638
|
+
yearLabel: t('@astryx.dateInput.yearWheel'),
|
|
639
|
+
isActive: isWheelOpen
|
|
640
|
+
})
|
|
641
|
+
})]
|
|
642
|
+
}), /*#__PURE__*/_jsxs("div", {
|
|
643
|
+
...{
|
|
644
|
+
className: "x1xye8es xrvj5dj x1y6fwsi"
|
|
645
|
+
},
|
|
646
|
+
children: [/*#__PURE__*/_jsxs("div", {
|
|
647
|
+
inert: isWheelOpen ? true : undefined,
|
|
648
|
+
...{
|
|
649
|
+
0: {
|
|
650
|
+
className: "x15r89dc x78zum5 x1txdalj x74b7sa xuedmi6 xzg1mie"
|
|
651
|
+
},
|
|
652
|
+
1: {
|
|
653
|
+
className: "x15r89dc x78zum5 x1txdalj x74b7sa xuedmi6 xzg1mie xlshs6z x47corl"
|
|
654
|
+
}
|
|
655
|
+
}[!!isWheelOpen << 0],
|
|
656
|
+
children: [/*#__PURE__*/_jsx(Button, {
|
|
657
|
+
variant: "secondary",
|
|
658
|
+
size: "md",
|
|
659
|
+
width: "100%",
|
|
660
|
+
label: t('@astryx.dateInput.resetPicking'),
|
|
661
|
+
onClick: handleResetInSheet
|
|
662
|
+
}), /*#__PURE__*/_jsx(Button, {
|
|
663
|
+
variant: "primary"
|
|
664
|
+
// md, not sm: it is the action a thumb reaches for, so it gets
|
|
665
|
+
// the comfortable size rather than the compact one the header's
|
|
666
|
+
// ghost buttons use.
|
|
667
|
+
,
|
|
668
|
+
size: "md",
|
|
669
|
+
width: "100%",
|
|
670
|
+
label: t('@astryx.dateInput.savePicking'),
|
|
671
|
+
onClick: () => setIsSheetOpen(false)
|
|
672
|
+
})]
|
|
673
|
+
}), /*#__PURE__*/_jsx("div", {
|
|
674
|
+
inert: isWheelOpen ? undefined : true,
|
|
675
|
+
...{
|
|
676
|
+
0: {
|
|
677
|
+
className: "x15r89dc x78zum5 x1txdalj x10xzikg xc8icb0 x1jl3cmp xuedmi6 xcj1dhv xzg1mie"
|
|
678
|
+
},
|
|
679
|
+
1: {
|
|
680
|
+
className: "x15r89dc x78zum5 x1txdalj x10xzikg xc8icb0 x1jl3cmp xuedmi6 xcj1dhv xzg1mie xlshs6z xg01cxk x47corl"
|
|
681
|
+
}
|
|
682
|
+
}[!!!isWheelOpen << 0],
|
|
683
|
+
children: /*#__PURE__*/_jsx(Button
|
|
684
|
+
// secondary, not primary: this one does not finish the task, it
|
|
685
|
+
// finishes a step. Giving both surfaces a primary button would
|
|
686
|
+
// say the wheels are somewhere you can complete from.
|
|
687
|
+
, {
|
|
688
|
+
variant: "secondary",
|
|
689
|
+
size: "md",
|
|
690
|
+
width: "100%",
|
|
691
|
+
label: t('@astryx.dateInput.doneChoosingMonth'),
|
|
692
|
+
onClick: () => setIsWheelOpen(false)
|
|
693
|
+
})
|
|
694
|
+
})]
|
|
695
|
+
})]
|
|
696
|
+
});
|
|
697
|
+
const inputWrapper = /*#__PURE__*/_jsxs("div", {
|
|
698
|
+
ref: el => {
|
|
699
|
+
// Anchor + hover/focus listeners for the disabled-message tooltip.
|
|
700
|
+
// Gated internally by isEnabled, so attaching unconditionally is safe.
|
|
701
|
+
disabledMessageTooltip.ref(el);
|
|
702
|
+
},
|
|
703
|
+
...rest,
|
|
704
|
+
...mergeProps(themeProps('date-input', {
|
|
705
|
+
size,
|
|
706
|
+
status: status?.type ?? null,
|
|
707
|
+
disabled: isDisabled ? 'disabled' : null
|
|
708
|
+
}), stylex.props(inputWrapperStyles.base, sizeStyles[size], styles.wrapper, isEffectivelyDisabled && inputWrapperStyles.disabled, status && inputStatusBorderStyles[status.type], status && !isEffectivelyDisabled && inputStatusHoverShadowStyles[status.type], status && inputStatusFocusWithinStyles[status.type], inputGroup && groupStyles.inGroup, xstyle), className, style),
|
|
709
|
+
children: [inputGroup && /*#__PURE__*/_jsx(VisuallyHidden, {
|
|
710
|
+
id: inputLabelID,
|
|
711
|
+
children: label
|
|
712
|
+
}), /*#__PURE__*/_jsx("button", {
|
|
713
|
+
type: "button",
|
|
714
|
+
onClick: openSheet,
|
|
715
|
+
disabled: isEffectivelyDisabled,
|
|
716
|
+
"aria-label": t('@astryx.dateInput.openCalendar'),
|
|
717
|
+
tabIndex: -1,
|
|
718
|
+
...stylex.props(focusOutlineStyles.focusVisible, styles.iconButton, isEffectivelyDisabled && styles.iconButtonDisabled),
|
|
719
|
+
children: /*#__PURE__*/_jsx(Icon, {
|
|
720
|
+
icon: "calendar",
|
|
721
|
+
size: "sm",
|
|
722
|
+
color: "secondary",
|
|
723
|
+
...themeProps('date-input-toggle-icon', {
|
|
724
|
+
state: isSheetOpen ? 'expanded' : 'collapsed'
|
|
725
|
+
})
|
|
726
|
+
})
|
|
727
|
+
}), /*#__PURE__*/_jsx("input", {
|
|
728
|
+
ref: mergeRefs(ref, inputRef),
|
|
729
|
+
id: id,
|
|
730
|
+
type: "text",
|
|
731
|
+
role: "combobox",
|
|
732
|
+
value: displayValue
|
|
733
|
+
// No typing on this surface: the picker is the input method, and the
|
|
734
|
+
// virtual keyboard would cover the sheet it is meant to fill in.
|
|
735
|
+
// readOnly blocks entry; inputMode="none" is what actually keeps the
|
|
736
|
+
// keyboard down when the field takes focus.
|
|
737
|
+
,
|
|
738
|
+
readOnly: true,
|
|
739
|
+
inputMode: "none",
|
|
740
|
+
onChange: () => {},
|
|
741
|
+
onClick: openSheet,
|
|
742
|
+
onKeyDown: handleInputKeyDown,
|
|
743
|
+
placeholder: placeholder,
|
|
744
|
+
disabled: isEffectivelyDisabled && !showsDisabledMessage,
|
|
745
|
+
"aria-disabled": showsDisabledMessage ? 'true' : undefined,
|
|
746
|
+
"aria-labelledby": ariaLabelledBy,
|
|
747
|
+
"aria-describedby": ariaDescribedBy,
|
|
748
|
+
"aria-required": isEffectivelyRequired ? 'true' : undefined,
|
|
749
|
+
"aria-invalid": status?.type === 'error' ? 'true' : undefined,
|
|
750
|
+
"aria-busy": isBusy || undefined,
|
|
751
|
+
"aria-expanded": isSheetOpen,
|
|
752
|
+
"aria-haspopup": "dialog",
|
|
753
|
+
"aria-autocomplete": "none",
|
|
754
|
+
autoComplete: "off",
|
|
755
|
+
...{
|
|
756
|
+
0: {
|
|
757
|
+
className: "x1lliihq x98rzlu xeuugli xc342km xng3xce x1717udv x9ynric xjm74w1 x6pjikd xw6l6zx x1tgivj0 xjbqb8w x1a2a7pz xbuiw85 x1ypdohk x16khyan x87ps6o xeyghm5"
|
|
758
|
+
},
|
|
759
|
+
1: {
|
|
760
|
+
className: "x1lliihq x98rzlu xeuugli xc342km xng3xce x1717udv x9ynric xjm74w1 x6pjikd xw6l6zx x1tgivj0 xjbqb8w x1a2a7pz xbuiw85 x87ps6o xeyghm5 xt0e3qv"
|
|
761
|
+
}
|
|
762
|
+
}[!!isEffectivelyDisabled << 0]
|
|
763
|
+
}), hasClear && value !== undefined && !isEffectivelyDisabled && /*#__PURE__*/_jsx(InputClearButton, {
|
|
764
|
+
label: t('@astryx.dateInput.clear', {
|
|
765
|
+
label
|
|
766
|
+
}),
|
|
767
|
+
onClick: handleClear,
|
|
768
|
+
iconClassName: stableClassName('date-input-clear-icon')
|
|
769
|
+
}), isBusy && /*#__PURE__*/_jsx(Spinner, {
|
|
770
|
+
size: "sm"
|
|
771
|
+
}), statusIcon, /*#__PURE__*/_jsx(BottomSheet, {
|
|
772
|
+
isOpen: isSheetOpen,
|
|
773
|
+
onOpenChange: setIsSheetOpen,
|
|
774
|
+
label: t('@astryx.dateInput.dialogLabel')
|
|
775
|
+
// The picker is a fixed height by construction, so the sheet should be
|
|
776
|
+
// exactly as tall as it is rather than claiming a viewport budget.
|
|
777
|
+
,
|
|
778
|
+
height: "hug",
|
|
779
|
+
children: /*#__PURE__*/_jsx("div", {
|
|
780
|
+
...{
|
|
781
|
+
className: "x1pzlopt x1adxfkp x1awphl8"
|
|
782
|
+
},
|
|
783
|
+
children: surface
|
|
784
|
+
})
|
|
785
|
+
}), showsDisabledMessage && disabledMessageTooltip.renderTooltip(disabledMessage)]
|
|
786
|
+
});
|
|
787
|
+
if (inputGroup) {
|
|
788
|
+
return inputWrapper;
|
|
789
|
+
}
|
|
790
|
+
return /*#__PURE__*/_jsx(Field, {
|
|
791
|
+
label: label,
|
|
792
|
+
isLabelHidden: isLabelHidden,
|
|
793
|
+
description: description,
|
|
794
|
+
inputID: id,
|
|
795
|
+
descriptionID: description ? descriptionID : undefined,
|
|
796
|
+
isOptional: isOptional,
|
|
797
|
+
isRequired: isRequired,
|
|
798
|
+
isDisabled: isDisabled,
|
|
799
|
+
status: status ? {
|
|
800
|
+
type: status.type,
|
|
801
|
+
message: status.message,
|
|
802
|
+
messageID: status.message ? statusMessageID : undefined
|
|
803
|
+
} : undefined,
|
|
804
|
+
statusVariant: statusVariant,
|
|
805
|
+
labelTooltip: labelTooltip,
|
|
806
|
+
width: width,
|
|
807
|
+
children: inputWrapper
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
TouchDateField.displayName = 'TouchDateField';
|