@astryxdesign/core 0.7.5 → 0.7.6-canary.bb18c81
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/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/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +4 -1
- package/dist/DateInput/MonthScroller.d.ts.map +1 -1
- package/dist/DateInput/MonthScroller.js +101 -15
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +1 -1
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +4 -1
- 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.map +1 -1
- package/dist/Drawer/Drawer.js +5 -0
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +4 -1
- package/dist/DropdownMenu/MenuBottomSheetActionList.d.ts.map +1 -1
- package/dist/DropdownMenu/MenuBottomSheetActionList.js +6 -5
- package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts +10 -1
- package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts.map +1 -1
- package/dist/DropdownMenu/lazyMenuBottomSheet.js +16 -2
- 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/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/MultiSelector.d.ts +1 -1
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +5 -2
- 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/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/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +7 -1
- package/dist/Spinner/Spinner.js +2 -2
- 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/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +2 -2
- package/dist/Timestamp/TimestampHoverCard.js +4 -4
- 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/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 +14 -1
- package/dist/gestures/PinchGestureRecognizer.d.ts +30 -0
- package/dist/gestures/PinchGestureRecognizer.d.ts.map +1 -0
- package/dist/gestures/PinchGestureRecognizer.js +125 -0
- package/dist/gestures/ScreenEdgePanGestureRecognizer.d.ts +70 -0
- package/dist/gestures/ScreenEdgePanGestureRecognizer.d.ts.map +1 -0
- package/dist/gestures/ScreenEdgePanGestureRecognizer.js +220 -0
- package/dist/gestures/SwipeGestureRecognizer.d.ts +36 -0
- package/dist/gestures/SwipeGestureRecognizer.d.ts.map +1 -0
- package/dist/gestures/SwipeGestureRecognizer.js +145 -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/types.d.ts +11 -7
- package/dist/gestures/types.d.ts.map +1 -1
- package/dist/gestures/types.js +22 -2
- package/dist/hooks/useAdaptivePresentation.d.ts.map +1 -1
- package/dist/hooks/useAdaptivePresentation.js +4 -1
- 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 +3 -0
- package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/pseudo.generated.js +3 -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.js +1 -1
- 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/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/presentation.d.ts +50 -0
- package/dist/utils/presentation.d.ts.map +1 -0
- package/dist/utils/presentation.js +125 -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/locales/en.json +13 -1
- package/locales/pseudo.json +9 -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/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/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/ContextMenu/ContextMenu.test.tsx +35 -0
- package/src/DateInput/DateInput.test.tsx +53 -2
- package/src/DateInput/DateInput.tsx +15 -11
- package/src/DateInput/MonthScroller.tsx +106 -20
- package/src/DateInput/MonthScrollerSettle.test.tsx +165 -0
- 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.spec.md +71 -48
- package/src/DateTimeInput/DateTimeInput.test.tsx +61 -0
- package/src/DateTimeInput/DateTimeInput.tsx +15 -11
- 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 +22 -0
- package/src/Drawer/Drawer.tsx +5 -0
- package/src/Drawer/DrawerHeader.spec.md +181 -0
- package/src/DropdownMenu/DropdownMenu.test.tsx +41 -0
- package/src/DropdownMenu/DropdownMenu.tsx +7 -1
- 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 +53 -0
- package/src/DropdownMenu/lazyMenuBottomSheet.ts +23 -6
- 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/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.tsx +3 -3
- 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/MultiSelector.spec.md +7 -4
- package/src/MultiSelector/MultiSelector.test.tsx +118 -1
- package/src/MultiSelector/MultiSelector.tsx +6 -2
- 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/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/Slider/Slider.test.tsx +12 -0
- package/src/Slider/Slider.tsx +4 -1
- package/src/Slider/__tests__/Slider.a11y.chromium.spec.ts +19 -7
- package/src/Spinner/Spinner.tsx +2 -2
- package/src/Stack/Stack.tsx +1 -1
- package/src/Stack/StackItem.tsx +1 -1
- package/src/TabList/TabList.test.tsx +52 -1
- 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/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 +7 -10
- package/src/Toast/ToastViewport.test.tsx +575 -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/Typeahead/Typeahead.test.tsx +40 -0
- package/src/Typeahead/Typeahead.tsx +12 -1
- package/src/gestures/PinchGestureRecognizer.ts +144 -0
- package/src/gestures/ScreenEdgePanGestureRecognizer.ts +252 -0
- package/src/gestures/SwipeGestureRecognizer.ts +193 -0
- package/src/gestures/VelocityTracker.ts +10 -3
- 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__/arenaPinchSwipeEdge.test.ts +188 -0
- package/src/gestures/__tests__/harness.ts +21 -2
- package/src/gestures/types.ts +23 -9
- package/src/hooks/useAdaptivePresentation.ts +4 -1
- package/src/hooks/useMenuHover.ts +15 -1
- package/src/i18n/generated-locales/en.generated.ts +4 -0
- package/src/i18n/generated-locales/pseudo.generated.ts +4 -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/defineTheme.ts +1 -1
- 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/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/presentation.test.ts +380 -0
- package/src/utils/presentation.ts +180 -0
- package/src/utils/pressPaintPriority.test.ts +80 -0
- package/src/utils/touchPresentation.stylex.ts +43 -0
- package/src/utils/touchPresentation.test.ts +140 -1
- package/src/utils/touchPresentation.ts +5 -3
|
@@ -3,11 +3,11 @@ schema_version: 3
|
|
|
3
3
|
template_version: 7
|
|
4
4
|
kind: component
|
|
5
5
|
id: component:CollapsibleGroup
|
|
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, imdreamrunner]
|
|
12
12
|
review_triggers: [public-api, behavior, layout, accessibility, theming]
|
|
13
13
|
verified_by:
|
|
@@ -17,6 +17,8 @@ verified_by:
|
|
|
17
17
|
packages/core/src/Collapsible/__tests__/Collapsible.a11y.test.tsx,
|
|
18
18
|
packages/core/src/Collapsible/__tests__/Collapsible.a11y.chromium.spec.ts,
|
|
19
19
|
packages/core/src/Collapsible/__tests__/CollapsibleGroup.a11y.chromium.spec.ts,
|
|
20
|
+
packages/core/src/Collapsible/__tests__/CollapsibleGroup.a11y.test.tsx,
|
|
21
|
+
packages/core/src/Collapsible/__tests__/CollapsibleGroupAccordion.a11y.chromium.spec.ts,
|
|
20
22
|
packages/core/src/theme/themingTargets.test.ts,
|
|
21
23
|
apps/storybook/stories/CollapsibleGroup.stories.tsx,
|
|
22
24
|
]
|
|
@@ -31,7 +33,7 @@ architecture:
|
|
|
31
33
|
architecture:component-test-sufficiency,
|
|
32
34
|
]
|
|
33
35
|
contributing: [contributing:api-conventions]
|
|
34
|
-
system_specs: [spec:AST-029]
|
|
36
|
+
system_specs: [spec:AST-029, spec:AST-085]
|
|
35
37
|
---
|
|
36
38
|
|
|
37
39
|
# CollapsibleGroup component contract
|
|
@@ -44,11 +46,11 @@ system_specs: [spec:AST-029]
|
|
|
44
46
|
| Behavior | Direct children with a `value` read group state; opening an item replaces or extends the open-value set according to mode. The group renders no wrapper unless divider chrome is enabled. |
|
|
45
47
|
| End-user impact | People can reveal one section or several sections without disclosure state drifting between sibling rows; divided groups keep one coherent visual and directional treatment. |
|
|
46
48
|
| Builder impact | Builders choose state ownership and selection mode, give participating items stable values, and may opt into divided-row presentation. |
|
|
47
|
-
| Compatibility/readiness |
|
|
49
|
+
| Compatibility/readiness | Records shipped behavior; no public change. Three implementation gaps, listed under Current-state impact. |
|
|
48
50
|
| Review checks | Reject lost single/multiple coordination, controlled state that mutates internally, uncontrolled state that stops updating, presentation leakage into nested disclosures, or a wrapper appearing when dividers are absent. |
|
|
49
51
|
| Governing rules | `component:Collapsible/FR7–FR9,DEC-2`; `architecture:public-component-api/INV1,INV5–INV9`; `architecture:react-component-runtime/INV1,INV8–INV9`; `architecture:component-theming-surface/INV3–INV7`. |
|
|
50
52
|
|
|
51
|
-
This table is a review projection; the body below is authoritative
|
|
53
|
+
This table is a review projection; the body below is authoritative.
|
|
52
54
|
|
|
53
55
|
## Intent
|
|
54
56
|
|
|
@@ -57,12 +59,29 @@ Coordinate a set of disclosure items so their open state follows one group owner
|
|
|
57
59
|
## Compatibility and migration
|
|
58
60
|
|
|
59
61
|
- Released default preserved: yes
|
|
60
|
-
- Compatibility class:
|
|
62
|
+
- Compatibility class: records shipped behavior; no public change
|
|
61
63
|
- Controlled/uncontrolled behavior: unchanged
|
|
62
64
|
- Migration decision: none
|
|
63
65
|
|
|
64
66
|
Consumer migration instructions belong in consumer docs and release notes.
|
|
65
67
|
|
|
68
|
+
## Current-state impact
|
|
69
|
+
|
|
70
|
+
- **A disabled header leaves the Tab order.** A disabled direct item's header
|
|
71
|
+
carries `aria-disabled` but drops out of the Tab order, so a keyboard user
|
|
72
|
+
cannot reach it to learn why it is unavailable. `spec:AST-085` FR1 keeps a
|
|
73
|
+
disabled control focusable; the header is owned by `component:Collapsible`.
|
|
74
|
+
- **Equal values can rebuild the coordination context.** An equal new
|
|
75
|
+
controlled array, or a new `onChange` such as an inline handler, rebuilds the
|
|
76
|
+
coordination context on every parent render, so memoized direct items
|
|
77
|
+
re-render. `architecture:react-component-runtime` INV9 keeps an unchanged
|
|
78
|
+
payload from broadcasting a new identity (FR7).
|
|
79
|
+
- **The accordion binding runs adopted rows as advisory.** The binding runs
|
|
80
|
+
the header-to-header Tab step, single-mode sibling collapse, and no
|
|
81
|
+
arrow-key movement as advisory rows, so
|
|
82
|
+
a regression there does not fail the binding lane. `spec:AST-020` FR9 makes
|
|
83
|
+
an adopted expectation required once this record adopts it (AR4).
|
|
84
|
+
|
|
66
85
|
## Ownership boundary
|
|
67
86
|
|
|
68
87
|
**Owns**
|
|
@@ -90,15 +109,15 @@ Consumer migration instructions belong in consumer docs and release notes.
|
|
|
90
109
|
|
|
91
110
|
## Behavioral and layout contract
|
|
92
111
|
|
|
93
|
-
| ID |
|
|
94
|
-
| --- |
|
|
95
|
-
| FR1 | In `single` mode, toggling a closed direct item MUST replace the open-value set with that item, and toggling the open item MUST clear the set.
|
|
96
|
-
| FR2 | In `multiple` mode, toggling a direct item MUST add or remove only that value while preserving the state of other values.
|
|
97
|
-
| FR3 | Supplying `value` MUST keep state caller-owned and report requested changes through `onChange`; omitting it MUST keep state internal after initialization from `defaultValue`.
|
|
98
|
-
| FR4 | A direct `Collapsible` with a `value` MUST use group coordination; an item without a value MUST retain standalone ownership.
|
|
99
|
-
| FR5 | With `hasDividers=false`, the group MUST add no DOM wrapper. With dividers enabled it MUST render one wrapper that receives documented root props and the `collapsible-group` target.
|
|
100
|
-
| FR6 | Density, divider, and chevron defaults MUST reach direct items without leaking through a direct item's revealed content into nested independent disclosures.
|
|
101
|
-
| FR7 | Presentation context identity MUST remain stable while divider, density, and chevron inputs are unchanged; coordination identity MUST
|
|
112
|
+
| ID | Invariant | Basis |
|
|
113
|
+
| --- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
|
|
114
|
+
| FR1 | In `single` mode, toggling a closed direct item MUST replace the open-value set with that item, and toggling the open item MUST clear the set. | shipped source, consumer docs, and focused interaction tests |
|
|
115
|
+
| FR2 | In `multiple` mode, toggling a direct item MUST add or remove only that value while preserving the state of other values. | shipped source, consumer docs, and focused interaction tests |
|
|
116
|
+
| FR3 | Supplying `value` MUST keep state caller-owned and report requested changes through `onChange`; omitting it MUST keep state internal after initialization from `defaultValue`. | `architecture:react-component-runtime/INV1,INV8`; shipped controlled and uncontrolled tests |
|
|
117
|
+
| FR4 | A direct `Collapsible` with a `value` MUST use group coordination; an item without a value MUST retain standalone ownership. | shipped hook behavior and focused group/standalone tests |
|
|
118
|
+
| FR5 | With `hasDividers=false`, the group MUST add no DOM wrapper. With dividers enabled it MUST render one wrapper that receives documented root props and the `collapsible-group` target. | `architecture:public-component-api/INV5–INV8`; `architecture:component-theming-surface/INV3–INV7` |
|
|
119
|
+
| FR6 | Density, divider, and chevron defaults MUST reach direct items without leaking through a direct item's revealed content into nested independent disclosures. | `component:Collapsible/FR7–FR8,DEC-2`; focused nesting tests |
|
|
120
|
+
| FR7 | Presentation context identity MUST remain stable while divider, density, and chevron inputs are unchanged; coordination identity MUST stay stable across a rerender with an unchanged controlled string, the same controlled array reference, or unchanged internal state, with the same `type` and `onChange`. Implementation gap: an equal new controlled array or a new `onChange` rebuilds it (Current-state impact). | `architecture:react-component-runtime/INV9`; memoized source and interaction tests |
|
|
102
121
|
|
|
103
122
|
### Allowed variation
|
|
104
123
|
|
|
@@ -126,14 +145,14 @@ Consumer migration instructions belong in consumer docs and release notes.
|
|
|
126
145
|
### Performance and resources
|
|
127
146
|
|
|
128
147
|
- **PR1 — Render-owned coordination.** The group derives output from props, state, and context and owns no Effect, listener, observer, timer, request, subscription, or imperative browser resource.
|
|
129
|
-
- **PR2 — Stable broadcasts.** Memoized context values
|
|
148
|
+
- **PR2 — Stable broadcasts.** Memoized context values keep the identities FR7 names stable for direct consumers.
|
|
130
149
|
|
|
131
150
|
## Accessibility contract
|
|
132
151
|
|
|
133
152
|
- **AR1 — Child semantics remain primary.** Group coordination MUST preserve each Collapsible button's accessible name, `aria-expanded`, `aria-controls`, controlled region, and keyboard activation.
|
|
134
153
|
- **AR2 — Presentation adds no competing interaction.** The divider wrapper MUST NOT add a role, focus target, accessible name, or keyboard behavior.
|
|
135
154
|
- **AR3 — Direction stays with Collapsible.** Group chevron defaults MUST preserve `component:Collapsible/AR1–AR3`, including the inward leading cue under LTR and RTL.
|
|
136
|
-
- **AR4 — The group adopts the APG Accordion pattern's required parts** (`spec:AST-020/FR15`): each direct item's header is a `button` whose accessible name is the item's title, with `aria-expanded` reflecting its panel, `aria-controls` naming the panel it reveals, and `aria-disabled` when it cannot be toggled; every enabled header sits in the page Tab order and Enter or Space toggles its panel, in `single` mode collapsing the sibling that was open; a disabled header carries `aria-disabled
|
|
155
|
+
- **AR4 — The group adopts the APG Accordion pattern's required parts** (`spec:AST-020/FR15`): each direct item's header is a `button` whose accessible name is the item's title, with `aria-expanded` reflecting its panel, `aria-controls` naming the panel it reveals, and `aria-disabled` when it cannot be toggled; every enabled header sits in the page Tab order and Enter or Space toggles its panel, in `single` mode collapsing the sibling that was open; a disabled header carries `aria-disabled` and cannot be toggled, apart from the Tab-order gap (Current-state impact). Not adopted: a heading element around each header (this record requires none; the caller's document structure supplies headings), the optional `region` role on panels, and arrow-key or Home/End movement between headers — the group is a set of independent disclosures, not one composite control.
|
|
137
156
|
|
|
138
157
|
## Design relationships
|
|
139
158
|
|
|
@@ -142,7 +161,7 @@ Consumer migration instructions belong in consumer docs and release notes.
|
|
|
142
161
|
| Group container | Optional divider chrome visually associates sibling disclosures as a set. | observed shipped representation | aggregate container | FR5–FR6, AR2 |
|
|
143
162
|
| Direct item | Density and chevron defaults remain consistent across sibling rows. | `component:Collapsible/FR7–FR8` | disclosure row | FR6, AR3 |
|
|
144
163
|
|
|
145
|
-
No current design record prescribes exact CollapsibleGroup pixels. This
|
|
164
|
+
No current design record prescribes exact CollapsibleGroup pixels. This record covers the shipped divided and plain relationships without deciding new visual direction.
|
|
146
165
|
|
|
147
166
|
### Theming anatomy
|
|
148
167
|
|
|
@@ -160,7 +179,7 @@ No current design record prescribes exact CollapsibleGroup pixels. This observat
|
|
|
160
179
|
}
|
|
161
180
|
```
|
|
162
181
|
|
|
163
|
-
The Group container is CollapsibleGroup's conditional aggregate wrapper. The other anatomy rows remain owned by `component:Collapsible`; they are repeated in this
|
|
182
|
+
The Group container is CollapsibleGroup's conditional aggregate wrapper. The other anatomy rows remain owned by `component:Collapsible`; they are repeated in this subcomponent map only because the released consumer anatomy and target inventory are shared. Trigger, content, chevron, open state, disabled state, density padding, and per-item dividers remain with Collapsible's contract.
|
|
164
183
|
|
|
165
184
|
## Family and system relationships
|
|
166
185
|
|
|
@@ -172,14 +191,23 @@ The Group container is CollapsibleGroup's conditional aggregate wrapper. The oth
|
|
|
172
191
|
|
|
173
192
|
## Verification map
|
|
174
193
|
|
|
175
|
-
| Contract | Verification
|
|
176
|
-
| ---------------------- |
|
|
177
|
-
| FR1–FR4, ORD1 | `CollapsibleGroup.test.tsx`; `useCollapsible.test.tsx`
|
|
178
|
-
| FR5–FR6, ORD2–ORD3 | `CollapsibleGroup.test.tsx`; `Collapsible.test.tsx`; `themingTargets.test.ts`
|
|
179
|
-
| AR4 | `Collapsible.test.tsx` (disabled trigger: `aria-disabled
|
|
180
|
-
| AR1–AR3 | DOM and Chromium accessibility suites; component-owned Storybook fixture; RTL audit
|
|
181
|
-
| PR1–PR2, FR7 | source review plus context and interaction tests
|
|
182
|
-
| Consumer documentation | CLI component projection, docs checks, and `CollapsibleGroup.stories.tsx`
|
|
194
|
+
| Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
|
|
195
|
+
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- |
|
|
196
|
+
| FR1–FR4, ORD1 | `CollapsibleGroup.test.tsx`; `useCollapsible.test.tsx` | single/multiple; controlled/uncontrolled; valued/unvalued | A sibling stays open in single mode, closes in multiple mode, controlled state mutates internally, or an unvalued item loses local state. | `audit:CollapsibleGroup/behavior` |
|
|
197
|
+
| FR5–FR6, ORD2–ORD3 | `CollapsibleGroup.test.tsx`; `Collapsible.test.tsx`; `themingTargets.test.ts` | plain/divided; each density; group/item/nested position | Wrapper/target reachability changes, defaults stop reaching direct items, or presentation leaks into nested content. | `audit:CollapsibleGroup/theming` |
|
|
198
|
+
| AR4 | `Collapsible.test.tsx` (disabled trigger: `aria-disabled` and no toggle; its out-of-Tab-order assertion pins the gap, pending conformance); `CollapsibleGroup.test.tsx` (single/multiple coordination, `aria-expanded`, Enter activation); `Collapsible.a11y.test.tsx` and `Collapsible.a11y.chromium.spec.ts` (disclosure semantics, Space, Tab reachability for a lone item); `CollapsibleGroup.a11y.test.tsx` and `CollapsibleGroupAccordion.a11y.chromium.spec.ts` (Space on grouped headers; the header-to-header Tab step, single-mode sibling collapse, and no arrow-key movement run as advisory rows) | single/multiple; open/closed; a disabled item, open or closed; Tab order; Enter/Space round trip | A header loses its button role, name, `aria-expanded`, or `aria-controls`; Enter or Space stops toggling; arrow keys move focus between headers | `audit:CollapsibleGroup/accessibility` |
|
|
199
|
+
| AR1–AR3 | DOM and Chromium accessibility suites; component-owned Storybook fixture; RTL audit | open/closed; single/multiple; leading/trailing; LTR/RTL | Disclosure semantics diverge from state, the wrapper becomes interactive, or leading direction stops mirroring. | `audit:CollapsibleGroup/accessibility` |
|
|
200
|
+
| PR1–PR2, FR7 | source review plus context and interaction tests | unchanged and changed state/presentation inputs | An Effect/resource appears, unchanged payload broadcasts a new identity, or changed group behavior fails to reach consumers. | `audit:CollapsibleGroup/code-health` |
|
|
201
|
+
| Consumer documentation | CLI component projection, docs checks, and `CollapsibleGroup.stories.tsx` | every public concept and representative composition | A released prop/default is undiscoverable or the owned browser route loses representative state coverage. | `audit:CollapsibleGroup/docs` |
|
|
202
|
+
|
|
203
|
+
Read from source, with no focused test yet:
|
|
204
|
+
|
|
205
|
+
- AR4: no Home/End movement between headers.
|
|
206
|
+
- FR7: presentation context identity staying stable while divider, density,
|
|
207
|
+
and chevron inputs are unchanged, and coordination identity across the same
|
|
208
|
+
array reference, unchanged internal state, and an equal new array; only the
|
|
209
|
+
controlled-string case is tested.
|
|
210
|
+
- PR1: the group owning no Effect or browser resource.
|
|
183
211
|
|
|
184
212
|
## Decision log
|
|
185
213
|
|
|
@@ -194,7 +222,7 @@ Rejected: arrow-key movement between headers; a required heading element around
|
|
|
194
222
|
|
|
195
223
|
## Open questions
|
|
196
224
|
|
|
197
|
-
None. This
|
|
225
|
+
None. This record does not broaden the released coordination modes or decide new presentation.
|
|
198
226
|
|
|
199
227
|
## Content boundary
|
|
200
228
|
|
|
@@ -155,16 +155,27 @@ test('the state inventory matches rendered disclosure facts', async ({
|
|
|
155
155
|
expect(wrong).toEqual([]);
|
|
156
156
|
});
|
|
157
157
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
158
|
+
// Checking coverage runs every state again, which on a loaded runner nears
|
|
159
|
+
// the per-test timeout as one test. It runs as one serial part per state,
|
|
160
|
+
// sharing their results, then one check over all of them.
|
|
161
|
+
test.describe('every disclosure expectation is exercised by a Collapsible state', () => {
|
|
162
|
+
test.describe.configure({mode: 'serial'});
|
|
163
163
|
const results: BindingResult[] = [];
|
|
164
|
+
|
|
164
165
|
for (const state of COLLAPSIBLE_DISCLOSURE_STATES) {
|
|
165
|
-
|
|
166
|
+
test(`runs ${state.id}`, async ({page}) => {
|
|
167
|
+
const cdp = await page.context().newCDPSession(page);
|
|
168
|
+
results.push(await runState(page, cdp, state));
|
|
169
|
+
});
|
|
166
170
|
}
|
|
167
|
-
|
|
171
|
+
|
|
172
|
+
test('no expectation is left unexercised', () => {
|
|
173
|
+
// Every part ran in this worker; this test alone proves nothing.
|
|
174
|
+
expect(results.map(result => result.state).sort()).toEqual(
|
|
175
|
+
COLLAPSIBLE_DISCLOSURE_STATES.map(state => state.id).sort(),
|
|
176
|
+
);
|
|
177
|
+
expect(neverExercised(results)).toEqual([]);
|
|
178
|
+
});
|
|
168
179
|
});
|
|
169
180
|
|
|
170
181
|
for (const state of COLLAPSIBLE_DISCLOSURE_STATES) {
|
|
@@ -103,15 +103,27 @@ async function runState(
|
|
|
103
103
|
});
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
106
|
+
// Checking coverage runs every state again, which on a loaded runner nears
|
|
107
|
+
// the per-test timeout as one test. It runs as one serial part per state,
|
|
108
|
+
// sharing their results, then one check over all of them.
|
|
109
|
+
test.describe('every accordion expectation is exercised by a CollapsibleGroup state', () => {
|
|
110
|
+
test.describe.configure({mode: 'serial'});
|
|
110
111
|
const results: BindingResult[] = [];
|
|
112
|
+
|
|
111
113
|
for (const state of COLLAPSIBLE_GROUP_ACCORDION_STATES) {
|
|
112
|
-
|
|
114
|
+
test(`runs ${state.id}`, async ({page}) => {
|
|
115
|
+
const cdp = await page.context().newCDPSession(page);
|
|
116
|
+
results.push(await runState(page, cdp, state));
|
|
117
|
+
});
|
|
113
118
|
}
|
|
114
|
-
|
|
119
|
+
|
|
120
|
+
test('no expectation is left unexercised', () => {
|
|
121
|
+
// Every part ran in this worker; this test alone proves nothing.
|
|
122
|
+
expect(results.map(result => result.state).sort()).toEqual(
|
|
123
|
+
COLLAPSIBLE_GROUP_ACCORDION_STATES.map(state => state.id).sort(),
|
|
124
|
+
);
|
|
125
|
+
expect(neverExercised(results)).toEqual([]);
|
|
126
|
+
});
|
|
115
127
|
});
|
|
116
128
|
|
|
117
129
|
for (const state of COLLAPSIBLE_GROUP_ACCORDION_STATES) {
|
|
@@ -1320,6 +1320,41 @@ describe('ContextMenu keyboard access for menuitemradio/menuitemcheckbox (#3829)
|
|
|
1320
1320
|
});
|
|
1321
1321
|
});
|
|
1322
1322
|
|
|
1323
|
+
describe('ContextMenu data-driven submenu inside a section', () => {
|
|
1324
|
+
it('renders a submenu row for an item with nested items inside a section', () => {
|
|
1325
|
+
render(
|
|
1326
|
+
<ContextMenu
|
|
1327
|
+
items={[
|
|
1328
|
+
{
|
|
1329
|
+
type: 'section',
|
|
1330
|
+
title: 'Organize',
|
|
1331
|
+
items: [
|
|
1332
|
+
{label: 'Rename', onClick: () => {}},
|
|
1333
|
+
{
|
|
1334
|
+
label: 'Move to',
|
|
1335
|
+
items: [
|
|
1336
|
+
{label: 'Folder A', onClick: () => {}},
|
|
1337
|
+
{label: 'Folder B', onClick: () => {}},
|
|
1338
|
+
],
|
|
1339
|
+
},
|
|
1340
|
+
],
|
|
1341
|
+
},
|
|
1342
|
+
]}>
|
|
1343
|
+
<div>Right-click me</div>
|
|
1344
|
+
</ContextMenu>,
|
|
1345
|
+
);
|
|
1346
|
+
fireEvent.contextMenu(screen.getByText('Right-click me'));
|
|
1347
|
+
const trigger = screen.getByRole('menuitem', {
|
|
1348
|
+
name: /Move to/,
|
|
1349
|
+
hidden: true,
|
|
1350
|
+
});
|
|
1351
|
+
expect(trigger).toHaveAttribute('aria-haspopup', 'menu');
|
|
1352
|
+
expect(
|
|
1353
|
+
screen.getByRole('menuitem', {name: 'Folder A', hidden: true}),
|
|
1354
|
+
).toBeInTheDocument();
|
|
1355
|
+
});
|
|
1356
|
+
});
|
|
1357
|
+
|
|
1323
1358
|
describe('ContextMenu press model', () => {
|
|
1324
1359
|
const touch = {pointerType: 'touch', pointerId: 1};
|
|
1325
1360
|
const item = (name: string) =>
|
|
@@ -633,15 +633,19 @@ describe('DateInput', () => {
|
|
|
633
633
|
}
|
|
634
634
|
|
|
635
635
|
render(<ControlledDateInput />);
|
|
636
|
-
|
|
636
|
+
const toggle = getButton('Open calendar');
|
|
637
|
+
await user.click(toggle);
|
|
637
638
|
await user.click(getButton(/January 15, 2026/));
|
|
639
|
+
// The calendar mounts only while open; reopen it to read the selection.
|
|
640
|
+
await user.click(toggle);
|
|
638
641
|
expect(
|
|
639
642
|
screen.getAllByRole('gridcell', {selected: true, hidden: true}),
|
|
640
643
|
).toHaveLength(1);
|
|
644
|
+
await user.click(toggle);
|
|
641
645
|
|
|
642
646
|
await user.click(getButton('Clear Date'));
|
|
643
647
|
expect(screen.getByRole('combobox')).toHaveValue('');
|
|
644
|
-
await user.click(
|
|
648
|
+
await user.click(toggle);
|
|
645
649
|
|
|
646
650
|
expect(
|
|
647
651
|
screen.queryAllByRole('gridcell', {selected: true, hidden: true}),
|
|
@@ -1152,6 +1156,53 @@ describe('DateInput', () => {
|
|
|
1152
1156
|
expect(screen.getByDisplayValue('Mar 10, 2026')).toBeInTheDocument();
|
|
1153
1157
|
});
|
|
1154
1158
|
});
|
|
1159
|
+
describe('calendar while the popover is closed', () => {
|
|
1160
|
+
const calendarGrid = () => document.querySelector('[role="grid"]');
|
|
1161
|
+
|
|
1162
|
+
it('renders no calendar until the popover opens, and none after it closes', () => {
|
|
1163
|
+
render(<DateInput label="Date" value="2026-01-25" onChange={() => {}} />);
|
|
1164
|
+
const toggle = getButton('Open calendar');
|
|
1165
|
+
expect(calendarGrid()).toBeNull();
|
|
1166
|
+
|
|
1167
|
+
fireEvent.click(toggle);
|
|
1168
|
+
expect(calendarGrid()).not.toBeNull();
|
|
1169
|
+
|
|
1170
|
+
fireEvent.click(toggle);
|
|
1171
|
+
expect(calendarGrid()).toBeNull();
|
|
1172
|
+
});
|
|
1173
|
+
|
|
1174
|
+
it('opens on the month of a date typed while closed', () => {
|
|
1175
|
+
function Controlled() {
|
|
1176
|
+
const [value, setValue] = useState<ISODateString | undefined>(
|
|
1177
|
+
'2026-01-25',
|
|
1178
|
+
);
|
|
1179
|
+
return <DateInput label="Date" value={value} onChange={setValue} />;
|
|
1180
|
+
}
|
|
1181
|
+
render(<Controlled />);
|
|
1182
|
+
const input = screen.getByRole('combobox');
|
|
1183
|
+
|
|
1184
|
+
fireEvent.change(input, {target: {value: 'March 5, 2027'}});
|
|
1185
|
+
fireEvent.keyDown(input, {key: 'ArrowDown'});
|
|
1186
|
+
|
|
1187
|
+
expect(calendarGrid()).toHaveAccessibleName('March 2027');
|
|
1188
|
+
});
|
|
1189
|
+
|
|
1190
|
+
it('moves focus into the calendar on each open from the toggle', async () => {
|
|
1191
|
+
render(<DateInput label="Date" value="2026-01-25" onChange={() => {}} />);
|
|
1192
|
+
const toggle = getButton('Open calendar');
|
|
1193
|
+
|
|
1194
|
+
for (let i = 0; i < 2; i++) {
|
|
1195
|
+
fireEvent.click(toggle);
|
|
1196
|
+
// The first calendar control takes focus, not the dialog surface.
|
|
1197
|
+
await waitFor(() => {
|
|
1198
|
+
expect(getButton('Previous month')).toHaveFocus();
|
|
1199
|
+
});
|
|
1200
|
+
fireEvent.click(toggle);
|
|
1201
|
+
expect(calendarGrid()).toBeNull();
|
|
1202
|
+
}
|
|
1203
|
+
});
|
|
1204
|
+
});
|
|
1205
|
+
|
|
1155
1206
|
describe('weekStartsOn', () => {
|
|
1156
1207
|
// The calendar popover renders in the top layer; jsdom keeps the content in
|
|
1157
1208
|
// the DOM but role queries skip it, so read the columnheaders directly.
|
|
@@ -948,17 +948,21 @@ function PointerDateField({
|
|
|
948
948
|
{isBusy && <Spinner size="sm" aria-hidden="true" />}
|
|
949
949
|
{statusIcon}
|
|
950
950
|
{popover.render(
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
951
|
+
// The layer renders its children open or closed, so mount the
|
|
952
|
+
// calendar only while it is open; it opens on the current value.
|
|
953
|
+
!popover.isOpen ? null : (
|
|
954
|
+
<Calendar
|
|
955
|
+
handleRef={calendarRef}
|
|
956
|
+
mode="single"
|
|
957
|
+
value={optimisticValue ?? null}
|
|
958
|
+
onChange={handleDateSelect}
|
|
959
|
+
min={min}
|
|
960
|
+
max={max}
|
|
961
|
+
dateConstraints={dateConstraints}
|
|
962
|
+
numberOfMonths={numberOfMonths}
|
|
963
|
+
weekStartsOn={weekStartsOn}
|
|
964
|
+
/>
|
|
965
|
+
),
|
|
962
966
|
{placement: 'below', alignment: 'start'},
|
|
963
967
|
)}
|
|
964
968
|
{showsDisabledMessage &&
|