@astryxdesign/core 0.7.5 → 0.7.6-canary.5cd7a15
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/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 +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/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/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/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/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 +15 -1
- 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/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/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/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 +15 -3
- 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/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/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 +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.spec.md +205 -0
- 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/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/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 +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/Typeahead/Typeahead.test.tsx +40 -0
- package/src/Typeahead/Typeahead.tsx +12 -1
- 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/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/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/pressPaintPriority.test.ts +80 -0
- package/src/utils/primaryClick.test.ts +38 -0
- package/src/utils/primaryClick.ts +28 -0
- package/src/utils/timeFormat.test.ts +204 -0
- package/src/utils/timeFormat.ts +314 -0
- package/src/utils/touchPresentation.stylex.ts +43 -0
- package/src/utils/touchPresentation.test.ts +140 -1
- package/src/utils/touchPresentation.ts +5 -3
- package/src/utils/unicodeDigits.test.ts +44 -0
- package/src/utils/unicodeDigits.ts +71 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file lazyMenuBottomSheet.test.ts
|
|
5
|
+
* @input lazyMenuBottomSheet's action-list preload, with the list's module
|
|
6
|
+
* failing to load once
|
|
7
|
+
* @output A failed preload is no unhandled rejection, and is not kept: the
|
|
8
|
+
* next load asks the module loader again
|
|
9
|
+
* @position Unit test of ./lazyMenuBottomSheet; the hydration case is in
|
|
10
|
+
* DropdownMenu.ssr.test.tsx
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import {afterEach, describe, expect, it, vi} from 'vitest';
|
|
14
|
+
|
|
15
|
+
afterEach(() => {
|
|
16
|
+
vi.doUnmock('./MenuBottomSheetActionList');
|
|
17
|
+
vi.resetModules();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
describe('preloadMenuBottomSheetActionList', () => {
|
|
21
|
+
it('drops a failed preload without an unhandled rejection, and asks the module loader again on the next call', async () => {
|
|
22
|
+
vi.resetModules();
|
|
23
|
+
let attempts = 0;
|
|
24
|
+
vi.doMock('./MenuBottomSheetActionList', () => {
|
|
25
|
+
attempts += 1;
|
|
26
|
+
if (attempts === 1) {
|
|
27
|
+
throw new Error('the connection dropped');
|
|
28
|
+
}
|
|
29
|
+
return {MenuBottomSheetActionList: () => null};
|
|
30
|
+
});
|
|
31
|
+
const unhandled: unknown[] = [];
|
|
32
|
+
const onUnhandled = (reason: unknown) => unhandled.push(reason);
|
|
33
|
+
process.on('unhandledRejection', onUnhandled);
|
|
34
|
+
try {
|
|
35
|
+
const {preloadMenuBottomSheetActionList} =
|
|
36
|
+
await import('./lazyMenuBottomSheet');
|
|
37
|
+
preloadMenuBottomSheetActionList();
|
|
38
|
+
await vi.waitFor(() => expect(attempts).toBe(1));
|
|
39
|
+
// An unhandled rejection is reported after the rejecting task's
|
|
40
|
+
// microtasks: give it two macrotasks.
|
|
41
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
42
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
43
|
+
expect(unhandled).toEqual([]);
|
|
44
|
+
|
|
45
|
+
preloadMenuBottomSheetActionList();
|
|
46
|
+
await vi.waitFor(() => expect(attempts).toBe(2));
|
|
47
|
+
const loaded = await import('./MenuBottomSheetActionList');
|
|
48
|
+
expect(typeof loaded.MenuBottomSheetActionList).toBe('function');
|
|
49
|
+
} finally {
|
|
50
|
+
process.off('unhandledRejection', onUnhandled);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
});
|
|
@@ -15,6 +15,11 @@
|
|
|
15
15
|
* of pages whose dropdowns only open as anchored popovers. Each wrapper keeps
|
|
16
16
|
* the wrapped component's props and renders nothing until its module loads.
|
|
17
17
|
*
|
|
18
|
+
* The action list preloads at rest; a failed load is not kept, so the next
|
|
19
|
+
* preload or open asks the module loader again (a loader that retries then
|
|
20
|
+
* loads it; a browser does not fetch a native module again once its import
|
|
21
|
+
* failed).
|
|
22
|
+
*
|
|
18
23
|
* Neither wrapper renders on the server or in the render that hydrates server
|
|
19
24
|
* HTML (spec:AST-013 FR9): a lazy component that has not loaded yet would
|
|
20
25
|
* leave server markup incomplete and abort hydration. The closed sheet has no
|
|
@@ -47,16 +52,28 @@ const LazyMenuBottomSheet = lazy(async () =>
|
|
|
47
52
|
let actionListModule: typeof ActionListModule | null = null;
|
|
48
53
|
let actionListLoad: Promise<typeof ActionListModule> | null = null;
|
|
49
54
|
async function loadActionList(): Promise<typeof ActionListModule> {
|
|
50
|
-
actionListLoad ??= import('./MenuBottomSheetActionList').then(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
55
|
+
actionListLoad ??= import('./MenuBottomSheetActionList').then(
|
|
56
|
+
module => {
|
|
57
|
+
actionListModule = module;
|
|
58
|
+
return module;
|
|
59
|
+
},
|
|
60
|
+
(error: unknown) => {
|
|
61
|
+
// A failed load (a dropped connection) is not kept: the next caller
|
|
62
|
+
// asks the module loader again.
|
|
63
|
+
actionListLoad = null;
|
|
64
|
+
throw error;
|
|
65
|
+
},
|
|
66
|
+
);
|
|
54
67
|
return actionListLoad;
|
|
55
68
|
}
|
|
56
69
|
|
|
57
|
-
/**
|
|
70
|
+
/**
|
|
71
|
+
* Starts loading the action list; a sheet menu calls it at rest. A preload
|
|
72
|
+
* that fails is dropped, never an unhandled rejection: the first open asks the
|
|
73
|
+
* module loader again.
|
|
74
|
+
*/
|
|
58
75
|
export function preloadMenuBottomSheetActionList(): void {
|
|
59
|
-
|
|
76
|
+
loadActionList().catch(() => {});
|
|
60
77
|
}
|
|
61
78
|
|
|
62
79
|
const LazyMenuBottomSheetActionList = lazy(async () =>
|
|
@@ -68,6 +68,28 @@ function renderLeafItem(
|
|
|
68
68
|
return <DropdownMenuItem key={getItemKey(item, index)} {...itemProps} />;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
/**
|
|
72
|
+
* A data item that declares nested `items` becomes a submenu (data-mode
|
|
73
|
+
* parity with the compound DropdownMenuSubMenu API), at the top level and
|
|
74
|
+
* inside a section alike; otherwise it's a leaf. renderDropdownItems owns the
|
|
75
|
+
* recursion and hands the rendered children to DropdownMenuSubMenu, so
|
|
76
|
+
* DropdownMenuSubMenu never imports this module back (no import cycle).
|
|
77
|
+
*/
|
|
78
|
+
function renderItem(item: DropdownMenuItemData, index: number): ReactElement {
|
|
79
|
+
if (item.items && item.items.length > 0) {
|
|
80
|
+
return (
|
|
81
|
+
<DropdownMenuSubMenu
|
|
82
|
+
key={getItemKey(item, index)}
|
|
83
|
+
icon={item.icon}
|
|
84
|
+
label={item.label}
|
|
85
|
+
isDisabled={item.isDisabled}>
|
|
86
|
+
{renderDropdownItems(item.items)}
|
|
87
|
+
</DropdownMenuSubMenu>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
return renderLeafItem(item, index);
|
|
91
|
+
}
|
|
92
|
+
|
|
71
93
|
/**
|
|
72
94
|
* Converts data-driven items into DropdownMenuItem components,
|
|
73
95
|
* so both modes share the same rendering and keyboard navigation path.
|
|
@@ -96,28 +118,11 @@ export function renderDropdownItems(items: DropdownMenuOption[]): ReactNode {
|
|
|
96
118
|
{option.title}
|
|
97
119
|
</div>
|
|
98
120
|
)}
|
|
99
|
-
{option.items.map(
|
|
121
|
+
{option.items.map(renderItem)}
|
|
100
122
|
</div>,
|
|
101
123
|
);
|
|
102
124
|
} else if (!('type' in option)) {
|
|
103
|
-
|
|
104
|
-
// parity with the compound DropdownMenuSubMenu API); otherwise it's a
|
|
105
|
-
// leaf. renderDropdownItems owns the recursion and hands the rendered
|
|
106
|
-
// children to DropdownMenuSubMenu — so DropdownMenuSubMenu never imports
|
|
107
|
-
// this module back (no import cycle).
|
|
108
|
-
if (option.items && option.items.length > 0) {
|
|
109
|
-
elements.push(
|
|
110
|
-
<DropdownMenuSubMenu
|
|
111
|
-
key={getItemKey(option, i)}
|
|
112
|
-
icon={option.icon}
|
|
113
|
-
label={option.label}
|
|
114
|
-
isDisabled={option.isDisabled}>
|
|
115
|
-
{renderDropdownItems(option.items)}
|
|
116
|
-
</DropdownMenuSubMenu>,
|
|
117
|
-
);
|
|
118
|
-
} else {
|
|
119
|
-
elements.push(renderLeafItem(option, i));
|
|
120
|
-
}
|
|
125
|
+
elements.push(renderItem(option, i));
|
|
121
126
|
}
|
|
122
127
|
}
|
|
123
128
|
|
|
@@ -24,7 +24,8 @@ import {
|
|
|
24
24
|
} from '../theme/tokens.stylex';
|
|
25
25
|
import type {BaseProps} from '../BaseProps';
|
|
26
26
|
import {AnnounceRenderedText} from '../hooks/AnnounceRenderedText';
|
|
27
|
-
import {isRenderable
|
|
27
|
+
import {isRenderable} from '../utils/isRenderable';
|
|
28
|
+
import {mergeProps} from '../utils/mergeProps';
|
|
28
29
|
import {themeProps} from '../utils/themeProps';
|
|
29
30
|
|
|
30
31
|
const styles = stylex.create({
|
package/src/Field/FieldLabel.tsx
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
import {use, useMemo, useRef, type ReactNode, type RefObject} from 'react';
|
|
20
20
|
import * as stylex from '@stylexjs/stylex';
|
|
21
21
|
import type {BaseProps} from '../BaseProps';
|
|
22
|
-
import {mergeProps} from '../utils';
|
|
22
|
+
import {mergeProps} from '../utils/mergeProps';
|
|
23
23
|
|
|
24
24
|
import {
|
|
25
25
|
colorVars,
|
|
@@ -28,9 +28,10 @@ import {
|
|
|
28
28
|
typographyVars,
|
|
29
29
|
typeScaleVars,
|
|
30
30
|
} from '../theme/tokens.stylex';
|
|
31
|
-
import {Icon, renderIconSlot
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
31
|
+
import {Icon, renderIconSlot} from '../Icon/Icon';
|
|
32
|
+
import type {IconType} from '../Icon';
|
|
33
|
+
import {Tooltip} from '../Tooltip/Tooltip';
|
|
34
|
+
import {useTranslator} from '../i18n/useTranslator';
|
|
34
35
|
import {themeProps} from '../utils/themeProps';
|
|
35
36
|
import {useInputContainer} from '../hooks/useInputContainer';
|
|
36
37
|
import {FormLayoutContext} from '../FormLayout/FormLayoutContext';
|
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
|
|
19
19
|
import type {ReactNode} from 'react';
|
|
20
20
|
import * as stylex from '@stylexjs/stylex';
|
|
21
|
-
import {Button} from '../Button';
|
|
22
|
-
import {Icon} from '../Icon';
|
|
23
|
-
import {useTranslator} from '../i18n';
|
|
21
|
+
import {Button} from '../Button/Button';
|
|
22
|
+
import {Icon} from '../Icon/Icon';
|
|
23
|
+
import {useTranslator} from '../i18n/useTranslator';
|
|
24
24
|
import {themeProps} from '../utils/themeProps';
|
|
25
25
|
|
|
26
26
|
const styles = stylex.create({
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
import {useCallback, useState, type Ref} from 'react';
|
|
43
43
|
import * as stylex from '@stylexjs/stylex';
|
|
44
44
|
import type {StyleXStyles} from '@stylexjs/stylex';
|
|
45
|
-
import {Icon} from '../Icon';
|
|
45
|
+
import {Icon} from '../Icon/Icon';
|
|
46
46
|
import {InputClearButton} from './InputClearButton';
|
|
47
|
-
import {mergeProps} from '../utils';
|
|
47
|
+
import {mergeProps} from '../utils/mergeProps';
|
|
48
48
|
import {
|
|
49
49
|
getInteractionModality,
|
|
50
50
|
useInteractionModalityTracking,
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
import React from 'react';
|
|
21
21
|
import * as stylex from '@stylexjs/stylex';
|
|
22
22
|
import type {BaseProps} from '../BaseProps';
|
|
23
|
-
import {mergeProps} from '../utils';
|
|
23
|
+
import {mergeProps} from '../utils/mergeProps';
|
|
24
24
|
import {
|
|
25
25
|
colorVars,
|
|
26
26
|
radiusVars,
|
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
import type {InputStatusType} from '../Field/types';
|
|
32
32
|
import {useEntryAnimation} from '../hooks/useEntryAnimation';
|
|
33
33
|
import {themeProps} from '../utils/themeProps';
|
|
34
|
-
import {Icon} from '../Icon';
|
|
34
|
+
import {Icon} from '../Icon/Icon';
|
|
35
35
|
import type {IconName} from '../Icon';
|
|
36
36
|
import type {FieldStatusVariantMap} from './index';
|
|
37
37
|
import {useFieldStatusAnnouncement} from './useFieldStatusAnnouncement';
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
} from '@testing-library/react';
|
|
21
21
|
import userEvent from '@testing-library/user-event';
|
|
22
22
|
import {FileInput} from './FileInput';
|
|
23
|
+
import {FormLayout} from '../FormLayout';
|
|
23
24
|
import {__resetLiveRegionsForTest} from '../hooks/useAnnounce';
|
|
24
25
|
import {InternationalizationProvider} from '../i18n';
|
|
25
26
|
import {Theme} from '../theme/Theme';
|
|
@@ -204,6 +205,26 @@ describe('FileInput', () => {
|
|
|
204
205
|
expect(trigger).not.toHaveAttribute('aria-required');
|
|
205
206
|
});
|
|
206
207
|
|
|
208
|
+
it('conveys required state under FormLayout defaultOptionality="required" unless isOptional (FormLayout FR5)', () => {
|
|
209
|
+
render(
|
|
210
|
+
<FormLayout defaultOptionality="required">
|
|
211
|
+
<FileInput label="Resume" value={null} onChange={() => {}} />
|
|
212
|
+
<FileInput
|
|
213
|
+
label="Cover letter"
|
|
214
|
+
isOptional
|
|
215
|
+
value={null}
|
|
216
|
+
onChange={() => {}}
|
|
217
|
+
/>
|
|
218
|
+
</FormLayout>,
|
|
219
|
+
);
|
|
220
|
+
expect(
|
|
221
|
+
screen.getByRole('button', {name: 'Resume'}),
|
|
222
|
+
).toHaveAccessibleDescription(/Required/);
|
|
223
|
+
expect(
|
|
224
|
+
screen.getByRole('button', {name: /Cover letter/}),
|
|
225
|
+
).not.toHaveAccessibleDescription(/Required/);
|
|
226
|
+
});
|
|
227
|
+
|
|
207
228
|
it('combines required with the description in the accessible description', () => {
|
|
208
229
|
render(
|
|
209
230
|
<FileInput
|
|
@@ -68,6 +68,7 @@ import {useTranslator} from '../i18n';
|
|
|
68
68
|
import type {TranslatorFn} from '../i18n';
|
|
69
69
|
|
|
70
70
|
import {useMergedRefs} from '../hooks/useMergedRefs';
|
|
71
|
+
import {useResolvedRequired} from '../hooks/useResolvedRequired';
|
|
71
72
|
function formatFileSize(bytes: number, t: TranslatorFn): string {
|
|
72
73
|
if (bytes < 1024) {
|
|
73
74
|
return t('@astryx.fileInput.fileSize.bytes', {size: bytes});
|
|
@@ -544,7 +545,9 @@ export function FileInput({
|
|
|
544
545
|
// at a visually hidden "Required" span — mirroring the Field label's visible
|
|
545
546
|
// indicator (where isOptional takes precedence) and the pattern Slider uses
|
|
546
547
|
// for its thumbs.
|
|
547
|
-
|
|
548
|
+
// A surrounding FormLayout's defaultOptionality="required" makes an unmarked
|
|
549
|
+
// field required too (FormLayout FR5).
|
|
550
|
+
const conveysRequired = useResolvedRequired({isRequired, isOptional});
|
|
548
551
|
|
|
549
552
|
const ariaDescribedBy =
|
|
550
553
|
[
|
|
@@ -63,12 +63,11 @@ This table is a review projection; the body below is authoritative.
|
|
|
63
63
|
|
|
64
64
|
## Current-state impact
|
|
65
65
|
|
|
66
|
-
- **Required state lost for
|
|
66
|
+
- **Required state lost for two controls (FR5, AR2).** Under
|
|
67
67
|
`defaultOptionality="required"` the visible "Required" marker is hidden,
|
|
68
|
-
but Typeahead and Tokenizer set no `aria-required
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
the form-wide convention.
|
|
68
|
+
but Typeahead and Tokenizer set no `aria-required`. Screen reader users
|
|
69
|
+
hear those fields as not required, while sighted users see the form-wide
|
|
70
|
+
convention.
|
|
72
71
|
|
|
73
72
|
## Ownership boundary
|
|
74
73
|
|
|
@@ -101,7 +100,7 @@ This table is a review projection; the body below is authoritative.
|
|
|
101
100
|
| FR2 | `horizontal` places every direct child in one `1fr` grid column in the document's logical inline order, with a `--spacing-4` gap and no component-owned wrap rule. | Released source, tests, and stories |
|
|
102
101
|
| FR3 | `horizontal-labels` is a two-column grid (`auto 1fr`) with a `--spacing-3` row gap and `--spacing-4` column gap, items aligned to the start, so Field labels sit on the inline-start side of their controls; at a viewport width of 480px or below it becomes one flex column with a `--spacing-4` gap. OQ1 holds whether the collapsed label and control need a tighter pair gap. | Released source, Field composition, and tests |
|
|
103
102
|
| FR4 | FormLayout provides its direction and `defaultOptionality` to descendants in the same layer; a nested FormLayout replaces both for its own descendants, and content in a layer opened inside a FormLayout starts without them (`spec:AST-038` FR7, FR8). | Context source and tests |
|
|
104
|
-
| FR5 | `defaultOptionality` suppresses only the visible marker that restates the form default; descendant controls still expose the resolved `aria-required`, while native `required` stays tied to an explicit field `isRequired`. Unset keeps each field's own indicators. Implementation gap: under `defaultOptionality="required"`, Typeahead and Tokenizer set no `aria-required`,
|
|
103
|
+
| FR5 | `defaultOptionality` suppresses only the visible marker that restates the form default; descendant controls still expose the resolved `aria-required`, while native `required` stays tied to an explicit field `isRequired`. Unset keeps each field's own indicators. Implementation gap: under `defaultOptionality="required"`, Typeahead and Tokenizer set no `aria-required`, so those fields are announced as not required while the marker is hidden (Current-state impact). | Tests; `family:input-fields` ownership |
|
|
105
104
|
| FR6 | The root is a `div`. `ref`, DOM, data, ARIA, and event props, `xstyle`, class name, and inline style reach or compose on the root without replacing `data-direction` or the `form-layout` target. | `architecture:public-component-api/INV5–INV8`; source and tests |
|
|
106
105
|
|
|
107
106
|
### Allowed variation
|
|
@@ -135,7 +134,7 @@ This table is a review projection; the body below is authoritative.
|
|
|
135
134
|
## Accessibility contract
|
|
136
135
|
|
|
137
136
|
- **AR1 — Layout remains nonsemantic.** FormLayout renders a `<div>` and does not imply `<form>`, group, label, or submission semantics; callers provide those when their composition needs them.
|
|
138
|
-
- **AR2 — Required state remains perceivable.** A form-wide optionality convention may remove redundant visible markers, but descendant controls preserve the resolved required state for assistive technology. Implementation gap: Typeahead
|
|
137
|
+
- **AR2 — Required state remains perceivable.** A form-wide optionality convention may remove redundant visible markers, but descendant controls preserve the resolved required state for assistive technology. Implementation gap: Typeahead and Tokenizer do not (FR5).
|
|
139
138
|
- **AR3 — Logical order is preserved.** Every direction retains DOM order and logical inline flow; FormLayout does not create a separate keyboard order.
|
|
140
139
|
|
|
141
140
|
## Design relationships
|
|
@@ -191,7 +190,7 @@ The root target reflects the closed `direction` axis. It owns the outer arrangem
|
|
|
191
190
|
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------- |
|
|
192
191
|
| FR1–FR3 | `FormLayout.test.tsx` direction snapshots; `FormLayout.stories.tsx` play checks; stable visual baseline `core-formlayout--vertical` | Vertical, horizontal, horizontal-labels wide and narrow | A changed style class set fails the snapshots; a narrow horizontal-labels control narrower than the layout, or a wide label not before its control, fails the play checks; a changed vertical layout comes back changed for review. The story play guard also runs the AuditMatrix play right-to-left at 320px and the default width, where mirrored horizontal columns are asserted. Gap: no right-to-left check asserts that a horizontal-labels label sits on the inline-start side of its control. | `audit:FormLayout/behavior` |
|
|
193
192
|
| FR4, ORD1 | `FormLayout.test.tsx` context and nesting tests; `Layer/layerScopedContext.test.tsx` | Default, explicit, nested; content in a fixed Layer and an inline Dialog | A lost default or value, lost shadowing by an inner layout's explicit values, or content inside a layer that still reads the outer `defaultOptionality` fails. Gap: no test covers an inner layout with unset props (which supplies its own defaults) or `direction` across a layer boundary. | `audit:FormLayout/behavior` |
|
|
194
|
-
| FR5, ORD3, AR2 | `FormLayout.test.tsx` optionality and `aria-required` tests | Required, optional, unset defaults; explicit exceptions | A redundant marker, a missing `aria-required`, or a native `required` from the default fails. Gap: no test covers Typeahead
|
|
193
|
+
| FR5, ORD3, AR2 | `FormLayout.test.tsx` optionality and `aria-required` tests | Required, optional, unset defaults; explicit exceptions | A redundant marker, a missing `aria-required`, or a native `required` from the default fails. FileInput and Slider tests cover a `required` default. Gap: no test covers Typeahead or Tokenizer under a `required` default, which do not expose it. | `audit:FormLayout/accessibility` |
|
|
195
194
|
| FR6, ORD2 | `FormLayout.test.tsx` ref, passthrough, and owned-metadata tests; `themingTargets.test.ts` | Ref, attributes, colliding `data-direction` | A ref on a non-`div`, a dropped `id` or `role`, or a replaced `data-direction` fails. Gap: no test covers event props or the styling-input merge order. | `audit:FormLayout/api` |
|
|
196
195
|
| AR1, AR3 | `FormLayout.test.tsx` div and passthrough tests; `FormLayout.stories.tsx` play checks | Plain root; caller `role` | A non-`div` root or a dropped caller `role` fails. Horizontal columns that do not mirror right-to-left fail the AuditMatrix play under the story play guard. Gap: no check fails if FormLayout adds a role of its own. | `audit:FormLayout/accessibility` |
|
|
197
196
|
| PR1 | Source review | Every direction | Gap: no automated check covers context identity or added resources. | `audit:FormLayout/behavior` |
|
package/src/Heading/Heading.tsx
CHANGED
|
@@ -45,7 +45,7 @@ import {
|
|
|
45
45
|
import {useTruncation} from '../Text/useTruncation';
|
|
46
46
|
import {resolveStyleColor} from '../Text/Text';
|
|
47
47
|
import type {LayerPlacement} from '../Layer';
|
|
48
|
-
import {mergeProps} from '../utils';
|
|
48
|
+
import {mergeProps} from '../utils/mergeProps';
|
|
49
49
|
import {useMergedRefs} from '../hooks/useMergedRefs';
|
|
50
50
|
import type {BaseProps} from '../BaseProps';
|
|
51
51
|
import {themeProps} from '../utils/themeProps';
|
package/src/Icon/Icon.tsx
CHANGED
|
@@ -38,7 +38,7 @@ import {useThemeName} from '../theme/useTheme';
|
|
|
38
38
|
import {resolveIcon} from './globalIconRegistry';
|
|
39
39
|
import type {IconName, NamespacedIconName} from './globalIconRegistry';
|
|
40
40
|
import type {IconVariant} from './index';
|
|
41
|
-
import {mergeProps} from '../utils';
|
|
41
|
+
import {mergeProps} from '../utils/mergeProps';
|
|
42
42
|
import {themeProps} from '../utils/themeProps';
|
|
43
43
|
import {useIconSize} from './IconDefaultSizeContext';
|
|
44
44
|
import {iconSizeStyles, type IconSize} from './IconSize.stylex';
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
---
|
|
2
2
|
schema_version: 3
|
|
3
|
-
template_version:
|
|
3
|
+
template_version: 7
|
|
4
4
|
kind: component
|
|
5
5
|
id: component:CheckIndicator
|
|
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, theming, accessibility, visual]
|
|
13
13
|
verified_by:
|
|
14
14
|
[
|
|
15
15
|
packages/core/src/Indicator/Indicator.test.tsx,
|
|
16
16
|
packages/core/src/theme/themingTargets.test.ts,
|
|
17
|
-
apps/storybook/stories/Indicator.stories.tsx,
|
|
18
17
|
]
|
|
19
18
|
modules: []
|
|
20
19
|
families: []
|
|
@@ -33,17 +32,17 @@ system_specs: []
|
|
|
33
32
|
|
|
34
33
|
## Contract at a glance
|
|
35
34
|
|
|
36
|
-
| Area | Contract
|
|
37
|
-
| ----------------------- |
|
|
38
|
-
| Public contract | `CheckIndicator` is exported from `@astryxdesign/core/Indicator`; `state` is required, `size` defaults to `md`, `isDisabled` defaults to `false`, and `children` may replace the built-in mark.
|
|
39
|
-
| Behavior | The component draws a decorative check glyph only when checked. Shallow-renderable `children` replace that glyph in either state; unchecked without replacement content renders no element.
|
|
40
|
-
| End-user impact | People receive one selection cue from the owning control without a duplicate accessible object or an empty placeholder beside unselected rows.
|
|
41
|
-
| Builder impact | Builders may replace the named `check` indicator or compose host-owned classes and styling without taking over the owning control's semantics.
|
|
42
|
-
| Compatibility/readiness |
|
|
43
|
-
| Review checks | Reject lost `aria-hidden`, a mark in the unchecked default, a missing checked mark, dropped supported DOM/styling passthrough, changed replacement precedence, a new component-owned theme target, or
|
|
44
|
-
| Governing rules | `architecture:public-component-api/INV1,INV5,INV6,INV8,INV9`; `architecture:component-theming-surface/INV3–INV6`; `architecture:component-test-sufficiency/INV1–INV7,INV10–INV11`.
|
|
35
|
+
| Area | Contract |
|
|
36
|
+
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
37
|
+
| Public contract | `CheckIndicator` is exported from `@astryxdesign/core/Indicator`; `state` is required, `size` defaults to `md`, `isDisabled` defaults to `false`, and `children` may replace the built-in mark. |
|
|
38
|
+
| Behavior | The component draws a decorative check glyph only when checked. Shallow-renderable `children` replace that glyph in either state; unchecked without replacement content renders no element. |
|
|
39
|
+
| End-user impact | People receive one selection cue from the owning control without a duplicate accessible object or an empty placeholder beside unselected rows. |
|
|
40
|
+
| Builder impact | Builders may replace the named `check` indicator or compose host-owned classes and styling without taking over the owning control's semantics. |
|
|
41
|
+
| Compatibility/readiness | Records shipped behavior; no API, default, or DOM change. The checked glyph path drops the declared `ref`; listed under Current-state impact, with the fix open (OQ1). |
|
|
42
|
+
| Review checks | Reject lost `aria-hidden`, a mark in the unchecked default, a missing checked mark, dropped supported DOM/styling passthrough, changed replacement precedence, a new component-owned theme target, or a checked path that still drops the ref once OQ1 is decided. |
|
|
43
|
+
| Governing rules | `architecture:public-component-api/INV1,INV5,INV6,INV8,INV9`; `architecture:component-theming-surface/INV3–INV6`; `architecture:component-test-sufficiency/INV1–INV7,INV10–INV11`. |
|
|
45
44
|
|
|
46
|
-
This table is a review projection; the body below is authoritative
|
|
45
|
+
This table is a review projection; the body below is authoritative.
|
|
47
46
|
|
|
48
47
|
## Intent
|
|
49
48
|
|
|
@@ -52,7 +51,8 @@ Render the replaceable, decorative checkmark used by a host to show that one opt
|
|
|
52
51
|
## Compatibility and migration
|
|
53
52
|
|
|
54
53
|
- Released default preserved: yes
|
|
55
|
-
- Compatibility class:
|
|
54
|
+
- Compatibility class: records shipped behavior; no public prop, default,
|
|
55
|
+
export, or DOM change
|
|
56
56
|
- Controlled/uncontrolled behavior: not applicable; `state` is supplied by the owner
|
|
57
57
|
- Migration decision: none; the public component and `check` registry name remain unchanged
|
|
58
58
|
|
|
@@ -68,29 +68,29 @@ Consumer migration instructions belong in consumer docs and release notes.
|
|
|
68
68
|
**Does not own / non-goals**
|
|
69
69
|
|
|
70
70
|
- Selection role, accessible name, state, focus, keyboard, activation, or busy semantics — owned by the composing control.
|
|
71
|
-
- Persistent checkbox or radio chrome — owned by `component:CheckboxIndicator` or `component:
|
|
71
|
+
- Persistent checkbox or radio chrome — owned by `component:CheckboxIndicator` or `component:Indicator`.
|
|
72
72
|
- Row placement and logical-edge layout — owned by the host component.
|
|
73
73
|
- The behavior or accessibility of consumer-supplied replacement content.
|
|
74
74
|
|
|
75
75
|
## Public concepts
|
|
76
76
|
|
|
77
|
-
| Concept | Closed values or states | Meaning | Availability by variant/orientation/state | Default | Owner | Stability
|
|
78
|
-
| ------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | ------------------ | -------------------------- |
|
|
79
|
-
| state | `unchecked`, `checked` | Selects whether the built-in check glyph is absent or present. | Every render path. | required | `component:CheckIndicator` | stable
|
|
80
|
-
| size | `sm`, `md` | Selects the shared indicator size; both current values use the `sm` Icon glyph. | Checked and replacement-content roots. | `md` | `component:CheckIndicator` | stable
|
|
81
|
-
| disabled appearance | enabled, disabled | Mirrors the owning control's disabled color without creating semantics. | Checked and replacement-content roots. | enabled | `component:CheckIndicator` | stable
|
|
82
|
-
| replacement content | shallow renderable or empty | Replaces the built-in mark in either state when `isRenderable(children)` returns true. React elements and containers take this branch even when descendants render nothing. | Every state; replacement content creates a span root. | built-in mark path | `component:CheckIndicator` |
|
|
77
|
+
| Concept | Closed values or states | Meaning | Availability by variant/orientation/state | Default | Owner | Stability | Invalid-value behavior |
|
|
78
|
+
| ------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | ------------------ | -------------------------- | ----------------------------------------- | -------------------------------------------------- |
|
|
79
|
+
| state | `unchecked`, `checked` | Selects whether the built-in check glyph is absent or present. | Every render path. | required | `component:CheckIndicator` | stable | rejected by the public type |
|
|
80
|
+
| size | `sm`, `md` | Selects the shared indicator size; both current values use the `sm` Icon glyph. | Checked and replacement-content roots. | `md` | `component:CheckIndicator` | stable | rejected by the public type |
|
|
81
|
+
| disabled appearance | enabled, disabled | Mirrors the owning control's disabled color without creating semantics. | Checked and replacement-content roots. | enabled | `component:CheckIndicator` | stable | boolean only |
|
|
82
|
+
| replacement content | shallow renderable or empty | Replaces the built-in mark in either state when `isRenderable(children)` returns true. React elements and containers take this branch even when descendants render nothing. | Every state; replacement content creates a span root. | built-in mark path | `component:CheckIndicator` | stable; empty-container policy open (OQ2) | unsupported values follow React rendering behavior |
|
|
83
83
|
|
|
84
84
|
## Behavioral and layout contract
|
|
85
85
|
|
|
86
|
-
| ID |
|
|
87
|
-
| --- |
|
|
88
|
-
| FR1 | The component MUST render one decorative check glyph when `state="checked"` and no replacement content is present, and MUST set its own `aria-hidden="true"` after caller passthrough.
|
|
89
|
-
| FR2 | The default component MUST render no element when `state="unchecked"` and no replacement content is present.
|
|
90
|
-
| FR3 |
|
|
91
|
-
| FR4 | Every rendered root MUST preserve supported DOM props, `className`, `style`, and `xstyle` while keeping component-owned accessibility precedence
|
|
92
|
-
| FR5 | The built-in checked mark MUST remain an Icon-owned painter on the same element as host-supplied classes; CheckIndicator MUST NOT add a wrapper or a distinct public target without an approved contract change.
|
|
93
|
-
| FR6 | Disabled color and replacement-content color MUST continue to use semantic tokens rather than raw color values.
|
|
86
|
+
| ID | Invariant | Basis |
|
|
87
|
+
| --- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ |
|
|
88
|
+
| FR1 | The component MUST render one decorative check glyph when `state="checked"` and no replacement content is present, and MUST set its own `aria-hidden="true"` after caller passthrough. | shipped source; `architecture:public-component-api/INV5` |
|
|
89
|
+
| FR2 | The default component MUST render no element when `state="unchecked"` and no replacement content is present. | shipped source, docs, tests, and stories |
|
|
90
|
+
| FR3 | Replacement uses shallow `isRenderable(children)` precedence in both states: nullish values, booleans, and the empty string keep the built-in state behavior; React elements and containers replace it even when descendants render nothing (OQ2). | shipped source and regression tests |
|
|
91
|
+
| FR4 | Every rendered root MUST preserve supported DOM props, `className`, `style`, and `xstyle` while keeping component-owned accessibility precedence, and the declared ref MUST reach the rendered root (`architecture:public-component-api/INV8`). Implementation gap: the replacement-content span receives the ref, but the checked Icon path drops it (OQ1). | `architecture:public-component-api/INV5,INV6,INV8`; current source |
|
|
92
|
+
| FR5 | The built-in checked mark MUST remain an Icon-owned painter on the same element as host-supplied classes; CheckIndicator MUST NOT add a wrapper or a distinct public target without an approved contract change. | shipped source; `architecture:component-theming-surface/INV3–INV5` |
|
|
93
|
+
| FR6 | Disabled color and replacement-content color MUST continue to use semantic tokens rather than raw color values. | shipped source; current token and theming architecture |
|
|
94
94
|
|
|
95
95
|
### Allowed variation
|
|
96
96
|
|
|
@@ -126,7 +126,7 @@ Consumer migration instructions belong in consumer docs and release notes.
|
|
|
126
126
|
| Chrome | CheckIndicator intentionally owns no persistent chrome. | observed shipped representation | not applicable | FR2, FR5 |
|
|
127
127
|
| State mark | Checked state renders the shared decorative check Icon. | Icon-owned current theming architecture | supporting state cue | FR1, FR5–FR6 |
|
|
128
128
|
|
|
129
|
-
The shared `Indicator.doc.mjs`
|
|
129
|
+
The shared `Indicator.doc.mjs` lists anatomy and targets for CheckboxIndicator, CheckIndicator, and RadioIndicator together, so this record carries no anatomy-theming map. CheckIndicator owns no persistent chrome and delegates its built-in checked mark to Icon.
|
|
130
130
|
|
|
131
131
|
## Family and system relationships
|
|
132
132
|
|
|
@@ -136,23 +136,28 @@ The shared `Indicator.doc.mjs` owns anatomy and targets for CheckboxIndicator, C
|
|
|
136
136
|
|
|
137
137
|
## Verification map
|
|
138
138
|
|
|
139
|
-
| Contract
|
|
140
|
-
|
|
|
141
|
-
| FR1
|
|
142
|
-
| FR1, AR1
|
|
143
|
-
| FR4
|
|
144
|
-
|
|
|
145
|
-
|
|
|
146
|
-
|
|
139
|
+
| Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
|
|
140
|
+
| ------------- | ------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ |
|
|
141
|
+
| FR1, FR2, FR3 | `Indicator.test.tsx` CheckIndicator state and replacement cases; falsy-children cases | Checked, unchecked, empty scalar, visible child, `0` | Removing the glyph, adding unchecked chrome, or choosing the wrong children branch fails. | `audit:CheckIndicator/behavior` |
|
|
142
|
+
| FR1, AR1 | `Indicator.test.tsx` decorative-contract cases | Glyph and replacement roots; a caller `aria-hidden={false}` | A root that a caller can expose fails. Evidence gap: no test asserts that replacement content is not the only state expression (AR2). | `audit:CheckIndicator/accessibility` |
|
|
143
|
+
| FR4 | `Indicator.test.tsx` "forwards caller props and styling on both render paths" | Both render paths | A caller DOM prop that stops reaching either root, or a `className` that stops reaching the replacement span, fails. Evidence gap: no test asserts `className`, `style`, or `xstyle` on the checked-glyph path, `style` or `xstyle` on the replacement span, or the ref on either path (the checked-path ref is the FR4 gap). | `audit:CheckIndicator/api` |
|
|
144
|
+
| FR5, FR6 | `themingTargets.test.ts` | Checked glyph | A rendered class absent from the documented targets fails. Evidence gap: no test asserts that no wrapper separates host classes from the Icon painter, or that disabled and replacement colors use semantic tokens. | `audit:CheckIndicator/theming` |
|
|
145
|
+
| ORD1, PR1 | Covered by the FR1–FR4 rows. Evidence gap: no test asserts the absence of state, effects, or listeners | — | — | `audit:CheckIndicator/behavior` |
|
|
146
|
+
|
|
147
|
+
## Current-state impact
|
|
148
|
+
|
|
149
|
+
- **Checked-path ref (FR4).** The declared ref is `null` when CheckIndicator
|
|
150
|
+
draws its checked glyph, against `architecture:public-component-api` INV8; the
|
|
151
|
+
fix is OQ1.
|
|
147
152
|
|
|
148
153
|
## Decision log
|
|
149
154
|
|
|
150
|
-
|
|
155
|
+
No component-local decision.
|
|
151
156
|
|
|
152
157
|
## Open questions
|
|
153
158
|
|
|
154
159
|
- **OQ1 — Should CheckIndicator preserve its declared `HTMLSpanElement` ref by owning a stable span root in the checked path, or should the public ref contract change to match the Icon-owned painter?** (`human-api`) The current checked path returns `null`; either correction changes a released DOM or ref contract.
|
|
155
|
-
- **OQ2 — Should empty React containers continue to suppress the built-in state mark?** (`human-api`)
|
|
160
|
+
- **OQ2 — Should empty React containers continue to suppress the built-in state mark?** (`human-api`) FR3 records that they do today.
|
|
156
161
|
|
|
157
162
|
## Content boundary
|
|
158
163
|
|
|
@@ -34,7 +34,8 @@ import * as stylex from '@stylexjs/stylex';
|
|
|
34
34
|
import type {SVGProps} from 'react';
|
|
35
35
|
import {Icon} from '../Icon/Icon';
|
|
36
36
|
import {colorVars} from '../theme/tokens.stylex';
|
|
37
|
-
import {isRenderable
|
|
37
|
+
import {isRenderable} from '../utils/isRenderable';
|
|
38
|
+
import {mergeProps} from '../utils/mergeProps';
|
|
38
39
|
import type {IndicatorProps} from './types';
|
|
39
40
|
|
|
40
41
|
/** The check glyph matches the control sizes the indicator families share. */
|