@astryxdesign/core 0.4.4 → 0.4.5-canary.013e728
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 +40 -0
- package/dist/AvatarGroup/AvatarGroupOverflow.js +1 -1
- package/dist/BottomSheet/BottomSheet.d.ts +11 -2
- package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheet.js +4 -0
- package/dist/BottomSheet/BottomSheetPanel.d.ts +5 -2
- package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetPanel.js +65 -15
- package/dist/BottomSheet/index.d.ts +1 -1
- package/dist/BottomSheet/index.d.ts.map +1 -1
- package/dist/BottomSheet/snapOffsets.d.ts +57 -20
- package/dist/BottomSheet/snapOffsets.d.ts.map +1 -1
- package/dist/BottomSheet/snapOffsets.js +106 -30
- package/dist/BottomSheet/useSheetGestures.d.ts +13 -8
- package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
- package/dist/BottomSheet/useSheetGestures.js +160 -64
- package/dist/Breadcrumbs/BreadcrumbItem.js +6 -6
- package/dist/Button/Button.js +5 -5
- package/dist/Calendar/Calendar.d.ts +17 -0
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +55 -15
- package/dist/Calendar/getStandaloneShortWeekdayNames.d.ts +14 -0
- package/dist/Calendar/getStandaloneShortWeekdayNames.d.ts.map +1 -0
- package/dist/Calendar/getStandaloneShortWeekdayNames.js +26 -0
- package/dist/Calendar/hooks/useCalendarConstraints.d.ts +22 -1
- package/dist/Calendar/hooks/useCalendarConstraints.d.ts.map +1 -1
- package/dist/Calendar/hooks/useCalendarConstraints.js +26 -4
- package/dist/Calendar/hooks/useCalendarDays.d.ts.map +1 -1
- package/dist/Calendar/hooks/useCalendarDays.js +14 -10
- package/dist/Calendar/hooks/useCalendarNavigation.d.ts.map +1 -1
- package/dist/Calendar/hooks/useCalendarNavigation.js +8 -4
- package/dist/Calendar/standaloneShortWeekdayNames.generated.d.ts +47 -0
- package/dist/Calendar/standaloneShortWeekdayNames.generated.d.ts.map +1 -0
- package/dist/Calendar/standaloneShortWeekdayNames.generated.js +40 -0
- package/dist/Calendar/styles.js +3 -3
- 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 +2 -2
- package/dist/Chat/ChatToolCalls.js +1 -1
- 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/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +9 -0
- package/dist/Citation/Citation.js +3 -3
- package/dist/ClickableCard/ClickableCard.js +2 -2
- package/dist/CommandPalette/CommandPaletteItem.js +1 -1
- package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
- package/dist/ComplexSelector/ComplexSelector.js +8 -3
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +17 -9
- package/dist/DateRangeInput/DateRangeInput.d.ts +23 -1
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +47 -9
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +18 -10
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +3 -3
- package/dist/Field/FieldLabel.d.ts +2 -1
- package/dist/Field/FieldLabel.d.ts.map +1 -1
- package/dist/Field/FieldLabel.js +21 -3
- package/dist/Field/InputClearButton.d.ts +2 -1
- package/dist/Field/InputClearButton.d.ts.map +1 -1
- package/dist/Field/InputClearButton.js +12 -1
- package/dist/Field/inputStyles.stylex.d.ts.map +1 -1
- package/dist/Field/inputStyles.stylex.js +4 -4
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +2 -2
- package/dist/FormLayout/FormLayout.d.ts +24 -2
- package/dist/FormLayout/FormLayout.d.ts.map +1 -1
- package/dist/FormLayout/FormLayout.js +7 -2
- package/dist/FormLayout/FormLayoutContext.d.ts +15 -2
- package/dist/FormLayout/FormLayoutContext.d.ts.map +1 -1
- package/dist/FormLayout/FormLayoutContext.js +19 -4
- package/dist/FormLayout/index.d.ts +1 -1
- package/dist/FormLayout/index.d.ts.map +1 -1
- 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/Item/Item.d.ts +9 -1
- package/dist/Item/Item.d.ts.map +1 -1
- package/dist/Item/Item.js +46 -8
- 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 +2 -1
- package/dist/Link/Link.js +4 -4
- package/dist/Markdown/Markdown.d.ts +8 -0
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.js +31 -3
- package/dist/Markdown/parser.d.ts +14 -2
- package/dist/Markdown/parser.d.ts.map +1 -1
- package/dist/Markdown/parser.js +50 -2
- 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 -3
- package/dist/NavItem/navItemStyles.stylex.d.ts +2 -2
- package/dist/NavItem/navItemStyles.stylex.js +2 -2
- package/dist/NavMenu/NavHeadingMenuItem.js +1 -1
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +38 -5
- package/dist/Outline/Outline.js +2 -2
- package/dist/Outline/parseOutlineFromMarkdown.d.ts +2 -0
- package/dist/Outline/parseOutlineFromMarkdown.d.ts.map +1 -1
- package/dist/Outline/parseOutlineFromMarkdown.js +5 -31
- 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/RadioList.d.ts.map +1 -1
- package/dist/RadioList/RadioList.js +12 -1
- package/dist/RadioList/RadioListItem.d.ts +2 -2
- package/dist/RadioList/RadioListItem.d.ts.map +1 -1
- package/dist/RadioList/RadioListItem.js +68 -38
- package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
- package/dist/Resizable/ResizeHandle.js +3 -3
- 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 +6 -1
- package/dist/SelectableCard/SelectableCard.js +1 -1
- package/dist/Selector/Selector.d.ts +26 -1
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +95 -17
- 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.js +1 -1
- package/dist/SideNav/SideNavItem.js +1 -1
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +3 -3
- 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/StatusDot/StatusDot.d.ts +43 -3
- package/dist/StatusDot/StatusDot.d.ts.map +1 -1
- package/dist/StatusDot/StatusDot.js +42 -5
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +9 -0
- package/dist/TabList/TabMenu.js +1 -1
- 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/groupedRows/useTableGroupedRows.d.ts.map +1 -1
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +1 -1
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +7 -2
- 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.js +2 -2
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +6 -1
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +6 -1
- package/dist/Thumbnail/Thumbnail.js +1 -1
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +6 -1
- 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/Token/Token.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.js +2 -2
- package/dist/TopNav/TopNavItem.js +2 -2
- package/dist/TopNav/TopNavMegaMenu.js +1 -1
- package/dist/TopNav/TopNavMegaMenuItem.js +1 -1
- package/dist/TopNav/TopNavMenu.js +2 -2
- package/dist/TreeList/TreeListItem.js +1 -1
- package/dist/astryx.css +85 -60
- 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/useResolvedRequired.d.ts +19 -0
- package/dist/hooks/useResolvedRequired.d.ts.map +1 -0
- package/dist/hooks/useResolvedRequired.js +40 -0
- 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/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/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/plainDate.d.ts +9 -2
- package/dist/utils/plainDate.d.ts.map +1 -1
- package/dist/utils/plainDate.js +16 -4
- package/locales/af-ZA.json +958 -0
- package/locales/ar-SA.json +998 -0
- package/locales/ca-ES.json +974 -0
- package/locales/cs-CZ.json +990 -0
- package/locales/da-DK.json +966 -0
- package/locales/de-DE.json +966 -0
- package/locales/el-GR.json +990 -0
- package/locales/en.json +8 -0
- package/locales/es-ES.json +978 -0
- package/locales/fi-FI.json +990 -0
- package/locales/fr-FR.json +928 -0
- package/locales/he-IL.json +990 -0
- package/locales/hu-HU.json +990 -0
- package/locales/it-IT.json +978 -0
- package/locales/ja-JP.json +998 -0
- package/locales/ko-KR.json +990 -0
- package/locales/nl-NL.json +954 -0
- package/locales/no-NO.json +978 -0
- package/locales/pl-PL.json +982 -0
- package/locales/pseudo.json +6 -0
- package/locales/pt-BR.json +982 -0
- package/locales/pt-PT.json +982 -0
- package/locales/ro-RO.json +982 -0
- package/locales/ru-RU.json +990 -0
- package/locales/sr-SP.json +990 -0
- package/locales/sv-SE.json +986 -0
- package/locales/tr-TR.json +990 -0
- package/locales/uk-UA.json +990 -0
- package/locales/vi-VN.json +986 -0
- package/locales/zh-CN.json +998 -0
- package/locales/zh-TW.json +998 -0
- package/package.json +3 -3
- package/src/AvatarGroup/AvatarGroupOverflow.tsx +1 -1
- package/src/Banner/Banner.doc.mjs +2 -0
- package/src/BottomSheet/BottomSheet.doc.mjs +36 -3
- package/src/BottomSheet/BottomSheet.test.tsx +177 -2
- package/src/BottomSheet/BottomSheet.tsx +16 -2
- package/src/BottomSheet/BottomSheetPanel.test.tsx +41 -0
- package/src/BottomSheet/BottomSheetPanel.tsx +95 -15
- package/src/BottomSheet/index.ts +5 -1
- package/src/BottomSheet/snapOffsets.test.ts +114 -47
- package/src/BottomSheet/snapOffsets.ts +119 -33
- package/src/BottomSheet/useSheetGestures.test.ts +113 -15
- package/src/BottomSheet/useSheetGestures.ts +196 -100
- package/src/Breadcrumbs/BreadcrumbItem.tsx +1 -1
- package/src/Button/Button.tsx +7 -7
- package/src/Calendar/Calendar.doc.mjs +16 -0
- package/src/Calendar/Calendar.test.tsx +137 -0
- package/src/Calendar/Calendar.tsx +80 -11
- package/src/Calendar/getStandaloneShortWeekdayNames.test.ts +54 -0
- package/src/Calendar/getStandaloneShortWeekdayNames.ts +38 -0
- package/src/Calendar/hooks/useCalendarConstraints.ts +54 -3
- package/src/Calendar/hooks/useCalendarDays.ts +13 -10
- package/src/Calendar/hooks/useCalendarNavigation.ts +6 -4
- package/src/Calendar/standaloneShortWeekdayNames.generated.ts +50 -0
- package/src/Calendar/styles.ts +3 -3
- 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 +7 -4
- package/src/Chat/ChatToolCalls.tsx +1 -1
- 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/CheckboxInput/CheckboxInput.tsx +6 -0
- package/src/Citation/Citation.tsx +3 -3
- package/src/ClickableCard/ClickableCard.tsx +2 -2
- package/src/CommandPalette/CommandPaletteItem.tsx +1 -1
- package/src/ComplexSelector/ComplexSelector.doc.mjs +10 -0
- package/src/ComplexSelector/ComplexSelector.tsx +8 -5
- package/src/DateInput/DateInput.test.tsx +17 -1
- package/src/DateInput/DateInput.tsx +13 -9
- package/src/DateRangeInput/DateRangeInput.doc.mjs +16 -0
- package/src/DateRangeInput/DateRangeInput.test.tsx +81 -1
- package/src/DateRangeInput/DateRangeInput.tsx +88 -8
- package/src/DateTimeInput/DateTimeInput.tsx +23 -8
- package/src/Dialog/Dialog.test.tsx +24 -0
- package/src/Dialog/Dialog.tsx +3 -0
- package/src/Field/Field.doc.mjs +3 -0
- package/src/Field/FieldLabel.tsx +20 -4
- package/src/Field/InputClearButton.test.tsx +134 -2
- package/src/Field/InputClearButton.tsx +42 -1
- package/src/Field/inputStyles.stylex.ts +16 -12
- package/src/FileInput/FileInput.tsx +5 -4
- package/src/FormLayout/FormLayout.doc.mjs +13 -0
- package/src/FormLayout/FormLayout.test.tsx +181 -4
- package/src/FormLayout/FormLayout.tsx +33 -2
- package/src/FormLayout/FormLayoutContext.ts +22 -7
- package/src/FormLayout/index.ts +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/Item/Item.doc.mjs +1 -0
- package/src/Item/Item.test.tsx +50 -0
- package/src/Item/Item.tsx +41 -2
- 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 +2 -1
- package/src/Link/Link.tsx +4 -4
- package/src/Markdown/Markdown.doc.mjs +3 -0
- package/src/Markdown/Markdown.test.tsx +78 -0
- package/src/Markdown/Markdown.tsx +41 -1
- package/src/Markdown/parser.ts +60 -2
- 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 +8 -5
- package/src/NavItem/navItemStyles.stylex.ts +2 -2
- package/src/NavMenu/NavHeadingMenuItem.tsx +1 -1
- package/src/NumberInput/NumberInput.doc.mjs +24 -0
- package/src/NumberInput/NumberInput.test.tsx +138 -0
- package/src/NumberInput/NumberInput.tsx +44 -6
- package/src/Outline/Outline.doc.mjs +2 -0
- package/src/Outline/Outline.tsx +1 -1
- package/src/Outline/parseOutlineFromMarkdown.ts +10 -40
- 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/RadioList.tsx +9 -1
- package/src/RadioList/RadioListItem.tsx +83 -51
- package/src/Resizable/ResizeHandle.test.tsx +22 -0
- package/src/Resizable/ResizeHandle.tsx +9 -3
- 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 +11 -2
- package/src/SelectableCard/SelectableCard.tsx +1 -1
- package/src/Selector/Selector.doc.mjs +16 -2
- package/src/Selector/Selector.test.tsx +525 -1
- package/src/Selector/Selector.tsx +166 -21
- 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 +2 -2
- package/src/SideNav/SideNavItem.tsx +1 -1
- package/src/Slider/Slider.tsx +11 -1
- 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/StatusDot/StatusDot.doc.mjs +13 -0
- package/src/StatusDot/StatusDot.test.tsx +115 -8
- package/src/StatusDot/StatusDot.tsx +74 -9
- package/src/Switch/Switch.tsx +6 -0
- package/src/TabList/TabMenu.tsx +1 -1
- package/src/Table/TableRow.tsx +4 -4
- package/src/Table/plugins/columnResize/useTableColumnResize.tsx +2 -1
- package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +2 -1
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +22 -4
- 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 +2 -2
- package/src/TextArea/TextArea.doc.mjs +1 -1
- package/src/TextArea/TextArea.tsx +3 -1
- package/src/TextInput/TextInput.tsx +3 -1
- package/src/Thumbnail/Thumbnail.tsx +1 -1
- package/src/TimeInput/TimeInput.tsx +3 -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/Token/Token.tsx +1 -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 +1 -1
- package/src/TopNav/TopNavItem.tsx +2 -2
- package/src/TopNav/TopNavMegaMenu.tsx +1 -1
- package/src/TopNav/TopNavMegaMenuItem.tsx +1 -1
- package/src/TopNav/TopNavMenu.tsx +2 -2
- package/src/TreeList/TreeListItem.tsx +1 -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/useResolvedRequired.ts +42 -0
- 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/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/utils/dateParser.test.ts +20 -0
- package/src/utils/dateParser.ts +14 -7
- package/src/utils/plainDate.test.ts +56 -0
- package/src/utils/plainDate.ts +17 -4
|
@@ -158,7 +158,7 @@ const itemStyles = stylex.create({
|
|
|
158
158
|
paddingBlock: spacingVars['--spacing-1'],
|
|
159
159
|
textDecoration: {
|
|
160
160
|
default: 'none',
|
|
161
|
-
':hover': {
|
|
161
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
162
162
|
'@media (hover: hover)': 'underline',
|
|
163
163
|
},
|
|
164
164
|
},
|
package/src/Button/Button.tsx
CHANGED
|
@@ -107,11 +107,11 @@ const styles = stylex.create({
|
|
|
107
107
|
},
|
|
108
108
|
},
|
|
109
109
|
ariaDisabled: {
|
|
110
|
+
// The variants' hover treatment already steps aside for
|
|
111
|
+
// `[aria-disabled]`; `:active` still matches a press on an aria-disabled
|
|
112
|
+
// button, so that one is suppressed here.
|
|
110
113
|
backgroundImage: {
|
|
111
114
|
default: 'none',
|
|
112
|
-
':hover': {
|
|
113
|
-
'@media (hover: hover)': 'none',
|
|
114
|
-
},
|
|
115
115
|
':active': 'none',
|
|
116
116
|
},
|
|
117
117
|
},
|
|
@@ -198,7 +198,7 @@ const variants = stylex.create({
|
|
|
198
198
|
color: colorVars['--color-on-accent'],
|
|
199
199
|
backgroundImage: {
|
|
200
200
|
default: null,
|
|
201
|
-
':hover': {
|
|
201
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
202
202
|
'@media (hover: hover)': `linear-gradient(${colorVars['--color-overlay-hover']}, ${colorVars['--color-overlay-hover']})`,
|
|
203
203
|
},
|
|
204
204
|
':active': `linear-gradient(${colorVars['--color-overlay-pressed']}, ${colorVars['--color-overlay-pressed']})`,
|
|
@@ -209,7 +209,7 @@ const variants = stylex.create({
|
|
|
209
209
|
color: colorVars['--color-text-primary'],
|
|
210
210
|
backgroundImage: {
|
|
211
211
|
default: null,
|
|
212
|
-
':hover': {
|
|
212
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
213
213
|
'@media (hover: hover)': `linear-gradient(${colorVars['--color-overlay-hover']}, ${colorVars['--color-overlay-hover']})`,
|
|
214
214
|
},
|
|
215
215
|
':active': `linear-gradient(${colorVars['--color-overlay-pressed']}, ${colorVars['--color-overlay-pressed']})`,
|
|
@@ -220,7 +220,7 @@ const variants = stylex.create({
|
|
|
220
220
|
color: colorVars['--color-text-primary'],
|
|
221
221
|
backgroundImage: {
|
|
222
222
|
default: null,
|
|
223
|
-
':hover': {
|
|
223
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
224
224
|
'@media (hover: hover)': `linear-gradient(${colorVars['--color-overlay-hover']}, ${colorVars['--color-overlay-hover']})`,
|
|
225
225
|
},
|
|
226
226
|
':active': `linear-gradient(${colorVars['--color-overlay-pressed']}, ${colorVars['--color-overlay-pressed']})`,
|
|
@@ -235,7 +235,7 @@ const variants = stylex.create({
|
|
|
235
235
|
outlineColor: {default: null, ':focus-visible': colorVars['--color-error']},
|
|
236
236
|
backgroundImage: {
|
|
237
237
|
default: null,
|
|
238
|
-
':hover': {
|
|
238
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
239
239
|
'@media (hover: hover)': `linear-gradient(${colorVars['--color-overlay-hover']}, ${colorVars['--color-overlay-hover']})`,
|
|
240
240
|
},
|
|
241
241
|
':active': `linear-gradient(${colorVars['--color-overlay-pressed']}, ${colorVars['--color-overlay-pressed']})`,
|
|
@@ -68,6 +68,18 @@ export const docs = {
|
|
|
68
68
|
type: 'Array<(date: Date) => boolean>',
|
|
69
69
|
description: 'Custom constraint functions.',
|
|
70
70
|
},
|
|
71
|
+
{
|
|
72
|
+
name: 'maxRangeSpan',
|
|
73
|
+
type: 'number',
|
|
74
|
+
description:
|
|
75
|
+
'Range mode: max days a range may span, both endpoints counted (7 = a 7-day window). Caps the window from the picked start; before a start is picked every day stays selectable.',
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'minRangeSpan',
|
|
79
|
+
type: 'number',
|
|
80
|
+
description:
|
|
81
|
+
'Range mode: min days a range must span, both endpoints counted (2 forbids a single-day range). Default 1.',
|
|
82
|
+
},
|
|
71
83
|
{
|
|
72
84
|
name: 'focusDate',
|
|
73
85
|
type: 'ISODateString',
|
|
@@ -142,6 +154,8 @@ export const docsZh = {
|
|
|
142
154
|
{name: 'min', type: 'ISODateString', description: '可选择的最早日期。'},
|
|
143
155
|
{name: 'max', type: 'ISODateString', description: '可选择的最晚日期。'},
|
|
144
156
|
{name: 'dateConstraints', type: 'Array<(date: Date) => boolean>', description: '自定义约束函数。'},
|
|
157
|
+
{name: 'maxRangeSpan', type: 'number', description: '范围模式:范围最多可跨越的天数,含首尾两端(7 = 7 天窗口)。选定起始日后限制窗口大小。'},
|
|
158
|
+
{name: 'minRangeSpan', type: 'number', description: '范围模式:范围最少需跨越的天数,含首尾两端(2 表示禁止单日范围)。默认为 1。'},
|
|
145
159
|
{name: 'focusDate', type: 'ISODateString', description: '受控可见月份。'},
|
|
146
160
|
{name: 'onFocusDateChange', type: '(focusDate: ISODateString) => void', description: '导航回调函数。'},
|
|
147
161
|
{name: 'handleRef', type: 'React.Ref<CalendarHandle>', description: '日历导航的命令式句柄,包括 navigateTo()。'},
|
|
@@ -205,6 +219,8 @@ export const docsDense = {
|
|
|
205
219
|
min: 'minimum selectable date',
|
|
206
220
|
max: 'maximum selectable date',
|
|
207
221
|
dateConstraints: 'custom constraint fns',
|
|
222
|
+
maxRangeSpan: 'range mode: max days a range may span, both ends counted (7 = 7-day window)',
|
|
223
|
+
minRangeSpan: 'range mode: min days a range must span, both ends counted (default 1)',
|
|
208
224
|
focusDate: 'controlled visible month',
|
|
209
225
|
onFocusDateChange: 'navigation callback',
|
|
210
226
|
handleRef: 'imperative navigation handle',
|
|
@@ -21,6 +21,8 @@ import {calendarStyles} from './styles';
|
|
|
21
21
|
import {defineTheme} from '../theme/defineTheme';
|
|
22
22
|
import {generateThemeCSS} from '../theme/generateThemeRules';
|
|
23
23
|
import {__resetLiveRegionsForTest} from '../hooks/useAnnounce';
|
|
24
|
+
import {InternationalizationProvider} from '../i18n/InternationalizationProvider';
|
|
25
|
+
import {standaloneShortWeekdayNamesByLocale} from './standaloneShortWeekdayNames.generated';
|
|
24
26
|
|
|
25
27
|
function generateThemeTestCSS(theme: Parameters<typeof generateThemeCSS>[0]) {
|
|
26
28
|
const {prose, component} = generateThemeCSS(theme);
|
|
@@ -120,6 +122,45 @@ describe('Calendar', () => {
|
|
|
120
122
|
expect(screen.getByText('Sa')).toBeInTheDocument();
|
|
121
123
|
});
|
|
122
124
|
|
|
125
|
+
it('uses the provider locale for stand-alone short day names', () => {
|
|
126
|
+
const localizedNames = standaloneShortWeekdayNamesByLocale.es;
|
|
127
|
+
const englishNames = standaloneShortWeekdayNamesByLocale.en;
|
|
128
|
+
expect(localizedNames).not.toEqual(englishNames);
|
|
129
|
+
|
|
130
|
+
const {rerender} = render(
|
|
131
|
+
<InternationalizationProvider locale="es-ES">
|
|
132
|
+
<Calendar />
|
|
133
|
+
</InternationalizationProvider>,
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
expect(
|
|
137
|
+
screen.getAllByRole('columnheader').map(header => header.textContent),
|
|
138
|
+
).toEqual(localizedNames);
|
|
139
|
+
|
|
140
|
+
rerender(
|
|
141
|
+
<InternationalizationProvider locale="en">
|
|
142
|
+
<Calendar />
|
|
143
|
+
</InternationalizationProvider>,
|
|
144
|
+
);
|
|
145
|
+
expect(
|
|
146
|
+
screen.getAllByRole('columnheader').map(header => header.textContent),
|
|
147
|
+
).toEqual(englishNames);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it('rotates localized day names by numeric weekday index', () => {
|
|
151
|
+
const localizedNames = standaloneShortWeekdayNamesByLocale.es;
|
|
152
|
+
|
|
153
|
+
render(
|
|
154
|
+
<InternationalizationProvider locale="es-ES">
|
|
155
|
+
<Calendar weekStartsOn={1} />
|
|
156
|
+
</InternationalizationProvider>,
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
expect(
|
|
160
|
+
screen.getAllByRole('columnheader').map(header => header.textContent),
|
|
161
|
+
).toEqual([...localizedNames.slice(1), localizedNames[0]]);
|
|
162
|
+
});
|
|
163
|
+
|
|
123
164
|
it('displays correct number of day cells', () => {
|
|
124
165
|
render(<Calendar />);
|
|
125
166
|
|
|
@@ -236,6 +277,102 @@ describe('Calendar', () => {
|
|
|
236
277
|
expect(sunday).toBeDisabled();
|
|
237
278
|
});
|
|
238
279
|
|
|
280
|
+
it('caps the end date to maxRangeSpan once a start is picked', async () => {
|
|
281
|
+
const user = userEvent.setup();
|
|
282
|
+
|
|
283
|
+
render(<Calendar mode="range" focusDate="2026-01-01" maxRangeSpan={7} />);
|
|
284
|
+
|
|
285
|
+
// Before a start is picked every day is selectable.
|
|
286
|
+
expect(getDayButton(20)).not.toBeDisabled();
|
|
287
|
+
|
|
288
|
+
// Pick Jan 10 as the start. A 7-day window spans Jan 4–16 (start ± 6).
|
|
289
|
+
await user.click(getDayButton(10));
|
|
290
|
+
|
|
291
|
+
expect(getDayButton(16)).not.toBeDisabled(); // 6 days after — the edge
|
|
292
|
+
expect(getDayButton(17)).toBeDisabled(); // 7 days after — beyond the cap
|
|
293
|
+
expect(getDayButton(4)).not.toBeDisabled(); // 6 days before — symmetric
|
|
294
|
+
expect(getDayButton(3)).toBeDisabled(); // 7 days before — beyond the cap
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
it('enforces minRangeSpan once a start is picked', async () => {
|
|
298
|
+
const user = userEvent.setup();
|
|
299
|
+
|
|
300
|
+
render(<Calendar mode="range" focusDate="2026-01-01" minRangeSpan={3} />);
|
|
301
|
+
|
|
302
|
+
// Pick Jan 10. A 3-day minimum forbids ends closer than 2 days away.
|
|
303
|
+
await user.click(getDayButton(10));
|
|
304
|
+
|
|
305
|
+
// The picked start itself stays enabled — it is the active selection
|
|
306
|
+
// anchor, not an unreachable end.
|
|
307
|
+
expect(getDayButton(10)).not.toBeDisabled();
|
|
308
|
+
expect(getDayButton(11)).toBeDisabled(); // 1 day apart — too short
|
|
309
|
+
expect(getDayButton(12)).not.toBeDisabled(); // 3-day span — allowed
|
|
310
|
+
expect(getDayButton(8)).not.toBeDisabled(); // 3-day span the other way
|
|
311
|
+
expect(getDayButton(9)).toBeDisabled(); // 2-day span — too short
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
it('clears the in-progress start when the anchor is clicked again', async () => {
|
|
315
|
+
const user = userEvent.setup();
|
|
316
|
+
const handleChange = vi.fn();
|
|
317
|
+
|
|
318
|
+
render(
|
|
319
|
+
<Calendar
|
|
320
|
+
mode="range"
|
|
321
|
+
focusDate="2026-01-01"
|
|
322
|
+
onChange={handleChange}
|
|
323
|
+
minRangeSpan={3}
|
|
324
|
+
/>,
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
// Pick Jan 10 as the start, then click it again.
|
|
328
|
+
await user.click(getDayButton(10));
|
|
329
|
+
await user.click(getDayButton(10));
|
|
330
|
+
|
|
331
|
+
// No zero-length range is committed…
|
|
332
|
+
expect(handleChange).not.toHaveBeenCalled();
|
|
333
|
+
|
|
334
|
+
// …and the start is cleared: the days that minRangeSpan disabled around
|
|
335
|
+
// the old anchor are selectable again, so a new start can be placed there.
|
|
336
|
+
expect(getDayButton(11)).not.toBeDisabled();
|
|
337
|
+
expect(getDayButton(9)).not.toBeDisabled();
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
it('does not apply range-span constraints in single mode', async () => {
|
|
341
|
+
const user = userEvent.setup();
|
|
342
|
+
|
|
343
|
+
render(<Calendar focusDate="2026-01-01" maxRangeSpan={7} />);
|
|
344
|
+
|
|
345
|
+
// A picked single date must not disable far-away days.
|
|
346
|
+
await user.click(getDayButton(10));
|
|
347
|
+
expect(getDayButton(25)).not.toBeDisabled();
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
it('keeps a controlled value that is wider than maxRangeSpan (selection-only)', () => {
|
|
351
|
+
// The span constraint governs which days are pickable, not validation of
|
|
352
|
+
// an already-set value — so a 15-day value under a 7-day cap stays
|
|
353
|
+
// rendered and is never silently rewritten.
|
|
354
|
+
render(
|
|
355
|
+
<Calendar
|
|
356
|
+
mode="range"
|
|
357
|
+
value={{start: '2026-01-05', end: '2026-01-20'}}
|
|
358
|
+
focusDate="2026-01-01"
|
|
359
|
+
maxRangeSpan={7}
|
|
360
|
+
/>,
|
|
361
|
+
);
|
|
362
|
+
|
|
363
|
+
// No selection is in progress (both endpoints are set), so no anchor →
|
|
364
|
+
// every day is pickable and both endpoints render selected.
|
|
365
|
+
expect(getDayButton(20)).not.toBeDisabled();
|
|
366
|
+
expect(getDayButton(5).closest('[role="gridcell"]')).toHaveAttribute(
|
|
367
|
+
'aria-selected',
|
|
368
|
+
'true',
|
|
369
|
+
);
|
|
370
|
+
expect(getDayButton(20).closest('[role="gridcell"]')).toHaveAttribute(
|
|
371
|
+
'aria-selected',
|
|
372
|
+
'true',
|
|
373
|
+
);
|
|
374
|
+
});
|
|
375
|
+
|
|
239
376
|
// ─── Multi-Month ─────────────────────────────────────────────
|
|
240
377
|
|
|
241
378
|
it('renders two months when numberOfMonths={2}', () => {
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
20
|
import {
|
|
21
|
+
use,
|
|
21
22
|
useState,
|
|
22
23
|
useMemo,
|
|
23
24
|
useCallback,
|
|
@@ -86,7 +87,7 @@ import type {
|
|
|
86
87
|
} from '../utils/dateTypes';
|
|
87
88
|
import {normalizeDayOfWeek} from '../utils/dateTypes';
|
|
88
89
|
import {themeProps} from '../utils/themeProps';
|
|
89
|
-
import {useTranslator} from '../i18n';
|
|
90
|
+
import {useTranslator, InternationalizationContext} from '../i18n';
|
|
90
91
|
|
|
91
92
|
/** Imperative handle for Calendar handleRef */
|
|
92
93
|
|
|
@@ -120,6 +121,25 @@ interface CalendarBaseProps extends Omit<
|
|
|
120
121
|
*/
|
|
121
122
|
dateConstraints?: ReadonlyArray<(date: Date) => boolean>;
|
|
122
123
|
|
|
124
|
+
/**
|
|
125
|
+
* Range mode only. Maximum number of days a selected range may span,
|
|
126
|
+
* counting both endpoints — `maxRangeSpan={7}` allows a 7-day window
|
|
127
|
+
* (start + 6 days). Once a start date is picked, days beyond this distance
|
|
128
|
+
* from it are disabled in either direction; before a start is picked every
|
|
129
|
+
* otherwise-valid day stays selectable. Use for rolling windows like "at
|
|
130
|
+
* most a week from the chosen day". For fixed calendar bounds use min/max.
|
|
131
|
+
*/
|
|
132
|
+
maxRangeSpan?: number;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Range mode only. Minimum number of days a selected range must span,
|
|
136
|
+
* counting both endpoints — `minRangeSpan={2}` forbids a single-day range.
|
|
137
|
+
* Once a start date is picked, days closer than this to it are disabled —
|
|
138
|
+
* except the start itself, which stays selectable as the active anchor.
|
|
139
|
+
* Defaults to 1 (a same-day start and end is allowed).
|
|
140
|
+
*/
|
|
141
|
+
minRangeSpan?: number;
|
|
142
|
+
|
|
123
143
|
/**
|
|
124
144
|
* Controlled focus date (which month is visible).
|
|
125
145
|
* If not provided, defaults to selected date or today.
|
|
@@ -201,6 +221,7 @@ export type CalendarProps = CalendarSingleProps | CalendarRangeProps;
|
|
|
201
221
|
*/
|
|
202
222
|
export function Calendar({ref, ...props}: CalendarProps) {
|
|
203
223
|
const t = useTranslator();
|
|
224
|
+
const {locale} = use(InternationalizationContext);
|
|
204
225
|
const {
|
|
205
226
|
handleRef,
|
|
206
227
|
mode = 'single',
|
|
@@ -211,6 +232,8 @@ export function Calendar({ref, ...props}: CalendarProps) {
|
|
|
211
232
|
min,
|
|
212
233
|
max,
|
|
213
234
|
dateConstraints,
|
|
235
|
+
maxRangeSpan,
|
|
236
|
+
minRangeSpan,
|
|
214
237
|
focusDate: focusDateProp,
|
|
215
238
|
onFocusDateChange,
|
|
216
239
|
hasOutsideDays = true,
|
|
@@ -306,12 +329,12 @@ export function Calendar({ref, ...props}: CalendarProps) {
|
|
|
306
329
|
// Format month header
|
|
307
330
|
const monthYearLabel = useMemo(() => {
|
|
308
331
|
if (numberOfMonths === 1) {
|
|
309
|
-
return plainDateFormat(visibleMonths[0], DATE_FORMAT_MONTH_YEAR);
|
|
332
|
+
return plainDateFormat(visibleMonths[0], DATE_FORMAT_MONTH_YEAR, locale);
|
|
310
333
|
}
|
|
311
334
|
return visibleMonths
|
|
312
|
-
.map(m => plainDateFormat(m, DATE_FORMAT_MONTH_YEAR))
|
|
335
|
+
.map(m => plainDateFormat(m, DATE_FORMAT_MONTH_YEAR, locale))
|
|
313
336
|
.join(' – ');
|
|
314
|
-
}, [visibleMonths, numberOfMonths]);
|
|
337
|
+
}, [visibleMonths, numberOfMonths, locale]);
|
|
315
338
|
|
|
316
339
|
// Announce the newly visible month to screen readers whenever it changes.
|
|
317
340
|
// The visible month label (`<span>`) carries no live semantics, so paging the
|
|
@@ -419,12 +442,29 @@ export function Calendar({ref, ...props}: CalendarProps) {
|
|
|
419
442
|
setRangeSelectionStart(iso);
|
|
420
443
|
announce(
|
|
421
444
|
t('@astryx.calendar.rangeStartAnnounce', {
|
|
422
|
-
date: plainDateFormat(date, DATE_FORMAT_WITH_WEEKDAY),
|
|
445
|
+
date: plainDateFormat(date, DATE_FORMAT_WITH_WEEKDAY, locale),
|
|
423
446
|
}),
|
|
424
447
|
);
|
|
425
448
|
} else {
|
|
426
449
|
// Second click - complete the range
|
|
427
450
|
const startPd = plainDateFromISO(rangeSelectionStart);
|
|
451
|
+
|
|
452
|
+
// Clicking the anchor again clears the in-progress start rather than
|
|
453
|
+
// committing a zero-length range. This is also the escape hatch when
|
|
454
|
+
// `minRangeSpan` disables the days around the anchor: without it the
|
|
455
|
+
// anchor would be the only clickable day left and the start could
|
|
456
|
+
// never be moved. `minRangeSpan` leaves the anchor itself enabled
|
|
457
|
+
// precisely so this toggle stays reachable.
|
|
458
|
+
if (plainDateIsEqual(date, startPd)) {
|
|
459
|
+
setRangeSelectionStart(null);
|
|
460
|
+
announce(
|
|
461
|
+
t('@astryx.calendar.rangeClearedAnnounce', {
|
|
462
|
+
date: plainDateFormat(date, DATE_FORMAT_WITH_WEEKDAY),
|
|
463
|
+
}),
|
|
464
|
+
);
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
|
|
428
468
|
let start: ISODateString;
|
|
429
469
|
let end: ISODateString;
|
|
430
470
|
|
|
@@ -448,17 +488,19 @@ export function Calendar({ref, ...props}: CalendarProps) {
|
|
|
448
488
|
start: plainDateFormat(
|
|
449
489
|
plainDateFromISO(start),
|
|
450
490
|
DATE_FORMAT_WITH_WEEKDAY,
|
|
491
|
+
locale,
|
|
451
492
|
),
|
|
452
493
|
end: plainDateFormat(
|
|
453
494
|
plainDateFromISO(end),
|
|
454
495
|
DATE_FORMAT_WITH_WEEKDAY,
|
|
496
|
+
locale,
|
|
455
497
|
),
|
|
456
498
|
}),
|
|
457
499
|
);
|
|
458
500
|
}
|
|
459
501
|
}
|
|
460
502
|
},
|
|
461
|
-
[mode, onChange, rangeSelectionStart, announce, t],
|
|
503
|
+
[mode, onChange, rangeSelectionStart, announce, t, locale],
|
|
462
504
|
);
|
|
463
505
|
|
|
464
506
|
return (
|
|
@@ -528,6 +570,8 @@ export function Calendar({ref, ...props}: CalendarProps) {
|
|
|
528
570
|
min={min}
|
|
529
571
|
max={max}
|
|
530
572
|
dateConstraints={dateConstraints}
|
|
573
|
+
maxRangeSpan={maxRangeSpan}
|
|
574
|
+
minRangeSpan={minRangeSpan}
|
|
531
575
|
hasOutsideDays={hasOutsideDays}
|
|
532
576
|
hasWeekNumbers={hasWeekNumbers}
|
|
533
577
|
hasVariableRowCount={hasVariableRowCount}
|
|
@@ -567,6 +611,8 @@ interface MonthGridProps {
|
|
|
567
611
|
min?: ISODateString;
|
|
568
612
|
max?: ISODateString;
|
|
569
613
|
dateConstraints?: ReadonlyArray<(date: Date) => boolean>;
|
|
614
|
+
maxRangeSpan?: number;
|
|
615
|
+
minRangeSpan?: number;
|
|
570
616
|
hasOutsideDays: boolean;
|
|
571
617
|
hasWeekNumbers: boolean;
|
|
572
618
|
hasVariableRowCount: boolean;
|
|
@@ -589,6 +635,8 @@ function MonthGrid({
|
|
|
589
635
|
min,
|
|
590
636
|
max,
|
|
591
637
|
dateConstraints,
|
|
638
|
+
maxRangeSpan,
|
|
639
|
+
minRangeSpan,
|
|
592
640
|
hasOutsideDays,
|
|
593
641
|
hasWeekNumbers,
|
|
594
642
|
hasVariableRowCount,
|
|
@@ -601,6 +649,7 @@ function MonthGrid({
|
|
|
601
649
|
pendingFocus,
|
|
602
650
|
onPendingFocusHandled,
|
|
603
651
|
}: MonthGridProps) {
|
|
652
|
+
const {locale} = use(InternationalizationContext);
|
|
604
653
|
const year = month.year;
|
|
605
654
|
|
|
606
655
|
// Use hooks for days generation and constraints
|
|
@@ -610,11 +659,30 @@ function MonthGrid({
|
|
|
610
659
|
weekStartsOn,
|
|
611
660
|
hasVariableRowCount,
|
|
612
661
|
});
|
|
662
|
+
const dayNameHeaders = useMemo(
|
|
663
|
+
() =>
|
|
664
|
+
dayNames.map((name, offset) => ({
|
|
665
|
+
dayOfWeek: ((weekStartsOn + offset) % 7) as DayOfWeek,
|
|
666
|
+
name,
|
|
667
|
+
})),
|
|
668
|
+
[dayNames, weekStartsOn],
|
|
669
|
+
);
|
|
670
|
+
|
|
671
|
+
const rangeAnchor = useMemo(
|
|
672
|
+
() =>
|
|
673
|
+
mode === 'range' && rangeSelectionStart
|
|
674
|
+
? plainDateFromISO(rangeSelectionStart)
|
|
675
|
+
: null,
|
|
676
|
+
[mode, rangeSelectionStart],
|
|
677
|
+
);
|
|
613
678
|
|
|
614
679
|
const {isDateDisabled} = useCalendarConstraints({
|
|
615
680
|
min,
|
|
616
681
|
max,
|
|
617
682
|
dateConstraints,
|
|
683
|
+
maxRangeSpan,
|
|
684
|
+
minRangeSpan,
|
|
685
|
+
rangeAnchor,
|
|
618
686
|
});
|
|
619
687
|
|
|
620
688
|
// Parse selected date for roving tabindex priority
|
|
@@ -803,8 +871,8 @@ function MonthGrid({
|
|
|
803
871
|
|
|
804
872
|
// Month label for announcements
|
|
805
873
|
const monthLabel = useMemo(() => {
|
|
806
|
-
return plainDateFormat(month, DATE_FORMAT_MONTH_YEAR);
|
|
807
|
-
}, [month]);
|
|
874
|
+
return plainDateFormat(month, DATE_FORMAT_MONTH_YEAR, locale);
|
|
875
|
+
}, [month, locale]);
|
|
808
876
|
|
|
809
877
|
return (
|
|
810
878
|
<div {...stylex.props(monthGridStyles.monthGrid)}>
|
|
@@ -833,9 +901,9 @@ function MonthGrid({
|
|
|
833
901
|
)}
|
|
834
902
|
/>
|
|
835
903
|
)}
|
|
836
|
-
{
|
|
904
|
+
{dayNameHeaders.map(({dayOfWeek, name}) => (
|
|
837
905
|
<div
|
|
838
|
-
key={
|
|
906
|
+
key={dayOfWeek}
|
|
839
907
|
role="columnheader"
|
|
840
908
|
{...stylex.props(monthGridStyles.dayName)}>
|
|
841
909
|
{name}
|
|
@@ -962,6 +1030,7 @@ function DayCell({
|
|
|
962
1030
|
onDayHover,
|
|
963
1031
|
}: DayCellProps) {
|
|
964
1032
|
const t = useTranslator();
|
|
1033
|
+
const {locale} = use(InternationalizationContext);
|
|
965
1034
|
const {date, isOutside, dayNumber} = day;
|
|
966
1035
|
|
|
967
1036
|
if (isOutside && !hasOutsideDays) {
|
|
@@ -1007,7 +1076,7 @@ function DayCell({
|
|
|
1007
1076
|
// params rather than string concatenation. A mid-flight first pick (where
|
|
1008
1077
|
// rangeStart === rangeEnd) reads as "range start" only; a completed one-day
|
|
1009
1078
|
// range reads as both start and end.
|
|
1010
|
-
const dateLabel = plainDateFormat(date, DATE_FORMAT_WITH_WEEKDAY);
|
|
1079
|
+
const dateLabel = plainDateFormat(date, DATE_FORMAT_WITH_WEEKDAY, locale);
|
|
1011
1080
|
const dayLabel = state.isSelected
|
|
1012
1081
|
? t('@astryx.calendar.daySelected', {date: dateLabel})
|
|
1013
1082
|
: state.isRangeStart && state.isRangeEnd
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file getStandaloneShortWeekdayNames.test.ts
|
|
5
|
+
* @input Private Calendar weekday locale resolver and generated CLDR data
|
|
6
|
+
* @output Regression coverage for exact, language, extension, and safe fallback
|
|
7
|
+
* @position Tests for getStandaloneShortWeekdayNames.ts
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import {describe, expect, it} from 'vitest';
|
|
11
|
+
import {getStandaloneShortWeekdayNames} from './getStandaloneShortWeekdayNames';
|
|
12
|
+
import {standaloneShortWeekdayNamesByLocale} from './standaloneShortWeekdayNames.generated';
|
|
13
|
+
|
|
14
|
+
describe('getStandaloneShortWeekdayNames', () => {
|
|
15
|
+
it('preserves the default English weekday names', () => {
|
|
16
|
+
expect(getStandaloneShortWeekdayNames('en')).toEqual([
|
|
17
|
+
'Su',
|
|
18
|
+
'Mo',
|
|
19
|
+
'Tu',
|
|
20
|
+
'We',
|
|
21
|
+
'Th',
|
|
22
|
+
'Fr',
|
|
23
|
+
'Sa',
|
|
24
|
+
]);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('returns an exact generated locale entry', () => {
|
|
28
|
+
expect(getStandaloneShortWeekdayNames('ar-SA')).toBe(
|
|
29
|
+
standaloneShortWeekdayNamesByLocale['ar-SA'],
|
|
30
|
+
);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('ignores Unicode extensions when resolving an exact locale', () => {
|
|
34
|
+
const expected = standaloneShortWeekdayNamesByLocale['zh-TW'];
|
|
35
|
+
|
|
36
|
+
expect(getStandaloneShortWeekdayNames('zh-TW')).toBe(expected);
|
|
37
|
+
expect(getStandaloneShortWeekdayNames('zh-TW-u-ca-chinese')).toBe(expected);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('falls back from a regional locale to its base language', () => {
|
|
41
|
+
expect(getStandaloneShortWeekdayNames('es-ES')).toBe(
|
|
42
|
+
standaloneShortWeekdayNamesByLocale.es,
|
|
43
|
+
);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('safely falls back to English for malformed and unsupported locales', () => {
|
|
47
|
+
expect(getStandaloneShortWeekdayNames('not_a_locale')).toBe(
|
|
48
|
+
standaloneShortWeekdayNamesByLocale.en,
|
|
49
|
+
);
|
|
50
|
+
expect(getStandaloneShortWeekdayNames('xx-ZZ')).toBe(
|
|
51
|
+
standaloneShortWeekdayNamesByLocale.en,
|
|
52
|
+
);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file getStandaloneShortWeekdayNames.ts
|
|
5
|
+
* @input Generated CLDR stand-alone-short weekday table
|
|
6
|
+
* @output Private locale resolver for Calendar weekday headers
|
|
7
|
+
* @position Calendar-internal pure utility; not exported from the package
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
standaloneShortWeekdayNamesByLocale,
|
|
12
|
+
type StandaloneShortWeekdayNames,
|
|
13
|
+
} from './standaloneShortWeekdayNames.generated';
|
|
14
|
+
|
|
15
|
+
const weekdayNamesByLocale: Readonly<
|
|
16
|
+
Record<string, StandaloneShortWeekdayNames>
|
|
17
|
+
> = standaloneShortWeekdayNamesByLocale;
|
|
18
|
+
const englishWeekdayNames = weekdayNamesByLocale.en;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Resolve generated weekday reference data as exact locale -> language -> English.
|
|
22
|
+
* Unicode extensions are ignored through Intl.Locale.baseName. Invalid tags and
|
|
23
|
+
* valid but unsupported languages safely use English.
|
|
24
|
+
*/
|
|
25
|
+
export function getStandaloneShortWeekdayNames(
|
|
26
|
+
locale: string,
|
|
27
|
+
): StandaloneShortWeekdayNames {
|
|
28
|
+
try {
|
|
29
|
+
const parsed = new Intl.Locale(locale);
|
|
30
|
+
return (
|
|
31
|
+
weekdayNamesByLocale[parsed.baseName] ??
|
|
32
|
+
weekdayNamesByLocale[parsed.language] ??
|
|
33
|
+
englishWeekdayNames
|
|
34
|
+
);
|
|
35
|
+
} catch {
|
|
36
|
+
return englishWeekdayNames;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
plainDateToDate,
|
|
21
21
|
plainDateIsBefore,
|
|
22
22
|
plainDateIsAfter,
|
|
23
|
+
plainDateDiffDays,
|
|
23
24
|
} from '../../utils/plainDate';
|
|
24
25
|
|
|
25
26
|
/**
|
|
@@ -35,6 +36,25 @@ export interface UseCalendarConstraintsOptions {
|
|
|
35
36
|
* Date is disabled if ANY function returns false.
|
|
36
37
|
*/
|
|
37
38
|
dateConstraints?: ReadonlyArray<(date: Date) => boolean>;
|
|
39
|
+
/**
|
|
40
|
+
* Maximum number of days a range may span, counting both endpoints
|
|
41
|
+
* (a value of 7 allows a 7-day window). In range mode, once a start is
|
|
42
|
+
* picked, dates further than this from it are disabled. No effect until a
|
|
43
|
+
* range anchor exists.
|
|
44
|
+
*/
|
|
45
|
+
maxRangeSpan?: number;
|
|
46
|
+
/**
|
|
47
|
+
* Minimum number of days a range must span, counting both endpoints
|
|
48
|
+
* (a value of 2 forbids a single-day range). In range mode, once a start
|
|
49
|
+
* is picked, dates closer than this to it are disabled.
|
|
50
|
+
*/
|
|
51
|
+
minRangeSpan?: number;
|
|
52
|
+
/**
|
|
53
|
+
* The in-progress range start (first click, awaiting the second). Span
|
|
54
|
+
* constraints are measured from this date. Null when no selection is
|
|
55
|
+
* underway.
|
|
56
|
+
*/
|
|
57
|
+
rangeAnchor?: PlainDate | null;
|
|
38
58
|
}
|
|
39
59
|
|
|
40
60
|
/**
|
|
@@ -53,13 +73,15 @@ export interface UseCalendarConstraintsReturn {
|
|
|
53
73
|
* Hook for managing calendar date validation constraints.
|
|
54
74
|
*
|
|
55
75
|
* Provides a function to check if a date is disabled based on
|
|
56
|
-
* min/max bounds and custom constraint functions.
|
|
76
|
+
* min/max bounds, range-span bounds, and custom constraint functions.
|
|
57
77
|
*
|
|
58
78
|
* @example
|
|
59
79
|
* ```
|
|
60
80
|
* const {isDateDisabled} = useCalendarConstraints({
|
|
61
81
|
* min: '2026-01-01',
|
|
62
82
|
* max: '2026-12-31',
|
|
83
|
+
* maxRangeSpan: 7, // once a start is picked, cap the window at 7 days
|
|
84
|
+
* rangeAnchor, // the in-progress start (null before the first click)
|
|
63
85
|
* dateConstraints: [
|
|
64
86
|
* (date) => date.getDay() !== 0, // No Sundays (receives native Date)
|
|
65
87
|
* ],
|
|
@@ -74,7 +96,8 @@ export interface UseCalendarConstraintsReturn {
|
|
|
74
96
|
export function useCalendarConstraints(
|
|
75
97
|
options: UseCalendarConstraintsOptions,
|
|
76
98
|
): UseCalendarConstraintsReturn {
|
|
77
|
-
const {min, max, dateConstraints} =
|
|
99
|
+
const {min, max, dateConstraints, maxRangeSpan, minRangeSpan, rangeAnchor} =
|
|
100
|
+
options;
|
|
78
101
|
|
|
79
102
|
// Parse min/max dates
|
|
80
103
|
const minDate = useMemo(() => (min ? plainDateFromISO(min) : null), [min]);
|
|
@@ -93,6 +116,27 @@ export function useCalendarConstraints(
|
|
|
93
116
|
return true;
|
|
94
117
|
}
|
|
95
118
|
|
|
119
|
+
// Range-span bounds, measured from the in-progress start. Spans count
|
|
120
|
+
// both endpoints (a span of 7 spans a 7-day window), so the reachable
|
|
121
|
+
// distance from the anchor is `span - 1` days in either direction. Only
|
|
122
|
+
// active once a start is picked — before that, every day stays pickable.
|
|
123
|
+
if (rangeAnchor) {
|
|
124
|
+
const distance = Math.abs(plainDateDiffDays(rangeAnchor, date));
|
|
125
|
+
if (maxRangeSpan != null && distance > maxRangeSpan - 1) {
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
// The anchor itself (distance 0) is never disabled by minRangeSpan —
|
|
129
|
+
// it is the picked start, and disabling it would render the active
|
|
130
|
+
// selection start as aria-disabled to keyboard and screen-reader users.
|
|
131
|
+
if (
|
|
132
|
+
minRangeSpan != null &&
|
|
133
|
+
distance > 0 &&
|
|
134
|
+
distance < minRangeSpan - 1
|
|
135
|
+
) {
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
96
140
|
// Check custom constraints (convert to Date for public API compatibility)
|
|
97
141
|
if (dateConstraints) {
|
|
98
142
|
for (const constraint of dateConstraints) {
|
|
@@ -104,7 +148,14 @@ export function useCalendarConstraints(
|
|
|
104
148
|
|
|
105
149
|
return false;
|
|
106
150
|
},
|
|
107
|
-
[
|
|
151
|
+
[
|
|
152
|
+
minDate,
|
|
153
|
+
maxDate,
|
|
154
|
+
dateConstraints,
|
|
155
|
+
maxRangeSpan,
|
|
156
|
+
minRangeSpan,
|
|
157
|
+
rangeAnchor,
|
|
158
|
+
],
|
|
108
159
|
);
|
|
109
160
|
|
|
110
161
|
return {
|