@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
|
@@ -99,7 +99,7 @@ import {
|
|
|
99
99
|
} from '../theme/tokens.stylex';
|
|
100
100
|
import {useDevWarning} from '../hooks/useDevWarning';
|
|
101
101
|
import {useScrollLock} from '../hooks/useScrollLock';
|
|
102
|
-
import {mergeProps} from '../utils';
|
|
102
|
+
import {mergeProps} from '../utils/mergeProps';
|
|
103
103
|
import {LayerDepthProvider} from '../Layer/LayerDepthContext';
|
|
104
104
|
import {ModalAnnounceProvider} from '../hooks/ModalAnnounceProvider';
|
|
105
105
|
import {useModalOutlet} from '../Layer/modalOutlet';
|
|
@@ -48,7 +48,8 @@ import {
|
|
|
48
48
|
sizeVars,
|
|
49
49
|
spacingVars,
|
|
50
50
|
} from '../theme/tokens.stylex';
|
|
51
|
-
import {mergeProps
|
|
51
|
+
import {mergeProps} from '../utils/mergeProps';
|
|
52
|
+
import {themeProps} from '../utils/themeProps';
|
|
52
53
|
import {focusOutlineStyles} from '../utils/focusOutline.stylex';
|
|
53
54
|
import {layerTextReset} from '../Layer/layerTextReset.stylex';
|
|
54
55
|
import {layerStructureReset} from '../Layer/layerStructureReset.stylex';
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
import {describe, it, expect, vi, beforeEach, afterEach} from 'vitest';
|
|
13
13
|
import {act, renderHook} from '@testing-library/react';
|
|
14
14
|
import {
|
|
15
|
+
isInsideNestedLayer,
|
|
15
16
|
useSheetGestures,
|
|
16
17
|
type UseSheetGesturesOptions,
|
|
17
18
|
} from './useSheetGestures';
|
|
@@ -106,6 +107,27 @@ function up(hook: Hook, y: number, t: number, target: HTMLElement) {
|
|
|
106
107
|
);
|
|
107
108
|
}
|
|
108
109
|
|
|
110
|
+
describe('isInsideNestedLayer', () => {
|
|
111
|
+
it("is true for a target inside a <dialog> rendered within the body, and false for the body's own content", () => {
|
|
112
|
+
const body = document.createElement('div');
|
|
113
|
+
const own = document.createElement('button');
|
|
114
|
+
body.append(own);
|
|
115
|
+
const nested = document.createElement('dialog');
|
|
116
|
+
const nestedHandle = document.createElement('div');
|
|
117
|
+
nested.append(nestedHandle);
|
|
118
|
+
body.append(nested);
|
|
119
|
+
expect(isInsideNestedLayer(own, body)).toBe(false);
|
|
120
|
+
expect(isInsideNestedLayer(body, body)).toBe(false);
|
|
121
|
+
expect(isInsideNestedLayer(nestedHandle, body)).toBe(true);
|
|
122
|
+
expect(isInsideNestedLayer(nested, body)).toBe(true);
|
|
123
|
+
// A dialog above the body (the sheet's own) does not count.
|
|
124
|
+
const ownDialog = document.createElement('dialog');
|
|
125
|
+
ownDialog.append(body);
|
|
126
|
+
expect(isInsideNestedLayer(own, body)).toBe(false);
|
|
127
|
+
expect(isInsideNestedLayer(null, body)).toBe(false);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
|
|
109
131
|
describe('useSheetGestures', () => {
|
|
110
132
|
it('dismisses on a fast downward flick (swipe-to-close)', () => {
|
|
111
133
|
const {hook, onDismiss} = setup({snapHeights: () => [200]});
|
|
@@ -1213,6 +1235,36 @@ describe('useSheetGestures', () => {
|
|
|
1213
1235
|
expect(hook.result.current.isDragging).toBe(true);
|
|
1214
1236
|
});
|
|
1215
1237
|
|
|
1238
|
+
it('leaves a touch that starts inside a nested <dialog> to that layer', () => {
|
|
1239
|
+
// A sheet opened from this sheet's content renders its <dialog> inside
|
|
1240
|
+
// the body, so its touches bubble here. The same pull-down from the
|
|
1241
|
+
// body's own content promotes (see above); from the nested layer it
|
|
1242
|
+
// must not.
|
|
1243
|
+
const {hook} = setup({snapHeights: () => [200]});
|
|
1244
|
+
const {body} = makeNested({
|
|
1245
|
+
bodyScrollTop: 0,
|
|
1246
|
+
innerScrollTop: 0,
|
|
1247
|
+
innerScrollHeight: 200,
|
|
1248
|
+
});
|
|
1249
|
+
const nested = document.createElement('dialog');
|
|
1250
|
+
const nestedHandle = document.createElement('div');
|
|
1251
|
+
nested.appendChild(nestedHandle);
|
|
1252
|
+
body.appendChild(nested);
|
|
1253
|
+
act(() => hook.result.current.sheetRef(body));
|
|
1254
|
+
act(() => hook.result.current.bodyProps.ref(body));
|
|
1255
|
+
let start: Event | undefined;
|
|
1256
|
+
let pull: Event | undefined;
|
|
1257
|
+
act(() => {
|
|
1258
|
+
start = touchOn(nestedHandle, body, 'touchstart', 100);
|
|
1259
|
+
pull = touchOn(nestedHandle, body, 'touchmove', 160);
|
|
1260
|
+
});
|
|
1261
|
+
expect(start?.defaultPrevented).toBe(false);
|
|
1262
|
+
expect(pull?.defaultPrevented).toBe(false);
|
|
1263
|
+
expect(hook.result.current.isDragging).toBe(false);
|
|
1264
|
+
expect(liveOffset(hook)).toBe(0);
|
|
1265
|
+
expect(body.style.transform).toBe('');
|
|
1266
|
+
});
|
|
1267
|
+
|
|
1216
1268
|
it('leaves a pull-up to a nested scroller with content below', () => {
|
|
1217
1269
|
const {hook} = setup({snapHeights: () => [200]});
|
|
1218
1270
|
const {body, tile} = makeNested({bodyScrollTop: 0, innerScrollTop: 100});
|
|
@@ -235,6 +235,33 @@ function isBlockScroller(element: HTMLElement): boolean {
|
|
|
235
235
|
return overflowY === 'auto' || overflowY === 'scroll';
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
+
/**
|
|
239
|
+
* Whether a gesture that lands on `target` began inside another layer
|
|
240
|
+
* rendered in this sheet's content — a `<dialog>` between the target and the
|
|
241
|
+
* body. A sheet opened from inside a sheet's content, a Dialog opened there,
|
|
242
|
+
* renders its dialog as a descendant of the host's body, so its pointer and
|
|
243
|
+
* touch events bubble through the host's gesture listeners. That gesture is
|
|
244
|
+
* the layer's own: the host must neither arm a drag on it nor take pointer
|
|
245
|
+
* capture for it, which would cancel the drag the layer's own handle began
|
|
246
|
+
* (`component:BottomSheet` FR7: a swipe reaches only the top sheet of a
|
|
247
|
+
* stack; FR6: a covered sheet is blocked).
|
|
248
|
+
*/
|
|
249
|
+
export function isInsideNestedLayer(
|
|
250
|
+
target: EventTarget | null,
|
|
251
|
+
body: HTMLElement,
|
|
252
|
+
): boolean {
|
|
253
|
+
for (
|
|
254
|
+
let element = target instanceof Element ? target : null;
|
|
255
|
+
element != null && element !== body;
|
|
256
|
+
element = element.parentElement
|
|
257
|
+
) {
|
|
258
|
+
if (element.localName === 'dialog') {
|
|
259
|
+
return true;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
|
|
238
265
|
/**
|
|
239
266
|
* The scrollers a gesture that lands on `target` can scroll, innermost first
|
|
240
267
|
* and the body last: every scrollable box between the target and the body,
|
|
@@ -1328,10 +1355,13 @@ export function useSheetGestures({
|
|
|
1328
1355
|
if (event.button !== 0 || !event.isPrimary) {
|
|
1329
1356
|
return;
|
|
1330
1357
|
}
|
|
1331
|
-
const
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1358
|
+
const body = event.currentTarget as HTMLElement;
|
|
1359
|
+
// A gesture inside a layer this sheet hosts belongs to that layer.
|
|
1360
|
+
if (isInsideNestedLayer(event.target, body)) {
|
|
1361
|
+
armedBodyRef.current = null;
|
|
1362
|
+
return;
|
|
1363
|
+
}
|
|
1364
|
+
const scrollers = scrollChainUnder(event.target, body);
|
|
1335
1365
|
if (!chainAtTop(scrollers)) {
|
|
1336
1366
|
armedBodyRef.current = null;
|
|
1337
1367
|
return;
|
|
@@ -1465,8 +1495,9 @@ export function useSheetGestures({
|
|
|
1465
1495
|
// At the top, a pull DOWN hands off (collapse); at the bottom, a pull UP
|
|
1466
1496
|
// hands off (expand). A gesture that starts mid-content is an ordinary
|
|
1467
1497
|
// scroll, but it is tracked all the same: the scroller can run out of
|
|
1468
|
-
// content while the finger is still down (see onTouchMove).
|
|
1469
|
-
|
|
1498
|
+
// content while the finger is still down (see onTouchMove). A touch
|
|
1499
|
+
// inside a layer this sheet hosts is that layer's, never tracked here.
|
|
1500
|
+
if (!touch || isInsideNestedLayer(event.target, body)) {
|
|
1470
1501
|
touchDragRef.current = null;
|
|
1471
1502
|
return;
|
|
1472
1503
|
}
|
|
@@ -97,15 +97,27 @@ async function runState(
|
|
|
97
97
|
});
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
100
|
+
// Checking coverage runs every state again, which on a loaded runner nears
|
|
101
|
+
// the per-test timeout as one test. It runs as one serial part per state,
|
|
102
|
+
// sharing their results, then one check over all of them.
|
|
103
|
+
test.describe('every Breadcrumb expectation is exercised by at least one state', () => {
|
|
104
|
+
test.describe.configure({mode: 'serial'});
|
|
104
105
|
const results: BindingResult[] = [];
|
|
106
|
+
|
|
105
107
|
for (const state of BREADCRUMB_A11Y_STATES) {
|
|
106
|
-
|
|
108
|
+
test(`runs ${state.id}`, async ({page}) => {
|
|
109
|
+
const cdp = await page.context().newCDPSession(page);
|
|
110
|
+
results.push(await runState(page, cdp, state));
|
|
111
|
+
});
|
|
107
112
|
}
|
|
108
|
-
|
|
113
|
+
|
|
114
|
+
test('no expectation is left unexercised', () => {
|
|
115
|
+
// Every part ran in this worker; this test alone proves nothing.
|
|
116
|
+
expect(results.map(result => result.state).sort()).toEqual(
|
|
117
|
+
BREADCRUMB_A11Y_STATES.map(state => state.id).sort(),
|
|
118
|
+
);
|
|
119
|
+
expect(neverExercised(results)).toEqual([]);
|
|
120
|
+
});
|
|
109
121
|
});
|
|
110
122
|
|
|
111
123
|
for (const state of BREADCRUMB_A11Y_STATES) {
|
package/src/Button/Button.tsx
CHANGED
|
@@ -43,8 +43,8 @@ import {
|
|
|
43
43
|
shadowVars,
|
|
44
44
|
focusVars,
|
|
45
45
|
} from '../theme/tokens.stylex';
|
|
46
|
-
import {Spinner} from '../Spinner';
|
|
47
|
-
import {VisuallyHidden} from '../VisuallyHidden';
|
|
46
|
+
import {Spinner} from '../Spinner/Spinner';
|
|
47
|
+
import {VisuallyHidden} from '../VisuallyHidden/VisuallyHidden';
|
|
48
48
|
import {IconDefaultSizeProvider} from '../Icon/IconDefaultSizeContext';
|
|
49
49
|
import {iconBoxSizeStyles, type IconSize} from '../Icon/IconSize.stylex';
|
|
50
50
|
|
|
@@ -57,7 +57,7 @@ import {
|
|
|
57
57
|
groupStyles as inputGroupStyles,
|
|
58
58
|
inputGroupItemProps,
|
|
59
59
|
} from '../InputGroup/groupStyles';
|
|
60
|
-
import {mergeProps} from '../utils';
|
|
60
|
+
import {mergeProps} from '../utils/mergeProps';
|
|
61
61
|
import {useMergedRefs} from '../hooks/useMergedRefs';
|
|
62
62
|
import {useLinkComponent} from '../Link/useLinkComponent';
|
|
63
63
|
import type {LinkComponentType} from '../Link/types';
|
|
@@ -65,7 +65,7 @@ import {themeProps} from '../utils/themeProps';
|
|
|
65
65
|
import {focusOutlineProps} from '../utils/focusOutline.stylex';
|
|
66
66
|
import {interactionOverlayStyles} from '../utils/interactionOverlay.stylex';
|
|
67
67
|
import {usePressFeedback} from '../hooks/usePressFeedback';
|
|
68
|
-
import {useTranslator} from '../i18n';
|
|
68
|
+
import {useTranslator} from '../i18n/useTranslator';
|
|
69
69
|
import type {ButtonVariantMap} from './index';
|
|
70
70
|
|
|
71
71
|
/**
|
|
@@ -3,45 +3,48 @@ schema_version: 3
|
|
|
3
3
|
template_version: 7
|
|
4
4
|
kind: component
|
|
5
5
|
id: component:Calendar
|
|
6
|
-
authority:
|
|
6
|
+
authority: current
|
|
7
7
|
archive_reason: null
|
|
8
8
|
superseded_by: null
|
|
9
|
-
approved_by:
|
|
10
|
-
approved_at:
|
|
9
|
+
approved_by: cixzhang
|
|
10
|
+
approved_at: 2026-10-31
|
|
11
11
|
owners: [cixzhang]
|
|
12
12
|
review_triggers: [public-api, behavior, accessibility, theming]
|
|
13
13
|
verified_by:
|
|
14
14
|
[
|
|
15
15
|
packages/core/src/Calendar/Calendar.test.tsx,
|
|
16
16
|
packages/core/src/hooks/useGridFocus.test.tsx,
|
|
17
|
+
packages/core/src/Calendar/__tests__/Calendar.a11y.test.tsx,
|
|
18
|
+
packages/core/src/Calendar/__tests__/Calendar.a11y.chromium.spec.ts,
|
|
17
19
|
scripts/check-knowledge.mjs,
|
|
18
20
|
]
|
|
19
21
|
modules: []
|
|
20
22
|
families: []
|
|
21
|
-
design_specs: []
|
|
23
|
+
design_specs: [design:bidirectionality, design:reduced-motion]
|
|
22
24
|
architecture:
|
|
23
25
|
[
|
|
26
|
+
architecture:internationalization,
|
|
24
27
|
architecture:public-component-api,
|
|
25
28
|
architecture:component-theming-surface,
|
|
26
29
|
architecture:react-component-runtime,
|
|
27
30
|
]
|
|
28
31
|
contributing: []
|
|
29
|
-
system_specs: [spec:AST-020/FR15]
|
|
32
|
+
system_specs: [spec:AST-020/FR15, spec:AST-085, spec:AST-102]
|
|
30
33
|
---
|
|
31
34
|
|
|
32
35
|
# Calendar component contract
|
|
33
36
|
|
|
34
37
|
## Contract at a glance
|
|
35
38
|
|
|
36
|
-
| Area | Contract
|
|
37
|
-
| ----------------------- |
|
|
38
|
-
| Public contract | None changes. `Calendar` and `CalendarProps` are exported from `@astryxdesign/core/Calendar`; `mode` selects a single date or a range, with `value`/`defaultValue`/`onChange`, bounds, constraints, span limits, focus date, and display options.
|
|
39
|
-
| Behavior | One or two months render as day grids; a day is picked by pointer or keyboard; each month grid holds at most one roving Tab stop, which arrow, Home/End, and Page keys move, following the reading direction.
|
|
40
|
-
| End-user impact | A keyboard or screen-reader user meets a named month grid, moves through it by day, week, and month, and hears each day's name, selection, today marker, and disabled state.
|
|
41
|
-
| Builder impact | None.
|
|
42
|
-
| Compatibility/readiness |
|
|
43
|
-
| Review checks | Reject a day grid without `role="grid"` or a name, two days in one month holding a Tab stop, an arrow key that stops following the reading direction, or a selection or today state carried only by colour.
|
|
44
|
-
| Governing rules | `architecture:public-component-api/INV1,INV5–INV8`; `architecture:component-theming-surface/INV3–INV7`; `spec:AST-020/FR15
|
|
39
|
+
| Area | Contract |
|
|
40
|
+
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
41
|
+
| Public contract | None changes. `Calendar` and `CalendarProps` are exported from `@astryxdesign/core/Calendar`; `mode` selects a single date or a range, with `value`/`defaultValue`/`onChange`, bounds, constraints, span limits, focus date, and display options. |
|
|
42
|
+
| Behavior | One or two months render as day grids; a day is picked by pointer or keyboard; each month grid holds at most one roving Tab stop, which arrow, Home/End, and Page keys move, following the reading direction. |
|
|
43
|
+
| End-user impact | A keyboard or screen-reader user meets a named month grid, moves through it by day, week, and month, and hears each day's name, selection, today marker, and disabled state. |
|
|
44
|
+
| Builder impact | None. |
|
|
45
|
+
| Compatibility/readiness | Records shipped behavior; no API, default, or DOM change. The month buttons use native `disabled` at a bound and scale under reduced motion, day buttons hold a fixed size, day and week numbers use ASCII digits, and a key-moved Tab stop can go stale; all are listed under Current-state impact. |
|
|
46
|
+
| Review checks | Reject a day grid without `role="grid"` or a name, two days in one month holding a Tab stop, an arrow key that stops following the reading direction, or a selection or today state carried only by colour. |
|
|
47
|
+
| Governing rules | `architecture:public-component-api/INV1,INV5–INV8`; `architecture:component-theming-surface/INV3–INV7`; `spec:AST-020/FR15`; `spec:AST-085/FR1, FR4`; `spec:AST-102` FR4; `design:bidirectionality` DR6; `design:reduced-motion` DR1; `architecture:internationalization` INV8. |
|
|
45
48
|
|
|
46
49
|
This table is a review projection; the body below is authoritative.
|
|
47
50
|
|
|
@@ -54,10 +57,10 @@ keyboard model that moves through days; date fields compose it.
|
|
|
54
57
|
## Compatibility and migration
|
|
55
58
|
|
|
56
59
|
- Released default preserved: `yes`
|
|
57
|
-
- Compatibility class:
|
|
58
|
-
|
|
59
|
-
- Controlled/uncontrolled behavior:
|
|
60
|
-
|
|
60
|
+
- Compatibility class: records shipped behavior; no public prop, default,
|
|
61
|
+
export, or DOM change
|
|
62
|
+
- Controlled/uncontrolled behavior: `value` with `onChange` is controlled;
|
|
63
|
+
`defaultValue` starts internal state
|
|
61
64
|
- Migration decision: none
|
|
62
65
|
|
|
63
66
|
Consumer migration instructions belong in consumer docs and release notes.
|
|
@@ -74,8 +77,11 @@ Consumer migration instructions belong in consumer docs and release notes.
|
|
|
74
77
|
**Does not own / non-goals**
|
|
75
78
|
|
|
76
79
|
- The text field, popover, and bottom sheet that present a Calendar — owned by
|
|
77
|
-
|
|
78
|
-
- Time of day — owned by
|
|
80
|
+
DateInput and its siblings.
|
|
81
|
+
- Time of day — owned by DateTimeInput.
|
|
82
|
+
- `handleRef`, `onFocusDateChange`, the opening month inside the `min`/`max`
|
|
83
|
+
window, `weekStartsOn`, and `numberOfMonths` clamping — shipped and covered
|
|
84
|
+
by the consumer docs and tests, uncontracted here beyond FR1–FR7.
|
|
79
85
|
|
|
80
86
|
## Public concepts
|
|
81
87
|
|
|
@@ -87,16 +93,15 @@ Consumer migration instructions belong in consumer docs and release notes.
|
|
|
87
93
|
|
|
88
94
|
## Behavioral and layout contract
|
|
89
95
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
|
94
|
-
|
|
|
95
|
-
|
|
|
96
|
-
|
|
|
97
|
-
|
|
|
98
|
-
|
|
|
99
|
-
| FR5 | Moving the focused day across a month boundary navigates the visible month so the focused day stays visible, in one month or two; a borrowed adjacent-month day is exposed `aria-disabled` and cannot be picked; arrow keys, Home and End skip it, and a page never lands on it. | shipped source and focused tests | verify |
|
|
96
|
+
| ID | Invariant | Basis |
|
|
97
|
+
| --- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------- |
|
|
98
|
+
| FR1 | Each rendered month is one `role="grid"` named for its month and year, with a `columnheader` per weekday (and, with week numbers, a named `columnheader` above the `rowheader` column) and one `row` per week. Month and year labels and day names come from the provider locale. Day and week numbers MUST use the locale's digits (`architecture:internationalization` INV8). Implementation gap: they render as ASCII digits in every locale. | shipped source and focused tests; `architecture:internationalization` INV8 |
|
|
99
|
+
| FR2 | At most one day button in each month's grid holds `tabIndex={0}`; every other day button in that grid is `-1`. Each day button is the shared `sm` element size (inside an `md`-sized cell) as a minimum that grows with a set text size (`spec:AST-102` FR4). Implementation gap: the day buttons hold a fixed size. | shipped `useGridFocus` behavior; `Calendar.test.tsx` single-Tab-stop assertion; `spec:AST-102` FR4 |
|
|
100
|
+
| FR3 | A disabled day (outside bounds or rejected by a constraint) stays in the grid, stays focusable with `aria-disabled` and no native `disabled`, never holds the grid's Tab stop, and cannot be picked. Implementation gap: once a key move (arrow, Home, End, or Page key) has placed the Tab stop, it stays on that day when every day of the month becomes disabled (for example a range span cap in a two-month view). | `spec:AST-085` FR1, FR2; shipped source and focused tests |
|
|
101
|
+
| FR4 | In `range` mode the first pick starts the range and the second ends it, a second pick before the start swapping the two so the end never precedes the start; `minRangeSpan`/`maxRangeSpan` bound it. Escape, or picking the start day again when `minRangeSpan` is above 1, clears an in-progress range. | shipped source and focused tests |
|
|
102
|
+
| FR5 | Moving the focused day across a month boundary navigates the visible month so the focused day stays visible, in one month or two; a borrowed adjacent-month day is exposed `aria-disabled` and cannot be picked; arrow keys, Home and End skip it, and a page never lands on it. | shipped source and focused tests |
|
|
103
|
+
| FR6 | The month header shows the month and year between Previous and Next month buttons (ghost, icon-only Buttons whose chevrons mirror under RTL), which carry `calendar-nav` with `data-nav` and `data-disabled`. A button whose direction would leave `min` or `max` MUST stay focusable with `aria-disabled`, change nothing, and keep focus (`spec:AST-085` FR1, FR4). Implementation gap: it is natively disabled, so a focused button that reaches the bound drops focus. The month buttons are `component:Button`s, so their press scale MUST NOT apply under reduced motion (`design:reduced-motion` DR1). Implementation gap: it still applies under reduced motion. | `spec:AST-085`; shipped source and focused tests; `design:reduced-motion` DR1 |
|
|
104
|
+
| FR7 | When the visible month changes, by the month buttons, a Page key, an arrow across a month edge, or the handle, the new month (both months in a two-month view) is announced politely; the first render and a pick that leaves the month in place announce nothing. In `range` mode the first pick announces the start and prompts for an end, the second announces the completed range in chronological order, and picking the start again when `minRangeSpan` is above 1 announces the cleared start; Escape clears an in-progress range without an announcement. Every announcement uses the provider locale. | shipped source and focused tests |
|
|
100
105
|
|
|
101
106
|
### Allowed variation
|
|
102
107
|
|
|
@@ -107,13 +112,13 @@ intentional decision. A `current` contract contains no unresolved rows.
|
|
|
107
112
|
|
|
108
113
|
### Representative states
|
|
109
114
|
|
|
110
|
-
| State | Required invariant
|
|
111
|
-
| ---------------------- |
|
|
112
|
-
| single, nothing picked | Today holds its month's Tab stop when it is enabled, otherwise the month's first enabled day does; no day is selected.
|
|
113
|
-
| single, picked | The selected day is exposed as selected and holds the Tab stop.
|
|
114
|
-
| range, in progress | The start is selected; hovered days preview the range.
|
|
115
|
-
| two months | Both grids are named; at most one Tab stop in each.
|
|
116
|
-
| bounded | Days outside `min`/`max` are disabled.
|
|
115
|
+
| State | Required invariant | Allowed variation |
|
|
116
|
+
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------- |
|
|
117
|
+
| single, nothing picked | Today holds its month's Tab stop when it is enabled, otherwise the month's first enabled day does; no day is selected. | Month shown. |
|
|
118
|
+
| single, picked | The selected day is exposed as selected and holds the Tab stop. Implementation gap: after a key move places the stop, a later pointer pick can leave it there, always when the picked day comes later in the grid. | Month shown. |
|
|
119
|
+
| range, in progress | The start is selected; hovered days preview the range. | Pointer position. |
|
|
120
|
+
| two months | Both grids are named; at most one Tab stop in each. | Which month is first. |
|
|
121
|
+
| bounded | Days outside `min`/`max` are disabled. | Which days. |
|
|
117
122
|
|
|
118
123
|
### Transformation and precedence order
|
|
119
124
|
|
|
@@ -124,7 +129,8 @@ intentional decision. A `current` contract contains no unresolved rows.
|
|
|
124
129
|
### Performance and resources
|
|
125
130
|
|
|
126
131
|
- **PR1 — Render-owned grid.** Day cells render from props and state; focus
|
|
127
|
-
movement reads the grid's cells on demand
|
|
132
|
+
movement reads the grid's cells on demand; day buttons share the press
|
|
133
|
+
controller's window and document listeners; Calendar owns no observer.
|
|
128
134
|
|
|
129
135
|
## Accessibility contract
|
|
130
136
|
|
|
@@ -132,12 +138,17 @@ intentional decision. A `current` contract contains no unresolved rows.
|
|
|
132
138
|
one composite control: each month is `role="grid"` with an accessible name,
|
|
133
139
|
weekday `columnheader` cells, week `row`s, and day `gridcell`s that carry
|
|
134
140
|
`aria-selected` when selected or in range and hold one `button` named by the
|
|
135
|
-
full date
|
|
141
|
+
full date plus its selection or range role (selected, range start, range end,
|
|
142
|
+
or in range), which exposes `aria-current="date"` for today and `aria-disabled`
|
|
136
143
|
when disabled; one day button holds the Tab stop — the selected day in
|
|
137
144
|
`single` mode when it is in that month and enabled, else today when it is in
|
|
138
145
|
that month and enabled, else the month's first enabled day; a month with no
|
|
139
|
-
enabled day has no Tab stop.
|
|
140
|
-
|
|
146
|
+
enabled day has no Tab stop. Implementation gap: once a key move (arrow, Home,
|
|
147
|
+
End, or Page key) has placed the stop, a later pointer pick can leave it
|
|
148
|
+
there (always when the picked day comes later in the grid), and when every
|
|
149
|
+
day of that month becomes disabled it stays on a disabled day.
|
|
150
|
+
ArrowLeft and ArrowRight move by a day following the reading direction
|
|
151
|
+
(`design:bidirectionality` DR6),
|
|
141
152
|
ArrowUp and ArrowDown by a week, Home and End to the first and last enabled day of the
|
|
142
153
|
week, PageUp and PageDown by a month, and Enter or Space picks the focused day;
|
|
143
154
|
an arrow skips a day disabled by a constraint and continues in the
|
|
@@ -149,10 +160,13 @@ intentional decision. A `current` contract contains no unresolved rows.
|
|
|
149
160
|
|
|
150
161
|
## Design relationships
|
|
151
162
|
|
|
163
|
+
`design:bidirectionality` DR6 governs the arrow-key direction (AR1), and
|
|
164
|
+
`design:reduced-motion` governs the month buttons' press scale (FR6).
|
|
165
|
+
|
|
152
166
|
| Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
|
|
153
167
|
| ---------------- | ---------------------------------------------------------------------- | ------------------------------ | -------------- | ------------------ |
|
|
154
168
|
| Calendar root | Holds the header and the grid; carries the component's theming target. | Current source and public docs | Supporting | FR1 |
|
|
155
|
-
| Month header | Names the month and offers previous/next navigation. | Current source and public docs | Supporting | FR1, FR5
|
|
169
|
+
| Month header | Names the month and offers previous/next navigation. | Current source and public docs | Supporting | FR1, FR5, FR6 |
|
|
156
170
|
| Day button | The control a date is picked with; carries the day target. | Current source and public docs | Prominent | FR2, FR3, AR1 |
|
|
157
171
|
| Day grid | Presents the weeks and days as a named grid. | Current source and public docs | Prominent | FR1, FR2, AR1 |
|
|
158
172
|
| Selected day | Marks the chosen day or range without relying on colour alone. | Current source and public docs | Prominent | FR4, AR1 |
|
|
@@ -185,18 +199,43 @@ button.
|
|
|
185
199
|
|
|
186
200
|
- `spec:AST-020/FR15` decides which APG parts a component adopts; the day grid
|
|
187
201
|
adopts the Grid pattern because it already acts as one composite control.
|
|
202
|
+
- `spec:AST-085` owns disabled focusability; days meet it and the month
|
|
203
|
+
buttons do not (FR6).
|
|
204
|
+
- `component:Button` renders the month buttons.
|
|
188
205
|
|
|
189
206
|
## Verification map
|
|
190
207
|
|
|
191
|
-
| Contract
|
|
192
|
-
|
|
|
193
|
-
| FR1–FR5
|
|
194
|
-
| AR1
|
|
208
|
+
| Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
|
|
209
|
+
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ |
|
|
210
|
+
| FR1–FR5 | `Calendar.test.tsx` structure ("renders a valid APG grid: one grid, header row of columnheaders inside it, week rows of gridcells", "with week numbers, the header row's corner cell is a named columnheader, so every row child is a grid cell"), selection ("handles reverse range selection (end before start)", "caps the range highlight next to a disabled mid-range day (#2715)", "Escape cancels range selection in progress", "clears the in-progress start when the anchor is clicked again"), bounds ("prev button is disabled when focusDate month contains min", "next button is disabled when focusDate month contains max"), and navigation ("navigates to next month", "calls onFocusDateChange when navigating") suites | single, range, two months, bounded | A missing header row, a reverse pick that does not swap, a range highlight that reaches a disabled day, or a Previous/Next button enabled past `min`/`max` fails. Evidence gap: no test asserts locale digits for day or week numbers. | `audit:Calendar/behavior` |
|
|
211
|
+
| AR1 | `Calendar.test.tsx` ("has accessible grid structure", "sets aria-multiselectable on both grids in a two-month range view", "does not set aria-multiselectable in single mode", "announces the new month politely when clicking next", "displays day names") and `useGridFocus.test.tsx` ("ArrowDown moves the tab stop one row down", "flips ArrowLeft/ArrowRight under RTL"); `Calendar.test.tsx` "ArrowUp skips a disabled cell in the same column to the next enabled row (complex-2)" for the disabled-day skip; `Calendar.test.tsx` Page-key cases ("moves the focused day by a month with PageDown and PageUp, into the month now shown", "pages from a borrowed adjacent-month day onto the real day in the month already shown", "an arrow past max changes nothing and leaves no pending target behind", "a page into a month with no enabled day changes nothing and keeps focus", "a page onto a day disabled by a constraint moves the month and focuses its first enabled day", "a page whose target lies past max changes nothing and keeps focus", "in a two-month view a boundary blocks only out-of-range targets, not month movement", "in a two-month view PageDown from the second month moves both months and a later Next click selects no stale day"); borrowed-day cases ("skips borrowed adjacent-month days and crosses into their month instead", "in a two-month view an arrow from the first month lands on the real day, never a borrowed one", "an arrow toward a direction where every remaining day is disabled changes nothing", "an arrow resolves the next enabled day in its direction first: weekdays-only ArrowRight from Friday January 30 reaches Monday February 2", "an arrow whose next day in range does not exist changes nothing: max January 25, ArrowDown from January 21"); the single-Tab-stop assertion in the AST-085 range-cap case (FR2). `Calendar.test.tsx` selection-state accessible-name cases ("appends 'selected' to the selected day's button name in single mode", "marks range start, end, and in-range days in their accessible names"). Evidence gap: no Calendar-level test of Home, End, Enter, or Space; no test covers the Tab stop after a key move followed by a pointer pick or a fully disabled month | LTR and RTL; month boundary; selected, today, disabled days | A day loses its role, name or state, two days in one month hold a Tab stop, or an arrow, Home/End, Page or activation key stops moving or picking. | `audit:Calendar/accessibility` |
|
|
212
|
+
| FR6 | `Calendar.test.tsx` navigation, bound, theming-target ("renders the astryx-calendar-nav target on both month-nav buttons", "reflects the disabled nav state as a data attribute at the range edges", "keeps the default nav rendering unchanged (still a ghost icon button)"), and RTL month-navigation cases | Previous and Next; at `min` and `max`; `dir="rtl"` | A button enabled past a bound, a missing `calendar-nav` target or state attribute, or a lost shared chevron wrapper fails. Evidence gap: no test asserts focus kept at a bound (the FR6 gap), the mirrored chevron pixels, or the press under reduced motion. | `audit:Calendar/behavior` |
|
|
213
|
+
| FR7 | `Calendar.test.tsx` month-change announcement cases ("does not announce on initial render", "announces the new month politely when clicking next", "announces the next month when paging the grid with PageDown", "announces both months in a two-month view", "does not announce when selecting a date leaves the visible month unchanged") and range announcement cases ("announces the start pick and prompts for an end date", "announces the completed range in chronological order for a reverse pick") | Month buttons, Page keys, handle; single and two months; range start, complete, cleared | A missing, extra, or out-of-order announcement fails. Evidence gap: no test reaches the cleared-start announcement (the cleared-range case sets no `minRangeSpan`). | `audit:Calendar/accessibility` |
|
|
214
|
+
| FR2 (size) | Evidence gap: no test asserts day-button size or text growth | — | — | `audit:Calendar/layout` |
|
|
215
|
+
| AR1 (browser) | `Calendar.a11y.test.tsx` and `Calendar.a11y.chromium.spec.ts` over the shared grid states | Every representative state | A lost grid name, role, or start neighbourhood fails; browser-owned outcomes are reported. | `audit:Calendar/accessibility` |
|
|
216
|
+
| ORD1, ORD2, PR1 | ORD1 and ORD2 are covered by the FR3–FR5 and AR1 rows. Evidence gap: no test asserts the absence of per-cell listeners | — | — | `audit:Calendar/behavior` |
|
|
217
|
+
|
|
218
|
+
## Current-state impact
|
|
219
|
+
|
|
220
|
+
- **Day and week digits (FR1).** Day and week numbers render as ASCII digits
|
|
221
|
+
in every locale, while month labels follow the locale, against
|
|
222
|
+
`architecture:internationalization` INV8.
|
|
223
|
+
- **Stale Tab stop (FR3, AR1).** After a key move places the Tab stop, a later
|
|
224
|
+
pointer pick can leave it there (always when the picked day comes later in
|
|
225
|
+
the grid), and when every day of that month becomes disabled it stays on a
|
|
226
|
+
disabled day, so Tab can land on an unselected or disabled day.
|
|
227
|
+
- **Month buttons under reduced motion (FR6).** The Previous and Next buttons
|
|
228
|
+
scale on a press when the person prefers reduced motion, as `component:Button`
|
|
229
|
+
FR15 records, against `design:reduced-motion` DR1.
|
|
230
|
+
- **Fixed day size (FR2).** Day buttons hold a fixed size instead of growing
|
|
231
|
+
with a set text size, against `spec:AST-102` FR4.
|
|
232
|
+
- **Month buttons at a bound (FR6).** Previous and Next become natively
|
|
233
|
+
disabled at `min` and `max`, so a keyboard user on the button that reaches the
|
|
234
|
+
bound loses focus, against `spec:AST-085` FR1 and FR4.
|
|
195
235
|
|
|
196
236
|
## Decision log
|
|
197
237
|
|
|
198
|
-
|
|
199
|
-
rule rather than a component-local decision.
|
|
238
|
+
No component-local decision. The Grid adoption follows `spec:AST-020/FR15`.
|
|
200
239
|
|
|
201
240
|
## Open questions
|
|
202
241
|
|
|
@@ -101,16 +101,30 @@ async function runState(
|
|
|
101
101
|
});
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
104
|
+
// Checking coverage runs every state again, which on a loaded runner nears
|
|
105
|
+
// the per-test timeout as one test. It runs as one serial part per state,
|
|
106
|
+
// sharing their results, then one check over all of them.
|
|
107
|
+
test.describe('every grid expectation is exercised by a Calendar state', () => {
|
|
108
|
+
test.describe.configure({mode: 'serial'});
|
|
108
109
|
const results: BindingResult[] = [];
|
|
110
|
+
|
|
109
111
|
for (const state of CALENDAR_BINDING_STATES) {
|
|
110
|
-
|
|
112
|
+
test(`runs ${state.id}`, async ({page}) => {
|
|
113
|
+
const cdp = await page.context().newCDPSession(page);
|
|
114
|
+
results.push(await runState(page, cdp, state));
|
|
115
|
+
});
|
|
111
116
|
}
|
|
112
|
-
|
|
113
|
-
|
|
117
|
+
|
|
118
|
+
test('no expectation is left unexercised', () => {
|
|
119
|
+
// Every part ran in this worker; this test alone proves nothing.
|
|
120
|
+
expect(results.map(result => result.state).sort()).toEqual(
|
|
121
|
+
CALENDAR_BINDING_STATES.map(state => state.id).sort(),
|
|
122
|
+
);
|
|
123
|
+
expect(neverExercised(results)).toEqual([]);
|
|
124
|
+
expect(unmatchedKnownFailures(CALENDAR_KNOWN_FAILURES, results)).toEqual(
|
|
125
|
+
[],
|
|
126
|
+
);
|
|
127
|
+
});
|
|
114
128
|
});
|
|
115
129
|
|
|
116
130
|
for (const state of CALENDAR_BINDING_STATES) {
|