@astryxdesign/core 0.1.2 → 0.1.3-canary.6d57c8d
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +165 -0
- package/README.md +12 -12
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +11 -5
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.js +24 -5
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +2 -4
- package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
- package/dist/ButtonGroup/ButtonGroup.js +0 -1
- package/dist/Calendar/Calendar.d.ts +5 -4
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +82 -43
- package/dist/Calendar/hooks/index.d.ts +0 -2
- package/dist/Calendar/hooks/index.d.ts.map +1 -1
- package/dist/Calendar/hooks/index.js +1 -2
- package/dist/Calendar/index.d.ts +3 -3
- package/dist/Calendar/index.d.ts.map +1 -1
- package/dist/Calendar/index.js +1 -1
- package/dist/Calendar/styles.d.ts +3 -9
- package/dist/Calendar/styles.d.ts.map +1 -1
- package/dist/Calendar/styles.js +3 -11
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +17 -3
- package/dist/Center/Center.d.ts +11 -1
- package/dist/Center/Center.d.ts.map +1 -1
- package/dist/Center/Center.js +9 -3
- package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
- package/dist/Chat/ChatComposerInput.js +0 -1
- package/dist/Chat/ChatMessageList.d.ts +14 -1
- package/dist/Chat/ChatMessageList.d.ts.map +1 -1
- package/dist/Chat/ChatMessageList.js +2 -0
- package/dist/Chat/useTriggerMenu.d.ts +8 -1
- package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
- package/dist/Chat/useTriggerMenu.js +15 -3
- package/dist/CheckboxInput/CheckboxInput.d.ts +23 -2
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +51 -9
- package/dist/CheckboxList/CheckboxList.d.ts +13 -1
- package/dist/CheckboxList/CheckboxList.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxList.js +39 -9
- package/dist/CheckboxList/CheckboxListContext.d.ts +7 -0
- package/dist/CheckboxList/CheckboxListContext.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxListItem.js +0 -1
- package/dist/Citation/Citation.d.ts.map +1 -1
- package/dist/Citation/Citation.js +9 -5
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +51 -37
- package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPalette.js +5 -5
- package/dist/ContextMenu/ContextMenu.d.ts +4 -5
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +93 -11
- package/dist/DateInput/DateInput.d.ts +23 -1
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +167 -99
- package/dist/DateRangeInput/DateRangeInput.d.ts +23 -1
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +42 -9
- package/dist/DateTimeInput/DateTimeInput.d.ts +35 -2
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +78 -15
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +12 -0
- package/dist/DropdownMenu/DropdownMenu.d.ts +1 -8
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +42 -14
- package/dist/Field/Field.d.ts +19 -2
- package/dist/Field/Field.d.ts.map +1 -1
- package/dist/Field/Field.js +4 -0
- package/dist/Field/FieldLabel.d.ts +21 -2
- package/dist/Field/FieldLabel.d.ts.map +1 -1
- package/dist/Field/FieldLabel.js +41 -26
- package/dist/FileInput/FileInput.d.ts +22 -1
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +56 -10
- package/dist/Grid/Grid.d.ts +11 -1
- package/dist/Grid/Grid.d.ts.map +1 -1
- package/dist/Grid/Grid.js +32 -6
- package/dist/InputGroup/InputGroup.d.ts +4 -3
- package/dist/InputGroup/InputGroup.d.ts.map +1 -1
- package/dist/InputGroup/InputGroup.js +16 -6
- package/dist/InputGroup/InputGroupContext.d.ts +4 -0
- package/dist/InputGroup/InputGroupContext.d.ts.map +1 -1
- package/dist/InputGroup/InputGroupContext.js +2 -2
- package/dist/InputGroup/groupStyles.d.ts +1 -1
- package/dist/InputGroup/groupStyles.d.ts.map +1 -1
- package/dist/InputGroup/groupStyles.js +3 -3
- package/dist/InputGroup/index.d.ts +1 -0
- package/dist/InputGroup/index.d.ts.map +1 -1
- package/dist/Kbd/Kbd.d.ts.map +1 -1
- package/dist/Kbd/Kbd.js +33 -1
- package/dist/Layer/layerAnimations.stylex.d.ts +4 -0
- package/dist/Layer/layerAnimations.stylex.d.ts.map +1 -1
- package/dist/Layer/layerAnimations.stylex.js +8 -4
- package/dist/Layer/useLayer.d.ts +10 -0
- package/dist/Layer/useLayer.d.ts.map +1 -1
- package/dist/Layer/useLayer.js +64 -9
- package/dist/Layout/Layout.d.ts +4 -11
- package/dist/Layout/Layout.d.ts.map +1 -1
- package/dist/Layout/Layout.js +10 -11
- package/dist/Layout/LayoutFooter.d.ts +2 -2
- package/dist/Layout/LayoutFooter.d.ts.map +1 -1
- package/dist/Layout/LayoutHeader.d.ts +2 -2
- package/dist/Layout/LayoutHeader.d.ts.map +1 -1
- package/dist/Layout/LayoutPanel.d.ts +2 -2
- package/dist/Layout/LayoutPanel.d.ts.map +1 -1
- package/dist/Layout/padding.stylex.d.ts +51 -0
- package/dist/Layout/padding.stylex.d.ts.map +1 -1
- package/dist/Layout/padding.stylex.js +63 -0
- package/dist/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/Lightbox/Lightbox.js +4 -2
- package/dist/Link/Link.d.ts +16 -1
- package/dist/Link/Link.d.ts.map +1 -1
- package/dist/Link/Link.js +18 -7
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.js +7 -0
- package/dist/MoreMenu/MoreMenu.d.ts +1 -7
- package/dist/MoreMenu/MoreMenu.d.ts.map +1 -1
- package/dist/MoreMenu/MoreMenu.js +0 -2
- package/dist/MultiSelector/MultiSelector.d.ts +27 -2
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +141 -42
- package/dist/MultiSelector/hooks.d.ts +12 -1
- package/dist/MultiSelector/hooks.d.ts.map +1 -1
- package/dist/MultiSelector/hooks.js +14 -1
- package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
- package/dist/NavMenu/NavHeadingMenu.js +34 -3
- package/dist/NumberInput/NumberInput.d.ts +23 -2
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +62 -12
- package/dist/Pagination/Pagination.d.ts +1 -1
- package/dist/Pagination/Pagination.d.ts.map +1 -1
- package/dist/Pagination/Pagination.js +15 -1
- package/dist/Popover/Popover.d.ts +18 -2
- package/dist/Popover/Popover.d.ts.map +1 -1
- package/dist/Popover/Popover.js +5 -2
- package/dist/Popover/usePopover.d.ts +38 -3
- package/dist/Popover/usePopover.d.ts.map +1 -1
- package/dist/Popover/usePopover.js +24 -9
- package/dist/PowerSearch/PowerSearch.d.ts +11 -1
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +6 -1
- package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
- package/dist/ProgressBar/ProgressBar.js +3 -5
- package/dist/RadioList/RadioList.d.ts +20 -2
- package/dist/RadioList/RadioList.d.ts.map +1 -1
- package/dist/RadioList/RadioList.js +105 -9
- package/dist/RadioList/RadioListItem.d.ts.map +1 -1
- package/dist/RadioList/RadioListItem.js +13 -2
- package/dist/SegmentedControl/SegmentedControl.d.ts +13 -2
- package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControl.js +78 -44
- package/dist/SegmentedControl/SegmentedControlContext.d.ts +7 -0
- package/dist/SegmentedControl/SegmentedControlContext.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.js +13 -2
- package/dist/Selector/Selector.d.ts +24 -1
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +122 -43
- package/dist/Selector/hooks.d.ts +8 -1
- package/dist/Selector/hooks.d.ts.map +1 -1
- package/dist/Selector/hooks.js +14 -1
- package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
- package/dist/SideNav/SideNavHeading.js +2 -0
- package/dist/SideNav/SideNavItem.d.ts.map +1 -1
- package/dist/SideNav/SideNavItem.js +1 -1
- package/dist/Skeleton/Skeleton.d.ts.map +1 -1
- package/dist/Skeleton/Skeleton.js +8 -2
- package/dist/Slider/Slider.d.ts +21 -0
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +36 -9
- package/dist/Spinner/Spinner.d.ts.map +1 -1
- package/dist/Spinner/Spinner.js +1 -1
- package/dist/Stack/Stack.d.ts +38 -23
- package/dist/Stack/Stack.d.ts.map +1 -1
- package/dist/Stack/Stack.js +25 -1
- package/dist/Stack/StackItem.d.ts +12 -23
- package/dist/Stack/StackItem.d.ts.map +1 -1
- package/dist/Stack/StackItem.js +8 -1
- package/dist/Switch/Switch.d.ts +23 -2
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +41 -11
- package/dist/TabList/Tab.d.ts.map +1 -1
- package/dist/TabList/Tab.js +6 -0
- package/dist/TabList/TabList.d.ts +16 -4
- package/dist/TabList/TabList.d.ts.map +1 -1
- package/dist/TabList/TabList.js +87 -10
- package/dist/TabList/TabListContext.d.ts +5 -0
- package/dist/TabList/TabListContext.d.ts.map +1 -1
- package/dist/TabList/TabListContext.js +5 -0
- package/dist/TabList/TabMenu.d.ts.map +1 -1
- package/dist/TabList/TabMenu.js +6 -1
- package/dist/Table/BaseTable.d.ts.map +1 -1
- package/dist/Table/BaseTable.js +11 -8
- package/dist/Table/Table.d.ts.map +1 -1
- package/dist/Table/Table.js +10 -1
- package/dist/Table/TableCell.d.ts +8 -1
- package/dist/Table/TableCell.d.ts.map +1 -1
- package/dist/Table/TableCell.js +10 -10
- package/dist/Table/TableHeaderCell.d.ts +8 -1
- package/dist/Table/TableHeaderCell.d.ts.map +1 -1
- package/dist/Table/TableHeaderCell.js +16 -16
- package/dist/Table/index.d.ts +2 -1
- package/dist/Table/index.d.ts.map +1 -1
- package/dist/Table/index.js +2 -2
- package/dist/Table/plugins/pagination/paginateData.d.ts +2 -1
- package/dist/Table/plugins/pagination/paginateData.d.ts.map +1 -1
- package/dist/Table/plugins/pagination/paginateData.js +8 -3
- package/dist/Table/plugins/pagination/useTablePagination.d.ts.map +1 -1
- package/dist/Table/plugins/pagination/useTablePagination.js +6 -1
- package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
- package/dist/Table/plugins/sortable/useTableSortable.js +59 -3
- package/dist/Table/tableContextMenu.d.ts +33 -0
- package/dist/Table/tableContextMenu.d.ts.map +1 -0
- package/dist/Table/tableContextMenu.js +133 -0
- package/dist/Table/types.d.ts +66 -0
- package/dist/Table/types.d.ts.map +1 -1
- package/dist/TextArea/TextArea.d.ts +22 -1
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +41 -9
- package/dist/TextInput/TextInput.d.ts +23 -2
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +55 -10
- package/dist/TimeInput/TimeInput.d.ts +23 -1
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +147 -76
- package/dist/Toast/Toast.d.ts.map +1 -1
- package/dist/Toast/Toast.js +14 -0
- package/dist/Toast/ToastViewport.d.ts.map +1 -1
- package/dist/Toast/ToastViewport.js +131 -3
- package/dist/Tokenizer/Tokenizer.d.ts +12 -1
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +26 -4
- package/dist/Toolbar/Toolbar.d.ts +3 -3
- package/dist/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/Toolbar/Toolbar.js +51 -7
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +56 -9
- package/dist/TopNav/TopNavHeading.d.ts +7 -1
- package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
- package/dist/TopNav/TopNavHeading.js +8 -0
- package/dist/TreeList/TreeList.d.ts +1 -1
- package/dist/TreeList/TreeList.d.ts.map +1 -1
- package/dist/TreeList/TreeList.js +72 -2
- package/dist/TreeList/TreeListItem.d.ts +11 -1
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +51 -12
- package/dist/TreeList/treeListItem.markers.stylex.d.ts +16 -0
- package/dist/TreeList/treeListItem.markers.stylex.d.ts.map +1 -0
- package/dist/TreeList/treeListItem.markers.stylex.js +22 -0
- package/dist/Typeahead/BaseTypeahead.d.ts +13 -0
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +69 -6
- package/dist/Typeahead/Typeahead.d.ts +26 -3
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +65 -29
- package/dist/VisuallyHidden/VisuallyHidden.d.ts +61 -0
- package/dist/VisuallyHidden/VisuallyHidden.d.ts.map +1 -0
- package/dist/VisuallyHidden/VisuallyHidden.js +65 -0
- package/dist/VisuallyHidden/index.d.ts +11 -0
- package/dist/VisuallyHidden/index.d.ts.map +1 -0
- package/dist/VisuallyHidden/index.js +13 -0
- package/dist/astryx.css +18 -0
- package/dist/astryx.umd.js +55 -55
- package/dist/astryx.umd.js.map +4 -4
- package/dist/hooks/focusableSelector.d.ts +22 -0
- package/dist/hooks/focusableSelector.d.ts.map +1 -0
- package/dist/hooks/focusableSelector.js +24 -0
- package/dist/hooks/index.d.ts +12 -2
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +7 -2
- package/dist/hooks/useAnnounce.d.ts +40 -0
- package/dist/hooks/useAnnounce.d.ts.map +1 -0
- package/dist/hooks/useAnnounce.js +142 -0
- package/dist/hooks/useClickableContainer.d.ts +16 -1
- package/dist/hooks/useClickableContainer.d.ts.map +1 -1
- package/dist/hooks/useClickableContainer.js +16 -4
- package/dist/hooks/useEntryAnimation.d.ts.map +1 -1
- package/dist/hooks/useEntryAnimation.js +4 -4
- package/dist/hooks/useFocusTrap.d.ts +18 -0
- package/dist/hooks/useFocusTrap.d.ts.map +1 -1
- package/dist/hooks/useFocusTrap.js +87 -3
- package/dist/hooks/useGridFocus.d.ts +88 -1
- package/dist/hooks/useGridFocus.d.ts.map +1 -1
- package/dist/hooks/useGridFocus.js +261 -62
- package/dist/hooks/useKeyboardHint.d.ts +82 -0
- package/dist/hooks/useKeyboardHint.d.ts.map +1 -0
- package/dist/hooks/useKeyboardHint.js +220 -0
- package/dist/hooks/useListFocus.d.ts +78 -7
- package/dist/hooks/useListFocus.d.ts.map +1 -1
- package/dist/hooks/useListFocus.js +305 -52
- package/dist/hooks/useLongPress.d.ts +21 -0
- package/dist/hooks/useLongPress.d.ts.map +1 -0
- package/dist/hooks/useLongPress.js +89 -0
- package/dist/hooks/useTreeFocus.d.ts +157 -0
- package/dist/hooks/useTreeFocus.d.ts.map +1 -0
- package/dist/hooks/useTreeFocus.js +337 -0
- package/dist/hooks/useTypeahead.d.ts +63 -0
- package/dist/hooks/useTypeahead.d.ts.map +1 -0
- package/dist/hooks/useTypeahead.js +117 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/utils/dateTypes.d.ts +12 -0
- package/dist/utils/dateTypes.d.ts.map +1 -1
- package/dist/utils/dateTypes.js +41 -1
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +3 -1
- package/dist/utils/inputAria.d.ts +29 -0
- package/dist/utils/inputAria.d.ts.map +1 -0
- package/dist/utils/inputAria.js +30 -0
- package/dist/utils/timeParser.d.ts.map +1 -1
- package/dist/utils/timeParser.js +5 -2
- package/docs.mjs +2 -2
- package/package.json +12 -8
- package/src/Avatar/Avatar.test.tsx +37 -0
- package/src/Avatar/Avatar.tsx +10 -5
- package/src/Breadcrumbs/BreadcrumbItem.tsx +25 -7
- package/src/Breadcrumbs/Breadcrumbs.test.tsx +31 -10
- package/src/Button/Button.tsx +3 -16
- package/src/ButtonGroup/ButtonGroup.test.tsx +9 -9
- package/src/ButtonGroup/ButtonGroup.tsx +0 -1
- package/src/Calendar/Calendar.doc.mjs +4 -4
- package/src/Calendar/Calendar.test.tsx +168 -30
- package/src/Calendar/Calendar.tsx +121 -66
- package/src/Calendar/hooks/index.ts +0 -6
- package/src/Calendar/index.ts +1 -3
- package/src/Calendar/styles.ts +4 -9
- package/src/Carousel/Carousel.doc.mjs +7 -1
- package/src/Carousel/Carousel.test.tsx +20 -0
- package/src/Carousel/Carousel.tsx +16 -1
- package/src/Center/Center.doc.mjs +12 -2
- package/src/Center/Center.tsx +28 -3
- package/src/Chat/ChatComposerInput.test.tsx +26 -7
- package/src/Chat/ChatComposerInput.tsx +0 -1
- package/src/Chat/ChatDictationButton.doc.mjs +1 -1
- package/src/Chat/ChatMessageList.doc.mjs +8 -0
- package/src/Chat/ChatMessageList.test.tsx +18 -0
- package/src/Chat/ChatMessageList.tsx +16 -0
- package/src/Chat/useTriggerMenu.tsx +22 -4
- package/src/CheckboxInput/CheckboxInput.doc.mjs +10 -0
- package/src/CheckboxInput/CheckboxInput.test.tsx +172 -27
- package/src/CheckboxInput/CheckboxInput.tsx +78 -6
- package/src/CheckboxList/CheckboxList.doc.mjs +9 -0
- package/src/CheckboxList/CheckboxList.test.tsx +192 -26
- package/src/CheckboxList/CheckboxList.tsx +56 -3
- package/src/CheckboxList/CheckboxListContext.tsx +7 -0
- package/src/CheckboxList/CheckboxListItem.tsx +0 -3
- package/src/Citation/Citation.doc.mjs +10 -0
- package/src/Citation/Citation.test.tsx +121 -0
- package/src/Citation/Citation.tsx +15 -3
- package/src/CodeBlock/CodeBlock.test.tsx +115 -0
- package/src/CodeBlock/CodeBlock.tsx +63 -33
- package/src/CommandPalette/CommandPalette.test.tsx +47 -1
- package/src/CommandPalette/CommandPalette.tsx +9 -21
- package/src/ContextMenu/ContextMenu.doc.mjs +4 -4
- package/src/ContextMenu/ContextMenu.test.tsx +155 -1
- package/src/ContextMenu/ContextMenu.tsx +113 -16
- package/src/DateInput/DateInput.doc.mjs +286 -56
- package/src/DateInput/DateInput.test.tsx +248 -2
- package/src/DateInput/DateInput.tsx +196 -100
- package/src/DateRangeInput/DateRangeInput.doc.mjs +251 -46
- package/src/DateRangeInput/DateRangeInput.test.tsx +182 -20
- package/src/DateRangeInput/DateRangeInput.tsx +63 -5
- package/src/DateTimeInput/DateTimeInput.doc.mjs +368 -67
- package/src/DateTimeInput/DateTimeInput.test.tsx +279 -11
- package/src/DateTimeInput/DateTimeInput.tsx +125 -17
- package/src/Dialog/Dialog.doc.mjs +2 -2
- package/src/Dialog/Dialog.tsx +12 -0
- package/src/DropdownMenu/DropdownMenu.doc.mjs +1 -8
- package/src/DropdownMenu/DropdownMenu.test.tsx +56 -42
- package/src/DropdownMenu/DropdownMenu.tsx +52 -18
- package/src/Field/Field.doc.mjs +59 -18
- package/src/Field/Field.test.tsx +32 -0
- package/src/Field/Field.tsx +23 -5
- package/src/Field/FieldLabel.tsx +55 -17
- package/src/FileInput/FileInput.doc.mjs +17 -0
- package/src/FileInput/FileInput.test.tsx +283 -49
- package/src/FileInput/FileInput.tsx +76 -4
- package/src/Grid/Grid.doc.mjs +17 -4
- package/src/Grid/Grid.test.tsx +43 -30
- package/src/Grid/Grid.tsx +38 -3
- package/src/Icon/Icon.doc.mjs +3 -3
- package/src/InputGroup/InputGroup.doc.mjs +111 -23
- package/src/InputGroup/InputGroup.test.tsx +257 -60
- package/src/InputGroup/InputGroup.tsx +23 -5
- package/src/InputGroup/InputGroupContext.ts +9 -4
- package/src/InputGroup/groupStyles.ts +7 -1
- package/src/InputGroup/index.ts +1 -0
- package/src/Kbd/Kbd.test.tsx +22 -4
- package/src/Kbd/Kbd.tsx +35 -3
- package/src/Layer/layerAnimations.stylex.ts +20 -4
- package/src/Layer/useLayer.doc.mjs +5 -0
- package/src/Layer/useLayer.test.tsx +111 -0
- package/src/Layer/useLayer.tsx +90 -9
- package/src/Layout/Layout.tsx +8 -16
- package/src/Layout/LayoutFooter.doc.mjs +4 -4
- package/src/Layout/LayoutFooter.tsx +3 -3
- package/src/Layout/LayoutHeader.doc.mjs +4 -4
- package/src/Layout/LayoutHeader.tsx +3 -3
- package/src/Layout/LayoutPanel.tsx +3 -3
- package/src/Layout/padding.stylex.ts +52 -0
- package/src/Lightbox/Lightbox.doc.mjs +9 -0
- package/src/Lightbox/Lightbox.test.tsx +53 -5
- package/src/Lightbox/Lightbox.tsx +9 -4
- package/src/Link/Link.doc.mjs +14 -0
- package/src/Link/Link.test.tsx +50 -0
- package/src/Link/Link.tsx +39 -4
- package/src/Markdown/Markdown.test.tsx +11 -0
- package/src/Markdown/Markdown.tsx +7 -0
- package/src/MetadataList/MetadataListItem.doc.mjs +4 -0
- package/src/MoreMenu/MoreMenu.doc.mjs +2 -17
- package/src/MoreMenu/MoreMenu.tsx +0 -9
- package/src/MultiSelector/MultiSelector.doc.mjs +30 -0
- package/src/MultiSelector/MultiSelector.test.tsx +375 -8
- package/src/MultiSelector/MultiSelector.tsx +194 -48
- package/src/MultiSelector/hooks.ts +27 -0
- package/src/NavMenu/NavHeadingMenu.test.tsx +77 -1
- package/src/NavMenu/NavHeadingMenu.tsx +50 -3
- package/src/NumberInput/NumberInput.doc.mjs +17 -0
- package/src/NumberInput/NumberInput.test.tsx +242 -40
- package/src/NumberInput/NumberInput.tsx +89 -11
- package/src/Pagination/Pagination.doc.mjs +3 -3
- package/src/Pagination/Pagination.test.tsx +117 -5
- package/src/Pagination/Pagination.tsx +21 -1
- package/src/Popover/Popover.doc.mjs +26 -0
- package/src/Popover/Popover.test.tsx +121 -0
- package/src/Popover/Popover.tsx +23 -2
- package/src/Popover/usePopover.doc.mjs +9 -3
- package/src/Popover/usePopover.tsx +70 -12
- package/src/PowerSearch/PowerSearch.doc.mjs +15 -0
- package/src/PowerSearch/PowerSearch.test.tsx +97 -1
- package/src/PowerSearch/PowerSearch.tsx +16 -3
- package/src/ProgressBar/ProgressBar.test.tsx +34 -26
- package/src/ProgressBar/ProgressBar.tsx +3 -4
- package/src/RadioList/RadioList.doc.mjs +9 -0
- package/src/RadioList/RadioList.test.tsx +252 -16
- package/src/RadioList/RadioList.tsx +166 -10
- package/src/RadioList/RadioListItem.tsx +14 -2
- package/src/SegmentedControl/SegmentedControl.doc.mjs +9 -0
- package/src/SegmentedControl/SegmentedControl.test.tsx +214 -42
- package/src/SegmentedControl/SegmentedControl.tsx +102 -54
- package/src/SegmentedControl/SegmentedControlContext.ts +7 -0
- package/src/SegmentedControl/SegmentedControlItem.tsx +14 -1
- package/src/SelectableCard/SelectableCard.doc.mjs +1 -1
- package/src/Selector/Selector.doc.mjs +26 -0
- package/src/Selector/Selector.test.tsx +387 -15
- package/src/Selector/Selector.tsx +175 -67
- package/src/Selector/hooks.ts +23 -0
- package/src/SideNav/SideNav.test.tsx +48 -0
- package/src/SideNav/SideNavHeading.tsx +8 -2
- package/src/SideNav/SideNavItem.tsx +2 -4
- package/src/Skeleton/Skeleton.test.tsx +25 -0
- package/src/Skeleton/Skeleton.tsx +11 -1
- package/src/Slider/Slider.doc.mjs +15 -0
- package/src/Slider/Slider.test.tsx +155 -2
- package/src/Slider/Slider.tsx +53 -5
- package/src/Spinner/Spinner.tsx +7 -1
- package/src/Stack/Stack.doc.mjs +77 -0
- package/src/Stack/Stack.test.tsx +55 -5
- package/src/Stack/Stack.tsx +73 -24
- package/src/Stack/StackItem.test.tsx +23 -0
- package/src/Stack/StackItem.tsx +20 -23
- package/src/Switch/Switch.doc.mjs +15 -0
- package/src/Switch/Switch.test.tsx +162 -27
- package/src/Switch/Switch.tsx +61 -21
- package/src/TabList/Tab.tsx +6 -0
- package/src/TabList/TabList.doc.mjs +6 -0
- package/src/TabList/TabList.test.tsx +251 -0
- package/src/TabList/TabList.tsx +103 -12
- package/src/TabList/TabListContext.ts +7 -3
- package/src/TabList/TabMenu.tsx +6 -3
- package/src/Table/BaseTable.tsx +21 -17
- package/src/Table/Table.doc.mjs +2 -0
- package/src/Table/Table.test.tsx +10 -0
- package/src/Table/Table.tsx +8 -0
- package/src/Table/TableCell.tsx +25 -23
- package/src/Table/TableHeaderCell.tsx +28 -29
- package/src/Table/index.ts +3 -2
- package/src/Table/plugins/pagination/paginateData.ts +10 -3
- package/src/Table/plugins/pagination/useTablePagination.test.tsx +16 -0
- package/src/Table/plugins/pagination/useTablePagination.tsx +8 -1
- package/src/Table/plugins/sortable/useTableSortable.test.tsx +91 -2
- package/src/Table/plugins/sortable/useTableSortable.tsx +53 -1
- package/src/Table/tableContextMenu.test.tsx +157 -0
- package/src/Table/tableContextMenu.tsx +142 -0
- package/src/Table/types.ts +74 -0
- package/src/Table/useTableColumnResize.doc.mjs +3 -3
- package/src/Table/useTableStickyColumns.doc.mjs +2 -2
- package/src/Text/Text.doc.mjs +18 -18
- package/src/TextArea/TextArea.doc.mjs +17 -0
- package/src/TextArea/TextArea.test.tsx +167 -35
- package/src/TextArea/TextArea.tsx +62 -15
- package/src/TextInput/TextInput.doc.mjs +17 -0
- package/src/TextInput/TextInput.test.tsx +168 -34
- package/src/TextInput/TextInput.tsx +77 -9
- package/src/Thumbnail/Thumbnail.doc.mjs +4 -4
- package/src/TimeInput/TimeInput.doc.mjs +340 -60
- package/src/TimeInput/TimeInput.test.tsx +255 -7
- package/src/TimeInput/TimeInput.tsx +176 -70
- package/src/Timestamp/Timestamp.doc.mjs +19 -19
- package/src/Toast/Toast.tsx +14 -0
- package/src/Toast/ToastViewport.test.tsx +214 -0
- package/src/Toast/ToastViewport.tsx +167 -21
- package/src/Tokenizer/Tokenizer.doc.mjs +29 -14
- package/src/Tokenizer/Tokenizer.test.tsx +105 -1
- package/src/Tokenizer/Tokenizer.tsx +37 -1
- package/src/Toolbar/Toolbar.test.tsx +109 -6
- package/src/Toolbar/Toolbar.tsx +59 -5
- package/src/Tooltip/Tooltip.test.tsx +68 -0
- package/src/Tooltip/useTooltip.tsx +55 -8
- package/src/TopNav/TopNav.test.tsx +50 -0
- package/src/TopNav/TopNavHeading.tsx +17 -1
- package/src/TreeList/TreeList.test.tsx +295 -6
- package/src/TreeList/TreeList.tsx +73 -1
- package/src/TreeList/TreeListItem.tsx +51 -5
- package/src/TreeList/treeListItem.markers.stylex.ts +20 -0
- package/src/Typeahead/BaseTypeahead.tsx +93 -9
- package/src/Typeahead/Typeahead.doc.mjs +141 -30
- package/src/Typeahead/Typeahead.test.tsx +331 -1
- package/src/Typeahead/Typeahead.tsx +105 -33
- package/src/VisuallyHidden/VisuallyHidden.doc.mjs +80 -0
- package/src/VisuallyHidden/VisuallyHidden.test.tsx +76 -0
- package/src/VisuallyHidden/VisuallyHidden.tsx +113 -0
- package/src/VisuallyHidden/index.ts +15 -0
- package/src/docs-script.test.mjs +50 -0
- package/src/hooks/focusableSelector.ts +25 -0
- package/src/hooks/index.ts +28 -2
- package/src/hooks/useAnnounce.test.tsx +101 -0
- package/src/hooks/useAnnounce.ts +168 -0
- package/src/hooks/useClickableContainer.ts +16 -4
- package/src/hooks/useEntryAnimation.ts +16 -4
- package/src/hooks/useFocusTrap.test.tsx +132 -0
- package/src/hooks/useFocusTrap.ts +98 -4
- package/src/hooks/useGridFocus.doc.mjs +40 -2
- package/src/hooks/useGridFocus.test.tsx +132 -0
- package/src/hooks/useGridFocus.ts +343 -67
- package/src/hooks/useKeyboardHint.doc.mjs +101 -0
- package/src/hooks/useKeyboardHint.test.tsx +70 -0
- package/src/hooks/useKeyboardHint.tsx +332 -0
- package/src/hooks/useListFocus.doc.mjs +50 -10
- package/src/hooks/useListFocus.test.tsx +375 -0
- package/src/hooks/useListFocus.ts +395 -57
- package/src/hooks/useLongPress.test.tsx +134 -0
- package/src/hooks/useLongPress.ts +119 -0
- package/src/hooks/useTreeFocus.doc.mjs +140 -0
- package/src/hooks/useTreeFocus.test.tsx +214 -0
- package/src/hooks/useTreeFocus.ts +559 -0
- package/src/hooks/useTypeahead.test.tsx +109 -0
- package/src/hooks/useTypeahead.ts +183 -0
- package/src/index.ts +1 -0
- package/src/theme/derivedVarRegistry.test.ts +10 -5
- package/src/utils/dateTypes.test.ts +40 -0
- package/src/utils/dateTypes.ts +40 -0
- package/src/utils/index.ts +9 -0
- package/src/utils/inputAria.test.ts +39 -0
- package/src/utils/inputAria.ts +58 -0
- package/src/utils/timeParser.test.ts +10 -0
- package/src/utils/timeParser.ts +5 -2
- package/dist/Calendar/hooks/useCalendarRovingTabindex.d.ts +0 -57
- package/dist/Calendar/hooks/useCalendarRovingTabindex.d.ts.map +0 -1
- package/dist/Calendar/hooks/useCalendarRovingTabindex.js +0 -96
- package/src/Calendar/hooks/useCalendarRovingTabindex.ts +0 -118
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file VisuallyHidden.test.tsx
|
|
5
|
+
* @input Uses vitest, @testing-library/react, VisuallyHidden component
|
|
6
|
+
* @output Unit tests for VisuallyHidden rendering + a11y behavior
|
|
7
|
+
* @position Testing; validates VisuallyHidden.tsx implementation
|
|
8
|
+
*
|
|
9
|
+
* SYNC: When VisuallyHidden.tsx changes, update tests to match new behavior
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import {describe, it, expect} from 'vitest';
|
|
13
|
+
import {render, screen} from '@testing-library/react';
|
|
14
|
+
import {createRef} from 'react';
|
|
15
|
+
import {VisuallyHidden} from './VisuallyHidden';
|
|
16
|
+
|
|
17
|
+
describe('VisuallyHidden', () => {
|
|
18
|
+
it('renders its children in the accessibility tree', () => {
|
|
19
|
+
render(<VisuallyHidden>Delete incident</VisuallyHidden>);
|
|
20
|
+
// Present in the a11y tree (getByText finds it — it is not display:none).
|
|
21
|
+
expect(screen.getByText('Delete incident')).toBeInTheDocument();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('renders a <span> by default', () => {
|
|
25
|
+
render(<VisuallyHidden>Label</VisuallyHidden>);
|
|
26
|
+
expect(screen.getByText('Label').tagName).toBe('SPAN');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('renders a custom element via the `as` prop', () => {
|
|
30
|
+
render(
|
|
31
|
+
<VisuallyHidden as="div" aria-live="polite">
|
|
32
|
+
Moved task to Done
|
|
33
|
+
</VisuallyHidden>,
|
|
34
|
+
);
|
|
35
|
+
const el = screen.getByText('Moved task to Done');
|
|
36
|
+
expect(el.tagName).toBe('DIV');
|
|
37
|
+
expect(el).toHaveAttribute('aria-live', 'polite');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('applies the clip styles that hide it visually', () => {
|
|
41
|
+
render(<VisuallyHidden>Hidden</VisuallyHidden>);
|
|
42
|
+
const el = screen.getByText('Hidden');
|
|
43
|
+
// jsdom does not apply the stylesheet, but the StyleX class is attached.
|
|
44
|
+
expect(el.getAttribute('class')).toBeTruthy();
|
|
45
|
+
// It must NOT be display:none / hidden — it stays in the a11y tree.
|
|
46
|
+
expect(el).not.toHaveAttribute('hidden');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('forwards a ref to the rendered element', () => {
|
|
50
|
+
const ref = createRef<HTMLElement>();
|
|
51
|
+
render(<VisuallyHidden ref={ref}>Ref target</VisuallyHidden>);
|
|
52
|
+
expect(ref.current).toBeInstanceOf(HTMLElement);
|
|
53
|
+
expect(ref.current?.textContent).toBe('Ref target');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('passes through arbitrary BaseProps (id, role, data-*)', () => {
|
|
57
|
+
render(
|
|
58
|
+
<VisuallyHidden id="announcer" role="status" data-testid="vh">
|
|
59
|
+
Status
|
|
60
|
+
</VisuallyHidden>,
|
|
61
|
+
);
|
|
62
|
+
const el = screen.getByTestId('vh');
|
|
63
|
+
expect(el).toHaveAttribute('id', 'announcer');
|
|
64
|
+
expect(el).toHaveAttribute('role', 'status');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('gives an icon-only control an accessible name', () => {
|
|
68
|
+
render(
|
|
69
|
+
<button type="button">
|
|
70
|
+
<span aria-hidden="true">🗑️</span>
|
|
71
|
+
<VisuallyHidden>Delete</VisuallyHidden>
|
|
72
|
+
</button>,
|
|
73
|
+
);
|
|
74
|
+
expect(screen.getByRole('button', {name: 'Delete'})).toBeInTheDocument();
|
|
75
|
+
});
|
|
76
|
+
});
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @file VisuallyHidden.tsx
|
|
7
|
+
* @input Uses React createElement/ElementType, stylex
|
|
8
|
+
* @output Exports VisuallyHidden component and VisuallyHiddenProps
|
|
9
|
+
* @position Accessibility primitive; renders content in the a11y tree while
|
|
10
|
+
* hiding it visually (icon-only labels, aria-live regions, SR-only context)
|
|
11
|
+
*
|
|
12
|
+
* SYNC: When modified, update these files to stay in sync:
|
|
13
|
+
* - /packages/core/src/VisuallyHidden/VisuallyHidden.doc.mjs
|
|
14
|
+
* - /packages/core/src/VisuallyHidden/VisuallyHidden.test.tsx
|
|
15
|
+
* - /apps/storybook/stories/VisuallyHidden.stories.tsx
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import {createElement, type ElementType, type ReactNode, type Ref} from 'react';
|
|
19
|
+
import type {BaseProps} from '../BaseProps';
|
|
20
|
+
import * as stylex from '@stylexjs/stylex';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* VisuallyHidden is deliberately styling-free: it exists to *not* be seen, so it
|
|
24
|
+
* intentionally omits `xstyle`/`className`/`style`. The clip block is fixed and
|
|
25
|
+
* non-overridable — styling a visually-hidden node is always a mistake. The
|
|
26
|
+
* accessibility pass-throughs from `BaseProps` (`aria-*`, `role`, `id`,
|
|
27
|
+
* `data-*`, event handlers) remain, since the live-region use case needs them.
|
|
28
|
+
*/
|
|
29
|
+
export interface VisuallyHiddenProps extends Omit<
|
|
30
|
+
BaseProps<HTMLElement>,
|
|
31
|
+
'className' | 'style'
|
|
32
|
+
> {
|
|
33
|
+
/** Ref forwarded to the rendered element. */
|
|
34
|
+
ref?: React.Ref<HTMLElement>;
|
|
35
|
+
|
|
36
|
+
/** Content to expose to assistive technology while hidden from sight. */
|
|
37
|
+
children: ReactNode;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* HTML tag to render as. Defaults to `'span'` (inline) for the common
|
|
41
|
+
* icon-label case; pass a block element such as `'div'` when wrapping block
|
|
42
|
+
* content or hosting an `aria-live` region. This is a structural choice, not
|
|
43
|
+
* a visual one.
|
|
44
|
+
*
|
|
45
|
+
* @default 'span'
|
|
46
|
+
*/
|
|
47
|
+
as?: ElementType;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const styles = stylex.create({
|
|
51
|
+
// Canonical "visually hidden" clip block. Uses `clip: rect(...)` (not
|
|
52
|
+
// clip-path) for the widest assistive-tech/browser support. `inset` pins the
|
|
53
|
+
// 1px box to the top-left so a positioned ancestor cannot reveal it, and
|
|
54
|
+
// pointer/selection are disabled so the hidden node can't catch clicks or be
|
|
55
|
+
// text-selected.
|
|
56
|
+
visuallyHidden: {
|
|
57
|
+
position: 'absolute',
|
|
58
|
+
width: 1,
|
|
59
|
+
height: 1,
|
|
60
|
+
margin: -1,
|
|
61
|
+
padding: 0,
|
|
62
|
+
overflow: 'hidden',
|
|
63
|
+
clip: 'rect(0, 0, 0, 0)',
|
|
64
|
+
whiteSpace: 'nowrap',
|
|
65
|
+
borderStyle: 'none',
|
|
66
|
+
insetBlockStart: 0,
|
|
67
|
+
insetInlineStart: 0,
|
|
68
|
+
pointerEvents: 'none',
|
|
69
|
+
userSelect: 'none',
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Renders its children in the accessibility tree while hiding them visually.
|
|
75
|
+
*
|
|
76
|
+
* Use for content that assistive technology must perceive but sighted users
|
|
77
|
+
* should not see: accessible names for icon-only controls, `aria-live`
|
|
78
|
+
* announcement regions, and supplementary screen-reader context.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```
|
|
82
|
+
* // Accessible name for an icon-only button
|
|
83
|
+
* <IconButton icon="trash" label="">
|
|
84
|
+
* <VisuallyHidden>Delete incident</VisuallyHidden>
|
|
85
|
+
* </IconButton>
|
|
86
|
+
*
|
|
87
|
+
* // Live region for announcements
|
|
88
|
+
* <VisuallyHidden as="div" aria-live="polite">
|
|
89
|
+
* {`Moved ${task} to ${column}`}
|
|
90
|
+
* </VisuallyHidden>
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
export function VisuallyHidden({
|
|
94
|
+
children,
|
|
95
|
+
as: element = 'span',
|
|
96
|
+
ref,
|
|
97
|
+
...props
|
|
98
|
+
}: VisuallyHiddenProps) {
|
|
99
|
+
return createElement(
|
|
100
|
+
element,
|
|
101
|
+
{
|
|
102
|
+
ref: ref as Ref<Element>,
|
|
103
|
+
// Spread consumer props (aria-*, role, id, data-*, handlers) first, then
|
|
104
|
+
// the fixed clip styles, so the visually-hidden class can never be
|
|
105
|
+
// displaced. There is no consumer className/style to merge — by design.
|
|
106
|
+
...props,
|
|
107
|
+
...stylex.props(styles.visuallyHidden),
|
|
108
|
+
},
|
|
109
|
+
children,
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
VisuallyHidden.displayName = 'VisuallyHidden';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @file index.ts
|
|
7
|
+
* @input Imports from VisuallyHidden.tsx
|
|
8
|
+
* @output Exports VisuallyHidden component and props type
|
|
9
|
+
* @position Package entry point for VisuallyHidden
|
|
10
|
+
*
|
|
11
|
+
* SYNC: When modified, update /packages/core/src/VisuallyHidden/VisuallyHidden.doc.mjs
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export {VisuallyHidden} from './VisuallyHidden';
|
|
15
|
+
export type {VisuallyHiddenProps} from './VisuallyHidden';
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file Subprocess smoke tests for the zero-dependency docs script.
|
|
5
|
+
*
|
|
6
|
+
* `docs.mjs` resolves the package directory from `import.meta.url`. Using
|
|
7
|
+
* `new URL(...).pathname` there breaks on Windows (drive-letter paths come
|
|
8
|
+
* back as `/D:/...`), which made `--list` print nothing and component
|
|
9
|
+
* lookups crash with ENOENT. These tests spawn the script as a real
|
|
10
|
+
* subprocess from a neutral cwd, so resolution can only come from the
|
|
11
|
+
* module URL, and assert it finds the component catalog on every platform.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import {describe, it, expect} from 'vitest';
|
|
15
|
+
import {spawnSync} from 'node:child_process';
|
|
16
|
+
import * as os from 'node:os';
|
|
17
|
+
import * as path from 'node:path';
|
|
18
|
+
import {fileURLToPath} from 'node:url';
|
|
19
|
+
|
|
20
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
21
|
+
const DOCS_SCRIPT = path.resolve(__dirname, '..', 'docs.mjs');
|
|
22
|
+
|
|
23
|
+
function runDocs(args) {
|
|
24
|
+
return spawnSync(process.execPath, [DOCS_SCRIPT, ...args], {
|
|
25
|
+
cwd: os.tmpdir(),
|
|
26
|
+
encoding: 'utf8',
|
|
27
|
+
timeout: 20_000,
|
|
28
|
+
env: {...process.env, FORCE_COLOR: '0'},
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
describe('docs.mjs component discovery', () => {
|
|
33
|
+
it('--list discovers the component catalog', () => {
|
|
34
|
+
const r = runDocs(['--list']);
|
|
35
|
+
expect(r.error).toBeUndefined();
|
|
36
|
+
expect(r.signal).toBeNull();
|
|
37
|
+
expect(r.status).toBe(0);
|
|
38
|
+
expect(r.stdout).toMatch(/\bButton\b/);
|
|
39
|
+
expect(r.stdout).toMatch(/\bDialog\b/);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('renders docs for a single component', () => {
|
|
43
|
+
const r = runDocs(['Button']);
|
|
44
|
+
expect(r.error).toBeUndefined();
|
|
45
|
+
expect(r.signal).toBeNull();
|
|
46
|
+
expect(r.status).toBe(0);
|
|
47
|
+
expect(r.stdout).toMatch(/^# Button$/m);
|
|
48
|
+
expect(r.stdout).toMatch(/## Props/);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file focusableSelector.ts
|
|
5
|
+
* @input None (a plain CSS selector string constant)
|
|
6
|
+
* @output Exports FOCUSABLE_SELECTOR
|
|
7
|
+
* @position Internal utility; the canonical CSS selector for focusable
|
|
8
|
+
* elements, shared by focus-management hooks (e.g. useFocusTrap) so the
|
|
9
|
+
* selector isn't duplicated across components/hooks. Not exported from the
|
|
10
|
+
* public barrel — internal implementation detail.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Canonical CSS selector for commonly focusable elements. Includes the
|
|
15
|
+
* tabbable natives (button/link/input/select/textarea/[tabindex]) plus
|
|
16
|
+
* editable and media elements the browser also puts in the tab order —
|
|
17
|
+
* contenteditable, media with controls, iframe, and an open <details>'s
|
|
18
|
+
* <summary> — which a naive selector misses, letting Tab escape a trap whose
|
|
19
|
+
* only interactive content is (e.g.) a contenteditable composer (infra-8).
|
|
20
|
+
*
|
|
21
|
+
* This is the canonical focusable selector; prefer importing it here over
|
|
22
|
+
* re-declaring the string so behavior stays consistent across hooks.
|
|
23
|
+
*/
|
|
24
|
+
export const FOCUSABLE_SELECTOR =
|
|
25
|
+
'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"]):not([disabled]), [contenteditable]:not([contenteditable="false"]), audio[controls], video[controls], iframe, details > summary:first-child';
|
package/src/hooks/index.ts
CHANGED
|
@@ -14,11 +14,31 @@
|
|
|
14
14
|
export {useFocusTrap} from './useFocusTrap';
|
|
15
15
|
export type {UseFocusTrapOptions, UseFocusTrapReturn} from './useFocusTrap';
|
|
16
16
|
|
|
17
|
+
export {useAnnounce} from './useAnnounce';
|
|
18
|
+
export type {AnnounceFn, AnnouncePoliteness} from './useAnnounce';
|
|
19
|
+
|
|
17
20
|
export {useGridFocus} from './useGridFocus';
|
|
18
21
|
export type {UseGridFocusOptions, UseGridFocusReturn} from './useGridFocus';
|
|
19
22
|
|
|
20
23
|
export {useListFocus} from './useListFocus';
|
|
21
|
-
export type {
|
|
24
|
+
export type {
|
|
25
|
+
UseListFocusOptions,
|
|
26
|
+
UseListFocusReturn,
|
|
27
|
+
ListFocusOrientation,
|
|
28
|
+
} from './useListFocus';
|
|
29
|
+
|
|
30
|
+
export {useTreeFocus} from './useTreeFocus';
|
|
31
|
+
export type {UseTreeFocusOptions, UseTreeFocusReturn} from './useTreeFocus';
|
|
32
|
+
|
|
33
|
+
export {useTypeahead} from './useTypeahead';
|
|
34
|
+
|
|
35
|
+
export {useKeyboardHint} from './useKeyboardHint';
|
|
36
|
+
export type {
|
|
37
|
+
UseKeyboardHintOptions,
|
|
38
|
+
UseKeyboardHintReturn,
|
|
39
|
+
KeyboardHintOrientation,
|
|
40
|
+
} from './useKeyboardHint';
|
|
41
|
+
export type {UseTypeaheadOptions, UseTypeaheadReturn} from './useTypeahead';
|
|
22
42
|
|
|
23
43
|
export {useMediaQuery} from './useMediaQuery';
|
|
24
44
|
|
|
@@ -41,7 +61,10 @@ export type {
|
|
|
41
61
|
export {useImageMode} from './useImageMode';
|
|
42
62
|
export type {ImageSampleRegion, UseImageModeOptions} from './useImageMode';
|
|
43
63
|
|
|
44
|
-
export {
|
|
64
|
+
export {
|
|
65
|
+
useClickableContainer,
|
|
66
|
+
INTERACTIVE_SELECTORS,
|
|
67
|
+
} from './useClickableContainer';
|
|
45
68
|
export type {
|
|
46
69
|
UseClickableContainerOptions,
|
|
47
70
|
ClickableContainerResult,
|
|
@@ -55,3 +78,6 @@ export type {
|
|
|
55
78
|
InteractiveRole,
|
|
56
79
|
UseInteractiveRoleOptions,
|
|
57
80
|
} from './useInteractiveRole';
|
|
81
|
+
|
|
82
|
+
export {useLongPress} from './useLongPress';
|
|
83
|
+
export type {UseLongPressOptions, UseLongPressHandlers} from './useLongPress';
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file useAnnounce.test.tsx
|
|
5
|
+
* @input Uses vitest, @testing-library/react, useAnnounce hook
|
|
6
|
+
* @output Unit tests for useAnnounce live-region announcements
|
|
7
|
+
* @position Testing; validates useAnnounce.ts
|
|
8
|
+
*
|
|
9
|
+
* SYNC: When useAnnounce.ts changes, update tests to match new behavior
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import {describe, it, expect, afterEach} from 'vitest';
|
|
13
|
+
import {renderHook, waitFor} from '@testing-library/react';
|
|
14
|
+
import {useAnnounce, __resetLiveRegionsForTest} from './useAnnounce';
|
|
15
|
+
|
|
16
|
+
afterEach(() => {
|
|
17
|
+
__resetLiveRegionsForTest();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
function politeRegion(): HTMLElement | null {
|
|
21
|
+
return document.querySelector('[data-astryx-live-region="polite"]');
|
|
22
|
+
}
|
|
23
|
+
function assertiveRegion(): HTMLElement | null {
|
|
24
|
+
return document.querySelector('[data-astryx-live-region="assertive"]');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
describe('useAnnounce', () => {
|
|
28
|
+
it('mounts empty polite and assertive live regions on first announce', async () => {
|
|
29
|
+
const {result} = renderHook(() => useAnnounce());
|
|
30
|
+
// Regions do not exist until first use.
|
|
31
|
+
expect(politeRegion()).toBeNull();
|
|
32
|
+
|
|
33
|
+
result.current('Saved');
|
|
34
|
+
|
|
35
|
+
// Both regions exist after the first announce, before content settles.
|
|
36
|
+
expect(politeRegion()).not.toBeNull();
|
|
37
|
+
expect(assertiveRegion()).not.toBeNull();
|
|
38
|
+
expect(politeRegion()).toHaveAttribute('aria-live', 'polite');
|
|
39
|
+
expect(politeRegion()).toHaveAttribute('aria-atomic', 'true');
|
|
40
|
+
expect(politeRegion()).toHaveAttribute('role', 'status');
|
|
41
|
+
expect(assertiveRegion()).toHaveAttribute('aria-live', 'assertive');
|
|
42
|
+
expect(assertiveRegion()).toHaveAttribute('role', 'alert');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('announces a polite message into the polite region', async () => {
|
|
46
|
+
const {result} = renderHook(() => useAnnounce());
|
|
47
|
+
result.current('12 results');
|
|
48
|
+
await waitFor(() => {
|
|
49
|
+
expect(politeRegion()).toHaveTextContent('12 results');
|
|
50
|
+
});
|
|
51
|
+
// Assertive region stays empty.
|
|
52
|
+
expect(assertiveRegion()).toHaveTextContent('');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('routes assertive messages to the assertive region', async () => {
|
|
56
|
+
const {result} = renderHook(() => useAnnounce());
|
|
57
|
+
result.current('Upload failed', 'assertive');
|
|
58
|
+
await waitFor(() => {
|
|
59
|
+
expect(assertiveRegion()).toHaveTextContent('Upload failed');
|
|
60
|
+
});
|
|
61
|
+
expect(politeRegion()).toHaveTextContent('');
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('re-announces an identical message (clears then re-sets)', async () => {
|
|
65
|
+
const {result} = renderHook(() => useAnnounce());
|
|
66
|
+
result.current('No results found');
|
|
67
|
+
await waitFor(() => {
|
|
68
|
+
expect(politeRegion()).toHaveTextContent('No results found');
|
|
69
|
+
});
|
|
70
|
+
// Second identical announce should still land (region is cleared first).
|
|
71
|
+
result.current('No results found');
|
|
72
|
+
expect(politeRegion()).toHaveTextContent('');
|
|
73
|
+
await waitFor(() => {
|
|
74
|
+
expect(politeRegion()).toHaveTextContent('No results found');
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('ignores empty messages', () => {
|
|
79
|
+
const {result} = renderHook(() => useAnnounce());
|
|
80
|
+
result.current('');
|
|
81
|
+
// No regions created for an empty announce.
|
|
82
|
+
expect(politeRegion()).toBeNull();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('reuses the same singleton regions across hook instances', async () => {
|
|
86
|
+
const {result: a} = renderHook(() => useAnnounce());
|
|
87
|
+
a.current('first');
|
|
88
|
+
const region = politeRegion();
|
|
89
|
+
|
|
90
|
+
const {result: b} = renderHook(() => useAnnounce());
|
|
91
|
+
b.current('second');
|
|
92
|
+
await waitFor(() => {
|
|
93
|
+
expect(politeRegion()).toHaveTextContent('second');
|
|
94
|
+
});
|
|
95
|
+
// Same DOM node, not a duplicate.
|
|
96
|
+
expect(politeRegion()).toBe(region);
|
|
97
|
+
expect(
|
|
98
|
+
document.querySelectorAll('[data-astryx-live-region="polite"]').length,
|
|
99
|
+
).toBe(1);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @file useAnnounce.ts
|
|
7
|
+
* @input Uses React useCallback; DOM APIs for a singleton live-region pair
|
|
8
|
+
* @output Exports useAnnounce hook and AnnouncePoliteness type
|
|
9
|
+
* @position Core a11y hook; provides imperative screen-reader announcements
|
|
10
|
+
* via persistently-mounted polite/assertive live regions
|
|
11
|
+
*
|
|
12
|
+
* SYNC: When modified, update:
|
|
13
|
+
* - /packages/core/src/hooks/index.ts
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import {useCallback} from 'react';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Announcement urgency:
|
|
20
|
+
* - `'polite'` (default): announced when the screen reader is idle. Use for
|
|
21
|
+
* status updates, result counts, "no results", non-urgent confirmations.
|
|
22
|
+
* - `'assertive'`: interrupts the current announcement. Reserve for errors and
|
|
23
|
+
* time-sensitive alerts.
|
|
24
|
+
*/
|
|
25
|
+
export type AnnouncePoliteness = 'polite' | 'assertive';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Imperative screen-reader announcement function.
|
|
29
|
+
*/
|
|
30
|
+
export type AnnounceFn = (
|
|
31
|
+
message: string,
|
|
32
|
+
politeness?: AnnouncePoliteness,
|
|
33
|
+
) => void;
|
|
34
|
+
|
|
35
|
+
const CONTAINER_ATTR = 'data-astryx-live-region';
|
|
36
|
+
|
|
37
|
+
// Visually-hidden clip block (matches the VisuallyHidden primitive). Applied
|
|
38
|
+
// inline so the regions work without any stylesheet being present.
|
|
39
|
+
const VISUALLY_HIDDEN_CSS =
|
|
40
|
+
'position:absolute;width:1px;height:1px;margin:-1px;padding:0;' +
|
|
41
|
+
'overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;' +
|
|
42
|
+
'inset-block-start:0;inset-inline-start:0;pointer-events:none;' +
|
|
43
|
+
'user-select:none;';
|
|
44
|
+
|
|
45
|
+
interface LiveRegions {
|
|
46
|
+
polite: HTMLElement;
|
|
47
|
+
assertive: HTMLElement;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Singleton: the live regions are created ONCE and stay mounted for the
|
|
51
|
+
// lifetime of the document. This is the crux of reliable announcements — many
|
|
52
|
+
// screen readers will not announce content injected into a live region that is
|
|
53
|
+
// created together with its content ("born with content"). By mounting empty
|
|
54
|
+
// regions up front and only mutating their text later, updates are announced.
|
|
55
|
+
let regions: LiveRegions | null = null;
|
|
56
|
+
|
|
57
|
+
function createRegion(politeness: AnnouncePoliteness): HTMLElement {
|
|
58
|
+
const el = document.createElement('div');
|
|
59
|
+
el.setAttribute(CONTAINER_ATTR, politeness);
|
|
60
|
+
el.setAttribute('aria-live', politeness);
|
|
61
|
+
el.setAttribute('aria-atomic', 'true');
|
|
62
|
+
el.setAttribute('role', politeness === 'assertive' ? 'alert' : 'status');
|
|
63
|
+
el.style.cssText = VISUALLY_HIDDEN_CSS;
|
|
64
|
+
document.body.appendChild(el);
|
|
65
|
+
return el;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function getRegions(): LiveRegions | null {
|
|
69
|
+
if (typeof document === 'undefined') {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
if (regions) {
|
|
73
|
+
// Re-attach if a region was removed from the DOM (e.g. by a test cleanup).
|
|
74
|
+
if (!regions.polite.isConnected) {
|
|
75
|
+
document.body.appendChild(regions.polite);
|
|
76
|
+
}
|
|
77
|
+
if (!regions.assertive.isConnected) {
|
|
78
|
+
document.body.appendChild(regions.assertive);
|
|
79
|
+
}
|
|
80
|
+
return regions;
|
|
81
|
+
}
|
|
82
|
+
regions = {
|
|
83
|
+
polite: createRegion('polite'),
|
|
84
|
+
assertive: createRegion('assertive'),
|
|
85
|
+
};
|
|
86
|
+
return regions;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function announceMessage(
|
|
90
|
+
message: string,
|
|
91
|
+
politeness: AnnouncePoliteness,
|
|
92
|
+
): void {
|
|
93
|
+
const r = getRegions();
|
|
94
|
+
if (!r) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const target = politeness === 'assertive' ? r.assertive : r.polite;
|
|
98
|
+
// Clearing first guarantees the mutation is observed even when the new
|
|
99
|
+
// message equals the current text — some AT deduplicate identical content.
|
|
100
|
+
target.textContent = '';
|
|
101
|
+
// A microtask/rAF-free re-set in the next frame is more reliable across AT
|
|
102
|
+
// than an immediate re-set, which can be coalesced with the clear.
|
|
103
|
+
requestAnimationFrame(() => {
|
|
104
|
+
target.textContent = message;
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Clear any pending announcement from a region without announcing anything new.
|
|
110
|
+
* Used when the triggering context goes away (e.g. a search query is cleared),
|
|
111
|
+
* so stale status text does not linger in the accessibility tree.
|
|
112
|
+
*/
|
|
113
|
+
function clearRegion(politeness: AnnouncePoliteness): void {
|
|
114
|
+
if (!regions) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const target =
|
|
118
|
+
politeness === 'assertive' ? regions.assertive : regions.polite;
|
|
119
|
+
target.textContent = '';
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Returns an imperative `announce(message, politeness?)` function that speaks a
|
|
124
|
+
* message through a persistently-mounted, visually-hidden live region.
|
|
125
|
+
*
|
|
126
|
+
* The polite and assertive regions are created once on first use and kept
|
|
127
|
+
* mounted, so announcements are reliable even for messages that appear
|
|
128
|
+
* immediately (unlike a live region rendered together with its content).
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```
|
|
132
|
+
* function Search() {
|
|
133
|
+
* const announce = useAnnounce();
|
|
134
|
+
* const onResults = (n: number) => {
|
|
135
|
+
* announce(n === 0 ? 'No results found' : `${n} results`);
|
|
136
|
+
* };
|
|
137
|
+
* // ...
|
|
138
|
+
* }
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
export function useAnnounce(): AnnounceFn {
|
|
142
|
+
return useCallback(
|
|
143
|
+
(message: string, politeness: AnnouncePoliteness = 'polite') => {
|
|
144
|
+
if (!message) {
|
|
145
|
+
// An empty message clears any lingering status from the region rather
|
|
146
|
+
// than announcing nothing — useful when the triggering context ends.
|
|
147
|
+
clearRegion(politeness);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
announceMessage(message, politeness);
|
|
151
|
+
},
|
|
152
|
+
[],
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Test-only helper: removes the singleton live regions and resets state so
|
|
158
|
+
* each test starts clean. Not part of the public runtime API.
|
|
159
|
+
*
|
|
160
|
+
* @internal
|
|
161
|
+
*/
|
|
162
|
+
export function __resetLiveRegionsForTest(): void {
|
|
163
|
+
if (regions) {
|
|
164
|
+
regions.polite.remove();
|
|
165
|
+
regions.assertive.remove();
|
|
166
|
+
regions = null;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
@@ -5,18 +5,30 @@
|
|
|
5
5
|
/**
|
|
6
6
|
* @file useClickableContainer.ts
|
|
7
7
|
* @input Container ref, interactive element ref, click/href handlers
|
|
8
|
-
* @output onClick and onMouseUp handlers for the container
|
|
8
|
+
* @output onClick and onMouseUp handlers for the container; INTERACTIVE_SELECTORS list
|
|
9
9
|
* @position Core hook for clickable containers that safely handle nested interactive elements
|
|
10
10
|
*
|
|
11
11
|
* Solves the "nested interactive elements" problem: when a card is clickable
|
|
12
12
|
* but contains buttons/links, clicking those should NOT trigger the card's action.
|
|
13
|
+
*
|
|
14
|
+
* SYNC: When modified, update:
|
|
15
|
+
* - /packages/core/src/hooks/index.ts (export)
|
|
13
16
|
*/
|
|
14
17
|
|
|
15
18
|
import {useCallback, useEffect, type RefObject, type MouseEvent} from 'react';
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Canonical list of interactive element selectors — native controls plus
|
|
22
|
+
* role-based interactive elements. Clicks on these (or their descendants)
|
|
23
|
+
* should NOT bubble to a clickable container's click handler.
|
|
24
|
+
*
|
|
25
|
+
* Exported so other focus/interaction utilities can share one comprehensive
|
|
26
|
+
* definition of "interactive target" rather than hand-rolling divergent lists.
|
|
27
|
+
* Note: this list is about "don't bubble clicks", not focus-eligibility —
|
|
28
|
+
* consumers that need focusable elements must additionally exclude
|
|
29
|
+
* unfocusable/disabled targets (e.g. `[tabindex="-1"]`, `:disabled`).
|
|
30
|
+
*/
|
|
31
|
+
export const INTERACTIVE_SELECTORS = [
|
|
20
32
|
'button',
|
|
21
33
|
'a',
|
|
22
34
|
'input',
|
|
@@ -61,25 +61,37 @@ const scaleIn = stylex.keyframes({
|
|
|
61
61
|
|
|
62
62
|
const styles = stylex.create({
|
|
63
63
|
slideDown: {
|
|
64
|
-
animationName:
|
|
64
|
+
animationName: {
|
|
65
|
+
default: slideDown,
|
|
66
|
+
'@media (prefers-reduced-motion: reduce)': 'none',
|
|
67
|
+
},
|
|
65
68
|
animationDuration: durationVars['--duration-fast-max'],
|
|
66
69
|
animationTimingFunction: easeVars['--ease-standard'],
|
|
67
70
|
animationFillMode: 'backwards',
|
|
68
71
|
},
|
|
69
72
|
slideUp: {
|
|
70
|
-
animationName:
|
|
73
|
+
animationName: {
|
|
74
|
+
default: slideUp,
|
|
75
|
+
'@media (prefers-reduced-motion: reduce)': 'none',
|
|
76
|
+
},
|
|
71
77
|
animationDuration: durationVars['--duration-fast-max'],
|
|
72
78
|
animationTimingFunction: easeVars['--ease-standard'],
|
|
73
79
|
animationFillMode: 'backwards',
|
|
74
80
|
},
|
|
75
81
|
fadeIn: {
|
|
76
|
-
animationName:
|
|
82
|
+
animationName: {
|
|
83
|
+
default: fadeIn,
|
|
84
|
+
'@media (prefers-reduced-motion: reduce)': 'none',
|
|
85
|
+
},
|
|
77
86
|
animationDuration: durationVars['--duration-fast-max'],
|
|
78
87
|
animationTimingFunction: easeVars['--ease-standard'],
|
|
79
88
|
animationFillMode: 'backwards',
|
|
80
89
|
},
|
|
81
90
|
scaleIn: {
|
|
82
|
-
animationName:
|
|
91
|
+
animationName: {
|
|
92
|
+
default: scaleIn,
|
|
93
|
+
'@media (prefers-reduced-motion: reduce)': 'none',
|
|
94
|
+
},
|
|
83
95
|
animationDuration: durationVars['--duration-fast-max'],
|
|
84
96
|
animationTimingFunction: easeVars['--ease-standard'],
|
|
85
97
|
animationFillMode: 'backwards',
|