@astryxdesign/core 0.7.5 → 0.7.6-canary.0ef60dd
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AlertDialog/AlertDialog.d.ts +1 -1
- package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
- package/dist/AlertDialog/AlertDialog.js +5 -5
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +12 -3
- package/dist/Badge/Badge.d.ts.map +1 -1
- package/dist/Badge/Badge.js +7 -1
- package/dist/BottomSheet/BottomSheet.js +1 -1
- package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetPanel.js +2 -1
- package/dist/BottomSheet/useSheetGestures.d.ts +12 -0
- package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
- package/dist/BottomSheet/useSheetGestures.js +30 -3
- package/dist/Button/Button.js +4 -4
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +6 -5
- package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
- package/dist/ClickableCard/ClickableCard.js +37 -4
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +12 -4
- package/dist/DateInput/MonthScroller.d.ts.map +1 -1
- package/dist/DateInput/MonthScroller.js +101 -15
- package/dist/DateInput/TouchDateField.d.ts.map +1 -1
- package/dist/DateInput/TouchDateField.js +8 -3
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +1 -1
- package/dist/DateTimeInput/DateTimeInput.d.ts +5 -2
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +23 -12
- package/dist/DateTimeInput/NativeTimeSegment.d.ts.map +1 -1
- package/dist/DateTimeInput/NativeTimeSegment.js +5 -4
- package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
- package/dist/DateTimeInput/TouchDateTimeField.js +4 -3
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +34 -9
- package/dist/Dialog/DialogHeader.d.ts.map +1 -1
- package/dist/Dialog/DialogHeader.js +5 -4
- package/dist/Divider/Divider.d.ts.map +1 -1
- package/dist/Divider/Divider.js +2 -1
- package/dist/Drawer/Drawer.d.ts +1 -0
- package/dist/Drawer/Drawer.d.ts.map +1 -1
- package/dist/Drawer/Drawer.js +7 -2
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +7 -3
- package/dist/DropdownMenu/MenuBottomSheetActionList.d.ts.map +1 -1
- package/dist/DropdownMenu/MenuBottomSheetActionList.js +6 -5
- package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts +20 -2
- package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts.map +1 -1
- package/dist/DropdownMenu/lazyMenuBottomSheet.js +31 -3
- package/dist/DropdownMenu/renderDropdownItems.d.ts.map +1 -1
- package/dist/DropdownMenu/renderDropdownItems.js +21 -16
- package/dist/EmptyState/EmptyState.d.ts.map +1 -1
- package/dist/EmptyState/EmptyState.js +2 -1
- package/dist/Field/FieldLabel.d.ts +1 -1
- package/dist/Field/FieldLabel.d.ts.map +1 -1
- package/dist/Field/FieldLabel.js +4 -4
- package/dist/Field/InputClearButton.js +3 -3
- package/dist/Field/PanelSearchInput.js +2 -2
- package/dist/FieldStatus/FieldStatus.js +2 -2
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +7 -1
- package/dist/Heading/Heading.js +1 -1
- package/dist/Icon/Icon.js +1 -1
- package/dist/Indicator/CheckIndicator.d.ts.map +1 -1
- package/dist/Indicator/CheckIndicator.js +2 -1
- package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -1
- package/dist/Indicator/CheckboxIndicator.js +3 -1
- package/dist/Indicator/RadioIndicator.d.ts.map +1 -1
- package/dist/Indicator/RadioIndicator.js +3 -1
- package/dist/Item/Item.d.ts.map +1 -1
- package/dist/Item/Item.js +2 -1
- package/dist/Item/ItemSwipeLayer.js +1 -1
- package/dist/Layer/popoverOperations.d.ts +27 -0
- package/dist/Layer/popoverOperations.d.ts.map +1 -0
- package/dist/Layer/popoverOperations.js +159 -0
- package/dist/Layer/useLayer.d.ts +1 -1
- package/dist/Layer/useLayer.d.ts.map +1 -1
- package/dist/Layer/useLayer.js +93 -59
- package/dist/Layout/Layout.js +1 -1
- package/dist/Layout/LayoutContent.js +1 -1
- package/dist/Layout/LayoutFooter.js +1 -1
- package/dist/Layout/LayoutHeader.js +1 -1
- package/dist/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/Lightbox/Lightbox.js +5 -0
- package/dist/Lightbox/LightboxViewport.a11y.browser.spec.js +5 -4
- package/dist/List/List.js +1 -1
- package/dist/List/ListItem.js +3 -3
- package/dist/MobileNav/MobileNav.d.ts.map +1 -1
- package/dist/MobileNav/MobileNav.js +7 -2
- package/dist/MultiSelector/CreateRow.a11y.chromium.spec.js +7 -6
- package/dist/MultiSelector/MultiSelector.d.ts +1 -1
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +26 -10
- package/dist/NumberInput/NumberInput.d.ts +3 -1
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +3 -3
- package/dist/NumberInput/numberParser.d.ts +3 -0
- package/dist/NumberInput/numberParser.d.ts.map +1 -1
- package/dist/NumberInput/numberParser.js +7 -44
- package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
- package/dist/ProgressBar/ProgressBar.js +16 -12
- package/dist/Resizable/useResizable.d.ts.map +1 -1
- package/dist/Resizable/useResizable.js +28 -2
- package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.js +4 -1
- package/dist/Selector/useSelectorPresentation.d.ts +8 -1
- package/dist/Selector/useSelectorPresentation.d.ts.map +1 -1
- package/dist/Selector/useSelectorPresentation.js +20 -4
- package/dist/Skeleton/Skeleton.d.ts.map +1 -1
- package/dist/Skeleton/Skeleton.js +1 -1
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +10 -2
- package/dist/Spinner/Spinner.d.ts.map +1 -1
- package/dist/Spinner/Spinner.js +3 -3
- package/dist/Stack/Stack.js +1 -1
- package/dist/Stack/StackItem.js +1 -1
- package/dist/TabList/TabList.d.ts.map +1 -1
- package/dist/TabList/TabList.js +16 -1
- package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
- package/dist/Table/plugins/columnResize/useTableColumnResize.js +9 -1
- package/dist/Text/Text.js +1 -1
- package/dist/Text/useTruncation.d.ts.map +1 -1
- package/dist/Text/useTruncation.js +23 -5
- package/dist/TextArea/TextArea.d.ts +1 -1
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +13 -2
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +3 -3
- package/dist/TimeInput/TimeInput.d.ts +6 -2
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +21 -14
- package/dist/TimeInput/TouchTimeField.d.ts.map +1 -1
- package/dist/TimeInput/TouchTimeField.js +5 -4
- package/dist/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +2 -2
- package/dist/Timestamp/TimestampHoverCard.js +4 -4
- package/dist/Toast/Toast.d.ts.map +1 -1
- package/dist/Toast/Toast.js +60 -20
- package/dist/Toast/ToastViewport.d.ts.map +1 -1
- package/dist/Toast/ToastViewport.js +82 -51
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +13 -2
- package/dist/Tokenizer/TokenizerBottomSheet.js +3 -3
- package/dist/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/Toolbar/Toolbar.js +2 -1
- package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMegaMenu.js +3 -0
- package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMenu.js +1 -0
- package/dist/Typeahead/Typeahead.d.ts +1 -1
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +9 -1
- package/dist/astryx.css +20 -4
- package/dist/gestures/GestureArena.d.ts +6 -0
- package/dist/gestures/GestureArena.d.ts.map +1 -1
- package/dist/gestures/GestureArena.js +39 -0
- package/dist/gestures/GestureHost.d.ts +352 -0
- package/dist/gestures/GestureHost.d.ts.map +1 -0
- package/dist/gestures/GestureHost.js +1773 -0
- package/dist/gestures/GestureRecognizer.d.ts +10 -0
- package/dist/gestures/GestureRecognizer.d.ts.map +1 -1
- package/dist/gestures/GestureRecognizer.js +16 -0
- package/dist/gestures/LongPressGestureRecognizer.d.ts +1 -0
- package/dist/gestures/LongPressGestureRecognizer.d.ts.map +1 -1
- package/dist/gestures/LongPressGestureRecognizer.js +3 -0
- package/dist/gestures/PanGestureRecognizer.d.ts +1 -0
- package/dist/gestures/PanGestureRecognizer.d.ts.map +1 -1
- package/dist/gestures/PanGestureRecognizer.js +3 -0
- package/dist/gestures/PinchGestureRecognizer.d.ts +31 -0
- package/dist/gestures/PinchGestureRecognizer.d.ts.map +1 -0
- package/dist/gestures/PinchGestureRecognizer.js +128 -0
- package/dist/gestures/ScreenEdgePanGestureRecognizer.d.ts +71 -0
- package/dist/gestures/ScreenEdgePanGestureRecognizer.d.ts.map +1 -0
- package/dist/gestures/ScreenEdgePanGestureRecognizer.js +223 -0
- package/dist/gestures/SwipeGestureRecognizer.d.ts +37 -0
- package/dist/gestures/SwipeGestureRecognizer.d.ts.map +1 -0
- package/dist/gestures/SwipeGestureRecognizer.js +148 -0
- package/dist/gestures/TapGestureRecognizer.d.ts +1 -0
- package/dist/gestures/TapGestureRecognizer.d.ts.map +1 -1
- package/dist/gestures/TapGestureRecognizer.js +3 -0
- package/dist/gestures/VelocityTracker.d.ts +6 -2
- package/dist/gestures/VelocityTracker.d.ts.map +1 -1
- package/dist/gestures/VelocityTracker.js +7 -3
- package/dist/gestures/haptics.d.ts +65 -0
- package/dist/gestures/haptics.d.ts.map +1 -0
- package/dist/gestures/haptics.js +182 -0
- package/dist/gestures/nativeScroll.d.ts +42 -0
- package/dist/gestures/nativeScroll.d.ts.map +1 -0
- package/dist/gestures/nativeScroll.js +228 -0
- package/dist/gestures/touchAction.d.ts +60 -0
- package/dist/gestures/touchAction.d.ts.map +1 -0
- package/dist/gestures/touchAction.js +157 -0
- package/dist/gestures/touchActionRule.d.ts +34 -0
- package/dist/gestures/touchActionRule.d.ts.map +1 -0
- package/dist/gestures/touchActionRule.js +140 -0
- package/dist/gestures/types.d.ts +18 -7
- package/dist/gestures/types.d.ts.map +1 -1
- package/dist/gestures/types.js +22 -2
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/modalAnnounce.d.ts.map +1 -1
- package/dist/hooks/modalAnnounce.js +107 -61
- package/dist/hooks/useAdaptivePresentation.d.ts.map +1 -1
- package/dist/hooks/useAdaptivePresentation.js +4 -1
- package/dist/hooks/useAnnounce.d.ts +101 -42
- package/dist/hooks/useAnnounce.d.ts.map +1 -1
- package/dist/hooks/useAnnounce.js +161 -75
- package/dist/hooks/useAnnounceRenderedText.d.ts +11 -3
- package/dist/hooks/useAnnounceRenderedText.d.ts.map +1 -1
- package/dist/hooks/useAnnounceRenderedText.js +5 -3
- package/dist/hooks/useBusyAnnouncement.d.ts.map +1 -1
- package/dist/hooks/useBusyAnnouncement.js +6 -12
- package/dist/hooks/useMenuHover.d.ts.map +1 -1
- package/dist/hooks/useMenuHover.js +12 -1
- package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/en.generated.js +5 -0
- package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/pseudo.generated.js +5 -0
- package/dist/motion/animator.d.ts +7 -1
- package/dist/motion/animator.d.ts.map +1 -1
- package/dist/motion/animator.js +119 -27
- package/dist/theme/defineTheme.d.ts +19 -5
- package/dist/theme/defineTheme.d.ts.map +1 -1
- package/dist/theme/defineTheme.js +64 -4
- package/dist/theme/domainTokens/domainTokenDefaults.d.ts +3 -0
- package/dist/theme/domainTokens/domainTokenDefaults.d.ts.map +1 -0
- package/dist/theme/domainTokens/domainTokenDefaults.js +19 -0
- package/dist/theme/domainTokens/index.d.ts +5 -4
- package/dist/theme/domainTokens/index.d.ts.map +1 -1
- package/dist/theme/domainTokens/index.js +5 -9
- package/dist/theme/index.d.ts +1 -0
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/motionKnobs.d.ts +56 -0
- package/dist/theme/motionKnobs.d.ts.map +1 -0
- package/dist/theme/motionKnobs.js +48 -0
- package/dist/theme/resolveThemeValues.d.ts +11 -4
- package/dist/theme/resolveThemeValues.d.ts.map +1 -1
- package/dist/theme/resolveThemeValues.js +40 -4
- package/dist/theme/themeAdaptations.d.ts +7 -3
- package/dist/theme/themeAdaptations.d.ts.map +1 -1
- package/dist/theme/themeAdaptations.js +36 -7
- package/dist/theme/themeMotion.d.ts +96 -0
- package/dist/theme/themeMotion.d.ts.map +1 -0
- package/dist/theme/themeMotion.js +177 -0
- package/dist/theme/tokenReferences.d.ts +31 -0
- package/dist/theme/tokenReferences.d.ts.map +1 -0
- package/dist/theme/tokenReferences.js +132 -0
- package/dist/theme/tokens.d.ts +1 -0
- package/dist/theme/tokens.d.ts.map +1 -1
- package/dist/theme/tokens.js +9 -129
- package/dist/theme/tokens.stylex.d.ts +12 -0
- package/dist/theme/tokens.stylex.d.ts.map +1 -1
- package/dist/theme/tokens.stylex.js +12 -0
- package/dist/utils/focusReturn.d.ts +17 -1
- package/dist/utils/focusReturn.d.ts.map +1 -1
- package/dist/utils/focusReturn.js +11 -4
- package/dist/utils/getNodeText.d.ts +8 -0
- package/dist/utils/getNodeText.d.ts.map +1 -0
- package/dist/utils/getNodeText.js +37 -0
- package/dist/utils/interactionModality.d.ts +11 -2
- package/dist/utils/interactionModality.d.ts.map +1 -1
- package/dist/utils/interactionModality.js +58 -5
- package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
- package/dist/utils/interactionOverlay.stylex.js +17 -8
- package/dist/utils/plainDate.d.ts +2 -0
- package/dist/utils/plainDate.d.ts.map +1 -1
- package/dist/utils/plainDate.js +46 -3
- package/dist/utils/presentation.d.ts +50 -0
- package/dist/utils/presentation.d.ts.map +1 -0
- package/dist/utils/presentation.js +125 -0
- package/dist/utils/pressFeedback.d.ts.map +1 -1
- package/dist/utils/pressFeedback.js +20 -1
- package/dist/utils/primaryClick.d.ts +11 -0
- package/dist/utils/primaryClick.d.ts.map +1 -0
- package/dist/utils/primaryClick.js +25 -0
- package/dist/utils/timeFormat.d.ts +47 -0
- package/dist/utils/timeFormat.d.ts.map +1 -0
- package/dist/utils/timeFormat.js +240 -0
- package/dist/utils/touchPresentation.d.ts.map +1 -1
- package/dist/utils/touchPresentation.js +5 -3
- package/dist/utils/touchPresentation.stylex.d.ts +15 -0
- package/dist/utils/touchPresentation.stylex.d.ts.map +1 -0
- package/dist/utils/touchPresentation.stylex.js +33 -0
- package/dist/utils/unicodeDigits.d.ts +20 -0
- package/dist/utils/unicodeDigits.d.ts.map +1 -0
- package/dist/utils/unicodeDigits.js +70 -0
- package/locales/en.json +23 -3
- package/locales/pseudo.json +15 -0
- package/package.json +5 -4
- package/src/AlertDialog/AlertDialog.tsx +6 -5
- package/src/AlertDialog/__tests__/AlertDialog.a11y.chromium.spec.ts +18 -6
- package/src/Avatar/Avatar.spec.md +22 -22
- package/src/Avatar/Avatar.tsx +18 -1
- package/src/Avatar/__tests__/AvatarForcedColors.a11y.chromium.spec.ts +126 -0
- package/src/Badge/Badge.doc.mjs +1 -1
- package/src/Badge/Badge.tsx +19 -2
- package/src/Badge/__tests__/BadgeLargerText.a11y.chromium.spec.ts +260 -0
- package/src/BottomSheet/BottomSheet.test.tsx +46 -0
- package/src/BottomSheet/BottomSheet.tsx +1 -1
- package/src/BottomSheet/BottomSheetPanel.tsx +2 -1
- package/src/BottomSheet/useSheetGestures.test.ts +52 -0
- package/src/BottomSheet/useSheetGestures.ts +37 -6
- package/src/Breadcrumbs/__tests__/Breadcrumbs.a11y.chromium.spec.ts +18 -6
- package/src/Button/Button.tsx +4 -4
- package/src/Calendar/Calendar.spec.md +87 -48
- package/src/Calendar/__tests__/Calendar.a11y.chromium.spec.ts +21 -7
- package/src/Carousel/__tests__/Carousel.a11y.chromium.spec.ts +21 -7
- package/src/CheckboxInput/CheckboxInput.tsx +6 -5
- package/src/ClickableCard/ClickableCard.test.tsx +96 -0
- package/src/ClickableCard/ClickableCard.tsx +48 -4
- package/src/Collapsible/Collapsible.spec.md +2 -0
- package/src/Collapsible/CollapsibleGroup.spec.md +57 -29
- package/src/Collapsible/__tests__/Collapsible.a11y.chromium.spec.ts +18 -7
- package/src/Collapsible/__tests__/CollapsibleGroupAccordion.a11y.chromium.spec.ts +18 -6
- package/src/ComplexSelector/ComplexSelector.test.tsx +37 -0
- package/src/ContextMenu/ContextMenu.test.tsx +35 -0
- package/src/DateInput/DateInput.test.tsx +115 -3
- package/src/DateInput/DateInput.tsx +29 -14
- package/src/DateInput/DateInputTouch.test.tsx +76 -0
- package/src/DateInput/MonthScroller.tsx +106 -20
- package/src/DateInput/MonthScrollerSettle.test.tsx +165 -0
- package/src/DateInput/TouchDateField.tsx +14 -3
- package/src/DateInput/__tests__/MonthScrollerSteps.interaction.browser.spec.ts +312 -0
- package/src/DateRangeInput/DateRangeInput.test.tsx +46 -3
- package/src/DateRangeInput/DateRangeInput.tsx +16 -12
- package/src/DateTimeInput/DateTimeInput.doc.mjs +10 -8
- package/src/DateTimeInput/DateTimeInput.spec.md +75 -51
- package/src/DateTimeInput/DateTimeInput.test.tsx +81 -0
- package/src/DateTimeInput/DateTimeInput.tsx +46 -24
- package/src/DateTimeInput/NativeTimeSegment.tsx +4 -6
- package/src/DateTimeInput/TouchDateTimeField.tsx +3 -7
- package/src/Dialog/Dialog.test.tsx +216 -2
- package/src/Dialog/Dialog.tsx +42 -9
- package/src/Dialog/DialogHeader.tsx +5 -4
- package/src/Dialog/__tests__/DialogSecondDocument.a11y.browser.spec.ts +202 -0
- package/src/Divider/Divider.tsx +2 -1
- package/src/Drawer/Drawer.spec.md +111 -80
- package/src/Drawer/Drawer.test.tsx +35 -0
- package/src/Drawer/Drawer.tsx +13 -2
- package/src/Drawer/DrawerHeader.spec.md +181 -0
- package/src/Drawer/__tests__/DrawerNonModalPageScroll.a11y.chromium.spec.ts +267 -0
- package/src/DropdownMenu/DropdownMenu.test.tsx +41 -0
- package/src/DropdownMenu/DropdownMenu.tsx +10 -3
- package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +34 -0
- package/src/DropdownMenu/MenuBottomSheetActionList.tsx +6 -5
- package/src/DropdownMenu/__tests__/Menu.a11y.chromium.spec.ts +19 -7
- package/src/DropdownMenu/__tests__/MenuButton.a11y.chromium.spec.ts +21 -9
- package/src/DropdownMenu/lazyMenuBottomSheet.test.ts +60 -0
- package/src/DropdownMenu/lazyMenuBottomSheet.ts +36 -7
- package/src/DropdownMenu/renderDropdownItems.tsx +24 -19
- package/src/EmptyState/EmptyState.tsx +2 -1
- package/src/Field/FieldLabel.tsx +5 -4
- package/src/Field/InputClearButton.tsx +3 -3
- package/src/Field/PanelSearchInput.tsx +2 -2
- package/src/FieldStatus/FieldStatus.tsx +2 -2
- package/src/FileInput/FileInput.test.tsx +21 -0
- package/src/FileInput/FileInput.tsx +4 -1
- package/src/FormLayout/FormLayout.spec.md +7 -8
- package/src/Heading/Heading.tsx +1 -1
- package/src/Icon/Icon.tsx +1 -1
- package/src/Indicator/CheckIndicator.spec.md +47 -42
- package/src/Indicator/CheckIndicator.tsx +2 -1
- package/src/Indicator/CheckboxIndicator.spec.md +40 -37
- package/src/Indicator/CheckboxIndicator.tsx +3 -1
- package/src/Indicator/Indicator.spec.md +188 -0
- package/src/Indicator/RadioIndicator.tsx +3 -1
- package/src/Item/Item.tsx +2 -1
- package/src/Item/ItemSwipeLayer.tsx +1 -1
- package/src/Kbd/Kbd.spec.md +81 -38
- package/src/Layer/__tests__/LayerBrowserHide.a11y.chromium.spec.ts +126 -0
- package/src/Layer/popoverOperations.test.ts +205 -0
- package/src/Layer/popoverOperations.ts +172 -0
- package/src/Layer/useLayer.test.tsx +348 -1
- package/src/Layer/useLayer.tsx +118 -71
- package/src/Layout/Layout.spec.md +127 -131
- package/src/Layout/Layout.tsx +1 -1
- package/src/Layout/LayoutContent.spec.md +205 -0
- package/src/Layout/LayoutContent.tsx +1 -1
- package/src/Layout/LayoutFooter.spec.md +190 -0
- package/src/Layout/LayoutFooter.tsx +1 -1
- package/src/Layout/LayoutHeader.spec.md +193 -0
- package/src/Layout/LayoutHeader.tsx +1 -1
- package/src/Layout/LayoutPanel.spec.md +194 -0
- package/src/Layout/__tests__/Layout.a11y.chromium.spec.ts +18 -6
- package/src/Lightbox/Lightbox.test.tsx +18 -0
- package/src/Lightbox/Lightbox.tsx +5 -0
- package/src/Lightbox/LightboxViewport.a11y.browser.spec.ts +8 -4
- package/src/Link/__tests__/Link.a11y.chromium.spec.ts +18 -8
- package/src/List/List.tsx +1 -1
- package/src/List/ListItem.spec.md +205 -0
- package/src/List/ListItem.tsx +3 -3
- package/src/MetadataList/MetadataList.spec.md +187 -0
- package/src/MetadataList/MetadataListItem.spec.md +165 -0
- package/src/MobileNav/MobileNav.test.tsx +15 -0
- package/src/MobileNav/MobileNav.tsx +9 -1
- package/src/MobileNav/__tests__/MobileNavHeader.a11y.chromium.spec.ts +89 -0
- package/src/MoreMenu/MoreMenu.test.tsx +11 -0
- package/src/MultiSelector/CreateRow.a11y.chromium.spec.ts +7 -8
- package/src/MultiSelector/MultiSelector.spec.md +7 -4
- package/src/MultiSelector/MultiSelector.test.tsx +270 -1
- package/src/MultiSelector/MultiSelector.tsx +25 -10
- package/src/MultiSelector/__tests__/MultiSelector.listbox.a11y.test.tsx +8 -1
- package/src/NavMenu/NavHeadingMenu.spec.md +1 -5
- package/src/NumberInput/NumberInput.doc.mjs +13 -7
- package/src/NumberInput/NumberInput.spec.md +59 -37
- package/src/NumberInput/NumberInput.tsx +13 -3
- package/src/NumberInput/__tests__/NumberInput.coarse-pointer.a11y.chromium.spec.ts +102 -0
- package/src/NumberInput/numberParser.ts +7 -45
- package/src/ProgressBar/ProgressBar.test.tsx +108 -32
- package/src/ProgressBar/ProgressBar.tsx +58 -10
- package/src/ProgressBar/__tests__/ProgressBar.a11y.chromium.spec.ts +21 -9
- package/src/ProgressBar/__tests__/ProgressBarMotion.a11y.chromium.spec.ts +831 -0
- package/src/Resizable/__tests__/ResizeHandle.a11y.chromium.spec.ts +21 -14
- package/src/Resizable/useResizable.test.ts +43 -0
- package/src/Resizable/useResizable.ts +32 -9
- package/src/SegmentedControl/SegmentedControl.test.tsx +84 -0
- package/src/SegmentedControl/SegmentedControlItem.tsx +11 -5
- package/src/Selector/Selector.test.tsx +90 -1
- package/src/Selector/__tests__/Selector.combobox.a11y.test.tsx +8 -1
- package/src/Selector/__tests__/Selector.listbox.a11y.test.tsx +8 -1
- package/src/Selector/useSelectorPresentation.ts +31 -3
- package/src/SideNav/SideNav.test.tsx +27 -0
- package/src/SideNav/__tests__/SideNavRailMotion.interaction.browser.spec.ts +176 -51
- package/src/Skeleton/Skeleton.tsx +3 -1
- package/src/Slider/Slider.test.tsx +31 -0
- package/src/Slider/Slider.tsx +8 -3
- package/src/Slider/__tests__/Slider.a11y.chromium.spec.ts +19 -7
- package/src/Spinner/Spinner.tsx +5 -3
- package/src/Stack/Stack.tsx +1 -1
- package/src/Stack/StackItem.tsx +1 -1
- package/src/TabList/TabList.test.tsx +58 -4
- package/src/TabList/TabList.tsx +16 -1
- package/src/TabList/__tests__/TabPressPointer.interaction.browser.spec.ts +163 -0
- package/src/Table/__tests__/Table.a11y.chromium.spec.ts +18 -6
- package/src/Table/plugins/columnResize/useTableColumnResize.test.tsx +22 -0
- package/src/Table/plugins/columnResize/useTableColumnResize.tsx +8 -4
- package/src/Text/Text.tsx +1 -1
- package/src/Text/useTruncation.test.tsx +128 -1
- package/src/Text/useTruncation.ts +23 -5
- package/src/TextArea/TextArea.spec.md +10 -13
- package/src/TextArea/TextArea.test.tsx +60 -0
- package/src/TextArea/TextArea.tsx +15 -1
- package/src/TextInput/TextInput.test.tsx +21 -0
- package/src/TextInput/TextInput.tsx +3 -1
- package/src/TimeInput/NativeTimeInput.test.tsx +17 -0
- package/src/TimeInput/Presentation.test.tsx +21 -0
- package/src/TimeInput/TimeInput.doc.mjs +8 -8
- package/src/TimeInput/TimeInput.spec.md +45 -48
- package/src/TimeInput/TimeInput.test.tsx +76 -0
- package/src/TimeInput/TimeInput.tsx +36 -18
- package/src/TimeInput/TouchTimeField.tsx +4 -6
- package/src/Timestamp/Timestamp.spec.md +6 -12
- package/src/Timestamp/Timestamp.test.tsx +30 -5
- package/src/Timestamp/Timestamp.tsx +6 -2
- package/src/Timestamp/TimestampHoverCard.tsx +4 -4
- package/src/Toast/Toast.spec.md +14 -20
- package/src/Toast/Toast.tsx +104 -36
- package/src/Toast/ToastViewport.test.tsx +719 -1
- package/src/Toast/ToastViewport.tsx +100 -50
- package/src/Tokenizer/Tokenizer.spec.md +5 -3
- package/src/Tokenizer/Tokenizer.test.tsx +68 -0
- package/src/Tokenizer/Tokenizer.tsx +14 -2
- package/src/Tokenizer/TokenizerBottomSheet.test.tsx +15 -4
- package/src/Tokenizer/TokenizerBottomSheet.tsx +3 -3
- package/src/Toolbar/Toolbar.spec.md +5 -6
- package/src/Toolbar/Toolbar.test.tsx +30 -0
- package/src/Toolbar/Toolbar.tsx +2 -1
- package/src/Toolbar/__tests__/Toolbar.a11y.chromium.spec.ts +18 -6
- package/src/Tooltip/__tests__/Tooltip.a11y.chromium.spec.ts +18 -7
- package/src/TopNav/TopNav.test.tsx +27 -0
- package/src/TopNav/TopNavMegaMenu.test.tsx +21 -0
- package/src/TopNav/TopNavMegaMenu.tsx +4 -1
- package/src/TopNav/TopNavMenu.test.tsx +17 -0
- package/src/TopNav/TopNavMenu.tsx +1 -0
- package/src/Typeahead/Typeahead.test.tsx +40 -0
- package/src/Typeahead/Typeahead.tsx +12 -1
- package/src/__tests__/pressState.ts +8 -4
- package/src/gestures/GestureArena.ts +35 -0
- package/src/gestures/GestureHost.ts +2065 -0
- package/src/gestures/GestureRecognizer.ts +18 -0
- package/src/gestures/LongPressGestureRecognizer.ts +4 -0
- package/src/gestures/PanGestureRecognizer.ts +4 -0
- package/src/gestures/PinchGestureRecognizer.ts +148 -0
- package/src/gestures/ScreenEdgePanGestureRecognizer.ts +256 -0
- package/src/gestures/SwipeGestureRecognizer.ts +197 -0
- package/src/gestures/TapGestureRecognizer.ts +4 -0
- package/src/gestures/VelocityTracker.ts +10 -3
- package/src/gestures/__tests__/GestureHost.test.ts +2087 -0
- package/src/gestures/__tests__/PanGestureRecognizer.test.ts +4 -4
- package/src/gestures/__tests__/PinchGestureRecognizer.test.ts +74 -0
- package/src/gestures/__tests__/ScreenEdgePanGestureRecognizer.test.ts +498 -0
- package/src/gestures/__tests__/SwipeGestureRecognizer.test.ts +108 -0
- package/src/gestures/__tests__/arena.test.ts +5 -0
- package/src/gestures/__tests__/arenaPinchSwipeEdge.test.ts +193 -0
- package/src/gestures/__tests__/browser/build-fixture.mjs +46 -0
- package/src/gestures/__tests__/browser/fixture.ts +307 -0
- package/src/gestures/__tests__/browser/gestures.interaction.browser.spec.ts +1137 -0
- package/src/gestures/__tests__/browserNegotiation.test.ts +293 -0
- package/src/gestures/__tests__/haptics.test.ts +187 -0
- package/src/gestures/__tests__/harness.ts +21 -2
- package/src/gestures/__tests__/recognizerKind.test.ts +78 -0
- package/src/gestures/__tests__/touchActionRule.test.ts +54 -0
- package/src/gestures/haptics.ts +203 -0
- package/src/gestures/nativeScroll.ts +277 -0
- package/src/gestures/touchAction.ts +191 -0
- package/src/gestures/touchActionRule.ts +157 -0
- package/src/gestures/types.ts +30 -9
- package/src/hooks/index.ts +5 -1
- package/src/hooks/modalAnnounce.ts +129 -72
- package/src/hooks/useAdaptivePresentation.ts +4 -1
- package/src/hooks/useAnnounce.doc.mjs +35 -3
- package/src/hooks/useAnnounce.replace.test.tsx +516 -0
- package/src/hooks/useAnnounce.ts +209 -102
- package/src/hooks/useAnnounceRenderedText.adopters.test.tsx +10 -1
- package/src/hooks/useAnnounceRenderedText.ts +17 -3
- package/src/hooks/useBusyAnnouncement.ts +7 -10
- package/src/hooks/useMenuHover.ts +15 -1
- package/src/i18n/generated-locales/en.generated.ts +6 -0
- package/src/i18n/generated-locales/pseudo.generated.ts +6 -0
- package/src/motion/README.md +11 -1
- package/src/motion/animator.test.ts +151 -3
- package/src/motion/animator.ts +149 -33
- package/src/theme/Theme.doc.mjs +1 -1
- package/src/theme/defineTheme.ts +117 -8
- package/src/theme/derivedVarRegistry.test.ts +4 -0
- package/src/theme/domainTokens/domainTokenDefaults.ts +19 -0
- package/src/theme/domainTokens/index.ts +6 -10
- package/src/theme/expandMotionScale.test.ts +1 -1
- package/src/theme/index.ts +5 -0
- package/src/theme/motionKnobs.ts +82 -0
- package/src/theme/resolveThemeValues.ts +68 -6
- package/src/theme/themeAdaptations.ts +52 -12
- package/src/theme/themeMotion.test.ts +620 -0
- package/src/theme/themeMotion.ts +221 -0
- package/src/theme/tokenReferences.ts +149 -0
- package/src/theme/tokens.stylex.ts +10 -0
- package/src/theme/tokens.ts +15 -158
- package/src/utils/focusReturn.ts +17 -6
- package/src/utils/getNodeText.test.ts +24 -0
- package/src/utils/getNodeText.ts +37 -0
- package/src/utils/interactionModality.test.ts +45 -1
- package/src/utils/interactionModality.ts +64 -5
- package/src/utils/interactionOverlay.stylex.ts +12 -3
- package/src/utils/plainDate.test.ts +90 -0
- package/src/utils/plainDate.ts +58 -3
- package/src/utils/presentation.test.ts +380 -0
- package/src/utils/presentation.ts +180 -0
- package/src/utils/pressFeedback.test.ts +138 -0
- package/src/utils/pressFeedback.ts +34 -11
- package/src/utils/pressPaintPriority.test.ts +80 -0
- package/src/utils/primaryClick.test.ts +38 -0
- package/src/utils/primaryClick.ts +28 -0
- package/src/utils/timeFormat.test.ts +204 -0
- package/src/utils/timeFormat.ts +314 -0
- package/src/utils/touchPresentation.stylex.ts +43 -0
- package/src/utils/touchPresentation.test.ts +140 -1
- package/src/utils/touchPresentation.ts +5 -3
- package/src/utils/unicodeDigits.test.ts +44 -0
- package/src/utils/unicodeDigits.ts +71 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file getNodeText.ts
|
|
5
|
+
* @input Receives a React node
|
|
6
|
+
* @output Exports getNodeText, the node's plain text
|
|
7
|
+
* @position Shared utility; consumed where a rendered node also needs a
|
|
8
|
+
* spoken name (Toast announcements, Table column-resize handle names)
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import {isValidElement} from 'react';
|
|
12
|
+
import type {ReactNode} from 'react';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The plain text a node renders through strings, numbers and element
|
|
16
|
+
* children, joined with spaces. Text a component renders internally, from
|
|
17
|
+
* props other than `children`, is not reachable and yields `''`.
|
|
18
|
+
*/
|
|
19
|
+
export function getNodeText(node: ReactNode): string {
|
|
20
|
+
if (node == null || typeof node === 'boolean') {
|
|
21
|
+
return '';
|
|
22
|
+
}
|
|
23
|
+
if (typeof node === 'string') {
|
|
24
|
+
return node;
|
|
25
|
+
}
|
|
26
|
+
if (typeof node === 'number') {
|
|
27
|
+
return String(node);
|
|
28
|
+
}
|
|
29
|
+
if (Array.isArray(node)) {
|
|
30
|
+
return node.map(getNodeText).filter(Boolean).join(' ');
|
|
31
|
+
}
|
|
32
|
+
if (isValidElement(node)) {
|
|
33
|
+
const {children} = node.props as {children?: ReactNode};
|
|
34
|
+
return getNodeText(children);
|
|
35
|
+
}
|
|
36
|
+
return '';
|
|
37
|
+
}
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* @file interactionModality.test.ts
|
|
5
5
|
* @input The interaction-modality utility loaded more than once
|
|
6
|
-
* @output Verifies document-wide continuity
|
|
6
|
+
* @output Verifies document-wide continuity, shared Shift-key modality policy,
|
|
7
|
+
* and a second document's separate value
|
|
7
8
|
* @position Unit coverage for interactionModality.ts
|
|
8
9
|
*/
|
|
9
10
|
|
|
@@ -88,6 +89,49 @@ describe('interactionModality', () => {
|
|
|
88
89
|
).toHaveLength(1);
|
|
89
90
|
});
|
|
90
91
|
|
|
92
|
+
it("keeps a second document's input apart from the page's", async () => {
|
|
93
|
+
const pageDocument = document.implementation.createHTMLDocument();
|
|
94
|
+
const secondDocument = document.implementation.createHTMLDocument();
|
|
95
|
+
vi.stubGlobal('document', pageDocument);
|
|
96
|
+
const tracker = await loadTracker();
|
|
97
|
+
tracker.__startInteractionModalityTrackingForTest();
|
|
98
|
+
tracker.trackInteractionModalityIn(secondDocument);
|
|
99
|
+
|
|
100
|
+
pageDocument.dispatchEvent(new Event('pointerdown'));
|
|
101
|
+
secondDocument.dispatchEvent(new KeyboardEvent('keydown', {key: 'Escape'}));
|
|
102
|
+
expect(tracker.getInteractionModality()).toBe('pointer');
|
|
103
|
+
expect(tracker.getInteractionModality(pageDocument)).toBe('pointer');
|
|
104
|
+
expect(tracker.getInteractionModality(secondDocument)).toBe('keyboard');
|
|
105
|
+
|
|
106
|
+
secondDocument.dispatchEvent(new Event('pointerdown'));
|
|
107
|
+
pageDocument.dispatchEvent(new KeyboardEvent('keydown', {key: 'Tab'}));
|
|
108
|
+
expect(tracker.getInteractionModality()).toBe('keyboard');
|
|
109
|
+
expect(tracker.getInteractionModality(secondDocument)).toBe('pointer');
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it("releases a second document's listeners with its last consumer", async () => {
|
|
113
|
+
const secondDocument = document.implementation.createHTMLDocument();
|
|
114
|
+
const tracker = await loadTracker();
|
|
115
|
+
const removeEventListener = vi.spyOn(secondDocument, 'removeEventListener');
|
|
116
|
+
const releaseFirst = tracker.trackInteractionModalityIn(secondDocument);
|
|
117
|
+
const releaseSecond = tracker.trackInteractionModalityIn(secondDocument);
|
|
118
|
+
secondDocument.dispatchEvent(new Event('pointerdown'));
|
|
119
|
+
expect(tracker.getInteractionModality(secondDocument)).toBe('pointer');
|
|
120
|
+
|
|
121
|
+
releaseFirst();
|
|
122
|
+
releaseFirst();
|
|
123
|
+
secondDocument.dispatchEvent(new KeyboardEvent('keydown', {key: 'Tab'}));
|
|
124
|
+
expect(tracker.getInteractionModality(secondDocument)).toBe('keyboard');
|
|
125
|
+
expect(removeEventListener).not.toHaveBeenCalled();
|
|
126
|
+
|
|
127
|
+
releaseSecond();
|
|
128
|
+
expect(removeEventListener.mock.calls.map(([type]) => type).sort()).toEqual(
|
|
129
|
+
['keydown', 'pointerdown'],
|
|
130
|
+
);
|
|
131
|
+
secondDocument.dispatchEvent(new Event('pointerdown'));
|
|
132
|
+
expect(tracker.getInteractionModality(secondDocument)).toBe('keyboard');
|
|
133
|
+
});
|
|
134
|
+
|
|
91
135
|
it('uses the keyboard-safe default without a document', async () => {
|
|
92
136
|
vi.stubGlobal('document', undefined);
|
|
93
137
|
const serverModule = await loadTracker();
|
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
* @file interactionModality.ts
|
|
7
7
|
* @input Global pointerdown/keydown events
|
|
8
8
|
* @output `useInteractionModalityTracking()` activates document-lifetime tracking;
|
|
9
|
-
* `getInteractionModality()` reads how the user last interacted
|
|
9
|
+
* `getInteractionModality()` reads how the user last interacted;
|
|
10
|
+
* `trackInteractionModalityIn(doc)` and `getInteractionModality(doc)` do the
|
|
11
|
+
* same for a second document
|
|
10
12
|
* @position Internal document-wide singleton; used where `:focus-visible` alone
|
|
11
13
|
* is too broad
|
|
12
14
|
*
|
|
@@ -26,8 +28,12 @@
|
|
|
26
28
|
* The store lives on `document`, so duplicate Astryx bundles share one state
|
|
27
29
|
* value and one listener pair. The first mounted consumer activates tracking;
|
|
28
30
|
* the listeners then remain for the document lifetime so input during a gap
|
|
29
|
-
* between consumers is not lost.
|
|
30
|
-
*
|
|
31
|
+
* between consumers is not lost. A second document (a same-origin iframe, a
|
|
32
|
+
* Document Picture-in-Picture window) gets its own store when a component
|
|
33
|
+
* tracks it, since input there never reaches the page's listeners; its
|
|
34
|
+
* listeners stay only while a consumer there is mounted. Importing this module
|
|
35
|
+
* has no DOM side effects, and server rendering keeps the keyboard-safe
|
|
36
|
+
* default.
|
|
31
37
|
*/
|
|
32
38
|
|
|
33
39
|
import {useEffect} from 'react';
|
|
@@ -37,6 +43,8 @@ export type InteractionModality = 'keyboard' | 'pointer';
|
|
|
37
43
|
type InteractionModalityStore = {
|
|
38
44
|
modality: InteractionModality;
|
|
39
45
|
isListening: boolean;
|
|
46
|
+
/** Mounted consumers holding a second document's listeners. */
|
|
47
|
+
consumers?: number;
|
|
40
48
|
onPointerDown: () => void;
|
|
41
49
|
onKeyDown: (event: KeyboardEvent) => void;
|
|
42
50
|
};
|
|
@@ -107,8 +115,59 @@ export function useInteractionModalityTracking(): void {
|
|
|
107
115
|
useEffect(() => trackInteractionModality(), []);
|
|
108
116
|
}
|
|
109
117
|
|
|
110
|
-
/**
|
|
111
|
-
|
|
118
|
+
/**
|
|
119
|
+
* Track a second document while a consumer there is mounted: a component an
|
|
120
|
+
* app renders into a same-origin iframe or a Document Picture-in-Picture
|
|
121
|
+
* window gets input there that never reaches the page's listeners. The first
|
|
122
|
+
* consumer installs the document's listener pair and the last one's cleanup
|
|
123
|
+
* removes it. Read the value with `getInteractionModality(doc)`. The page's
|
|
124
|
+
* own document keeps its document-lifetime listeners.
|
|
125
|
+
*/
|
|
126
|
+
export function trackInteractionModalityIn(
|
|
127
|
+
targetDocument: Document,
|
|
128
|
+
): () => void {
|
|
129
|
+
if (typeof document !== 'undefined' && targetDocument === document) {
|
|
130
|
+
return trackInteractionModality();
|
|
131
|
+
}
|
|
132
|
+
const store = getStore(targetDocument);
|
|
133
|
+
store.consumers = (store.consumers ?? 0) + 1;
|
|
134
|
+
if (store.consumers === 1) {
|
|
135
|
+
store.isListening = true;
|
|
136
|
+
targetDocument.addEventListener('pointerdown', store.onPointerDown, {
|
|
137
|
+
capture: true,
|
|
138
|
+
passive: true,
|
|
139
|
+
});
|
|
140
|
+
targetDocument.addEventListener('keydown', store.onKeyDown, {
|
|
141
|
+
capture: true,
|
|
142
|
+
passive: true,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
let isReleased = false;
|
|
146
|
+
return () => {
|
|
147
|
+
if (isReleased) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
isReleased = true;
|
|
151
|
+
store.consumers = (store.consumers ?? 1) - 1;
|
|
152
|
+
if (store.consumers === 0) {
|
|
153
|
+
store.isListening = false;
|
|
154
|
+
targetDocument.removeEventListener('pointerdown', store.onPointerDown, {
|
|
155
|
+
capture: true,
|
|
156
|
+
});
|
|
157
|
+
targetDocument.removeEventListener('keydown', store.onKeyDown, {
|
|
158
|
+
capture: true,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** How the user last interacted with the page, or with `targetDocument`. */
|
|
165
|
+
export function getInteractionModality(
|
|
166
|
+
targetDocument?: Document,
|
|
167
|
+
): InteractionModality {
|
|
168
|
+
if (targetDocument != null) {
|
|
169
|
+
return getStore(targetDocument).modality;
|
|
170
|
+
}
|
|
112
171
|
return typeof document === 'undefined'
|
|
113
172
|
? 'keyboard'
|
|
114
173
|
: getStore(document).modality;
|
|
@@ -116,8 +116,14 @@ export const pressConsts = stylex.defineConsts({
|
|
|
116
116
|
releaseMs: 200,
|
|
117
117
|
});
|
|
118
118
|
|
|
119
|
-
/**
|
|
120
|
-
|
|
119
|
+
/**
|
|
120
|
+
* The release's clock as CSS, scaled by the theme's `--_astryx-motion-tempo`
|
|
121
|
+
* (`spec:AST-108` FR4, `component:Button` FR15) up to 1.5, its maximum. The
|
|
122
|
+
* controller's timer reads the same property.
|
|
123
|
+
*/
|
|
124
|
+
const PRESS_RELEASE_DURATION = `calc(${pressConsts.releaseMs}ms * min(var(--_astryx-motion-tempo, 1), 1.5))`;
|
|
125
|
+
/** The same clock under Reduce Motion: a tempo may shorten it, never lengthen it. */
|
|
126
|
+
const PRESS_RELEASE_DURATION_REDUCED = `min(${pressConsts.releaseMs}ms, calc(${pressConsts.releaseMs}ms * var(--_astryx-motion-tempo, 1)))`;
|
|
121
127
|
|
|
122
128
|
const ENABLED = ':where(:not(:disabled,[aria-disabled="true"]))';
|
|
123
129
|
const HOVER_HOVER = '@media (hover: hover)';
|
|
@@ -205,7 +211,10 @@ const pressReleaseAnimation = {
|
|
|
205
211
|
},
|
|
206
212
|
animationDuration: {
|
|
207
213
|
default: null,
|
|
208
|
-
'[data-astryx-press="fading"]':
|
|
214
|
+
'[data-astryx-press="fading"]': {
|
|
215
|
+
default: PRESS_RELEASE_DURATION,
|
|
216
|
+
'@media (prefers-reduced-motion: reduce)': PRESS_RELEASE_DURATION_REDUCED,
|
|
217
|
+
},
|
|
209
218
|
},
|
|
210
219
|
animationTimingFunction: {
|
|
211
220
|
default: null,
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
plainDateFromISO,
|
|
8
8
|
plainDateToISO,
|
|
9
9
|
plainDateToDate,
|
|
10
|
+
dateTimeFormatFor,
|
|
10
11
|
plainDateFromDate,
|
|
11
12
|
plainDateToday,
|
|
12
13
|
getDaysInMonth,
|
|
@@ -28,6 +29,7 @@ import {
|
|
|
28
29
|
plainDateGetWeekNumber,
|
|
29
30
|
plainDateFormat,
|
|
30
31
|
formatSharedDate,
|
|
32
|
+
DATE_FORMAT_LONG,
|
|
31
33
|
DATE_FORMAT_WITH_WEEKDAY,
|
|
32
34
|
DATE_FORMAT_MONTH_YEAR,
|
|
33
35
|
plainDateWeekFieldName,
|
|
@@ -754,6 +756,94 @@ describe('plainDateGetWeekNumber', () => {
|
|
|
754
756
|
});
|
|
755
757
|
|
|
756
758
|
describe('plainDateFormat', () => {
|
|
759
|
+
it('keeps one formatter per locale and options, whatever order the options are in', () => {
|
|
760
|
+
// A month of day labels, as a calendar renders them, reuses one formatter.
|
|
761
|
+
const first = dateTimeFormatFor('en-NZ', DATE_FORMAT_WITH_WEEKDAY);
|
|
762
|
+
expect(dateTimeFormatFor('en-NZ', DATE_FORMAT_WITH_WEEKDAY)).toBe(first);
|
|
763
|
+
expect(
|
|
764
|
+
dateTimeFormatFor('en-NZ', {
|
|
765
|
+
year: 'numeric',
|
|
766
|
+
day: 'numeric',
|
|
767
|
+
month: 'long',
|
|
768
|
+
weekday: 'long',
|
|
769
|
+
}),
|
|
770
|
+
).toBe(first);
|
|
771
|
+
// Other options, or another locale, get their own.
|
|
772
|
+
expect(dateTimeFormatFor('en-NZ', DATE_FORMAT_MONTH_YEAR)).not.toBe(first);
|
|
773
|
+
expect(dateTimeFormatFor('en-ZA', DATE_FORMAT_WITH_WEEKDAY)).not.toBe(
|
|
774
|
+
first,
|
|
775
|
+
);
|
|
776
|
+
});
|
|
777
|
+
|
|
778
|
+
it('formats the same date after the host zone moves', () => {
|
|
779
|
+
// The page stays open while the device travels east: a formatter cached
|
|
780
|
+
// in the first zone must not move the date.
|
|
781
|
+
const zone = process.env.TZ;
|
|
782
|
+
try {
|
|
783
|
+
process.env.TZ = 'America/Los_Angeles';
|
|
784
|
+
expect(
|
|
785
|
+
plainDateFormat(
|
|
786
|
+
{year: 2026, month: 2, day: 1},
|
|
787
|
+
DATE_FORMAT_MONTH_YEAR,
|
|
788
|
+
'en-IE',
|
|
789
|
+
),
|
|
790
|
+
).toBe('February 2026');
|
|
791
|
+
process.env.TZ = 'America/New_York';
|
|
792
|
+
expect(
|
|
793
|
+
plainDateFormat(
|
|
794
|
+
{year: 2026, month: 2, day: 1},
|
|
795
|
+
DATE_FORMAT_MONTH_YEAR,
|
|
796
|
+
'en-IE',
|
|
797
|
+
),
|
|
798
|
+
).toBe('February 2026');
|
|
799
|
+
process.env.TZ = 'Pacific/Kiritimati';
|
|
800
|
+
expect(
|
|
801
|
+
plainDateFormat(
|
|
802
|
+
{year: 2026, month: 2, day: 1},
|
|
803
|
+
DATE_FORMAT_WITH_WEEKDAY,
|
|
804
|
+
'en-IE',
|
|
805
|
+
),
|
|
806
|
+
).toBe('Sunday 1 February 2026');
|
|
807
|
+
} finally {
|
|
808
|
+
if (zone === undefined) {
|
|
809
|
+
delete process.env.TZ;
|
|
810
|
+
} else {
|
|
811
|
+
process.env.TZ = zone;
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
});
|
|
815
|
+
|
|
816
|
+
it('prints a zone name or a time of day in the host zone, as before', () => {
|
|
817
|
+
// A PlainDate has neither: such fields read local midnight in the zone
|
|
818
|
+
// current at the call, not the UTC the date-only path formats in.
|
|
819
|
+
const zone = process.env.TZ;
|
|
820
|
+
try {
|
|
821
|
+
process.env.TZ = 'America/Los_Angeles';
|
|
822
|
+
const withZone = plainDateFormat(
|
|
823
|
+
{year: 2026, month: 1, day: 25},
|
|
824
|
+
{...DATE_FORMAT_LONG, timeZoneName: 'short'},
|
|
825
|
+
'en-US',
|
|
826
|
+
);
|
|
827
|
+
expect(withZone).toContain('January 25, 2026');
|
|
828
|
+
expect(withZone).toContain('PST');
|
|
829
|
+
expect(withZone).not.toContain('UTC');
|
|
830
|
+
process.env.TZ = 'America/New_York';
|
|
831
|
+
expect(
|
|
832
|
+
plainDateFormat(
|
|
833
|
+
{year: 2026, month: 1, day: 25},
|
|
834
|
+
{...DATE_FORMAT_LONG, timeZoneName: 'short'},
|
|
835
|
+
'en-US',
|
|
836
|
+
),
|
|
837
|
+
).toContain('EST');
|
|
838
|
+
} finally {
|
|
839
|
+
if (zone === undefined) {
|
|
840
|
+
delete process.env.TZ;
|
|
841
|
+
} else {
|
|
842
|
+
process.env.TZ = zone;
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
});
|
|
846
|
+
|
|
757
847
|
it('returns a human-readable date string with weekday', () => {
|
|
758
848
|
const result = plainDateFormat(
|
|
759
849
|
{year: 2026, month: 1, day: 25},
|
package/src/utils/plainDate.ts
CHANGED
|
@@ -374,10 +374,65 @@ export function plainDateFormat(
|
|
|
374
374
|
options: Intl.DateTimeFormatOptions,
|
|
375
375
|
locale: Locale = 'en',
|
|
376
376
|
): string {
|
|
377
|
-
|
|
377
|
+
const calendar = options.calendar ?? 'gregory';
|
|
378
|
+
if (options.timeZone != null) {
|
|
379
|
+
return dateTimeFormatFor(locale, {...options, calendar}).format(
|
|
380
|
+
plainDateToDate(pd),
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
if (TIME_OF_DAY_FIELDS.some(field => options[field] != null)) {
|
|
384
|
+
// A zone name or a time of day reads local midnight in the zone current
|
|
385
|
+
// at the call. A cached formatter would keep the zone it was built in,
|
|
386
|
+
// so this one is built for the call.
|
|
387
|
+
return new Intl.DateTimeFormat(locale, {...options, calendar}).format(
|
|
388
|
+
plainDateToDate(pd),
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
// Date fields alone: UTC midnight formatted in UTC, so neither the cached
|
|
392
|
+
// formatter nor the date depends on the host's zone, which can change while
|
|
393
|
+
// a page is open.
|
|
394
|
+
return dateTimeFormatFor(locale, {
|
|
378
395
|
...options,
|
|
379
|
-
calendar
|
|
380
|
-
|
|
396
|
+
calendar,
|
|
397
|
+
timeZone: 'UTC',
|
|
398
|
+
}).format(utcTime(pd.year, pd.month - 1, pd.day));
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/** Options that print a time of day or a zone, which a PlainDate lacks. */
|
|
402
|
+
const TIME_OF_DAY_FIELDS = [
|
|
403
|
+
'timeZoneName',
|
|
404
|
+
'hour',
|
|
405
|
+
'minute',
|
|
406
|
+
'second',
|
|
407
|
+
'fractionalSecondDigits',
|
|
408
|
+
'dayPeriod',
|
|
409
|
+
'timeStyle',
|
|
410
|
+
] as const satisfies ReadonlyArray<keyof Intl.DateTimeFormatOptions>;
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* One `Intl.DateTimeFormat` per locale and options, built on first use.
|
|
414
|
+
* Building a formatter costs far more than formatting with it, and a calendar
|
|
415
|
+
* formats each of a month's 42 day labels with the same options on every
|
|
416
|
+
* render. The options are keyed in a fixed order, so the same options written
|
|
417
|
+
* in another order share a formatter.
|
|
418
|
+
*/
|
|
419
|
+
const dateTimeFormats = new Map<string, Intl.DateTimeFormat>();
|
|
420
|
+
|
|
421
|
+
/** @internal plainDateFormat's formatter cache; not part of the public API. */
|
|
422
|
+
export function dateTimeFormatFor(
|
|
423
|
+
locale: Locale,
|
|
424
|
+
options: Intl.DateTimeFormatOptions,
|
|
425
|
+
): Intl.DateTimeFormat {
|
|
426
|
+
const key = JSON.stringify([
|
|
427
|
+
locale,
|
|
428
|
+
Object.entries(options).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)),
|
|
429
|
+
]);
|
|
430
|
+
let format = dateTimeFormats.get(key);
|
|
431
|
+
if (format == null) {
|
|
432
|
+
format = new Intl.DateTimeFormat(locale, options);
|
|
433
|
+
dateTimeFormats.set(key, format);
|
|
434
|
+
}
|
|
435
|
+
return format;
|
|
381
436
|
}
|
|
382
437
|
|
|
383
438
|
/**
|