@astryxdesign/core 0.1.2 → 0.1.3
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
|
@@ -29,6 +29,7 @@ import {mergeProps} from '../utils';
|
|
|
29
29
|
import {useLinkComponent} from '../Link/useLinkComponent';
|
|
30
30
|
import {TreeListBranches} from './TreeListBranches';
|
|
31
31
|
import type {TreeListDensity} from './TreeListTypes';
|
|
32
|
+
import {treeItemScope} from './treeListItem.markers.stylex';
|
|
32
33
|
import {themeProps} from '../utils/themeProps';
|
|
33
34
|
|
|
34
35
|
// =============================================================================
|
|
@@ -42,6 +43,9 @@ const styles = stylex.create({
|
|
|
42
43
|
padding: 0,
|
|
43
44
|
position: 'relative',
|
|
44
45
|
width: '100%',
|
|
46
|
+
// The treeitem row is the roving-tabindex focus owner; suppress the
|
|
47
|
+
// native focus ring in favor of the row's :focus-visible outline below.
|
|
48
|
+
outline: 'none',
|
|
45
49
|
},
|
|
46
50
|
childGroup: {
|
|
47
51
|
margin: 0,
|
|
@@ -82,10 +86,16 @@ const styles = stylex.create({
|
|
|
82
86
|
focusVisibleOutline: {
|
|
83
87
|
outline: {
|
|
84
88
|
default: 'none',
|
|
89
|
+
// Focus lives on the treeitem row (the <li>) via roving tabindex.
|
|
90
|
+
// Scoped to the row's OWN treeitem so focusing a parent does not leak
|
|
91
|
+
// the ring onto descendant rows. Also support inner focusable actions.
|
|
92
|
+
[stylex.when.ancestor(':focus-visible', treeItemScope)]:
|
|
93
|
+
`2px solid ${colorVars['--color-accent']}`,
|
|
85
94
|
':has(:focus-visible)': `2px solid ${colorVars['--color-accent']}`,
|
|
86
95
|
},
|
|
87
96
|
outlineOffset: {
|
|
88
97
|
default: '0',
|
|
98
|
+
[stylex.when.ancestor(':focus-visible', treeItemScope)]: '2px',
|
|
89
99
|
':has(:focus-visible)': '2px',
|
|
90
100
|
},
|
|
91
101
|
},
|
|
@@ -250,6 +260,16 @@ export interface TreeListItemInternalProps {
|
|
|
250
260
|
density: TreeListDensity;
|
|
251
261
|
/** Pre-rendered children subtree (rendered by the parent recursion) */
|
|
252
262
|
renderedChildren?: ReactNode;
|
|
263
|
+
/** 1-based position of this item among its siblings (aria-posinset). */
|
|
264
|
+
posInSet: number;
|
|
265
|
+
/** Number of siblings at this level (aria-setsize). */
|
|
266
|
+
setSize: number;
|
|
267
|
+
/**
|
|
268
|
+
* Whether this treeitem is the initial roving-tabindex seed. Exactly one
|
|
269
|
+
* treeitem is seeded tabbable at mount; useTreeFocus (hasRovingTabIndex)
|
|
270
|
+
* then owns the tab stop dynamically.
|
|
271
|
+
*/
|
|
272
|
+
isTabbable: boolean;
|
|
253
273
|
}
|
|
254
274
|
|
|
255
275
|
// =============================================================================
|
|
@@ -275,6 +295,9 @@ export function TreeListItem({
|
|
|
275
295
|
onToggle,
|
|
276
296
|
density,
|
|
277
297
|
renderedChildren,
|
|
298
|
+
posInSet,
|
|
299
|
+
setSize,
|
|
300
|
+
isTabbable,
|
|
278
301
|
}: TreeListItemInternalProps) {
|
|
279
302
|
const labelId = useId();
|
|
280
303
|
const descriptionId = useId();
|
|
@@ -342,18 +365,26 @@ export function TreeListItem({
|
|
|
342
365
|
);
|
|
343
366
|
|
|
344
367
|
const chevron = hasChildren ? (
|
|
345
|
-
|
|
346
|
-
//
|
|
368
|
+
handleToggle != null ? (
|
|
369
|
+
// Real toggle button whenever expand/collapse is supported, so the row
|
|
370
|
+
// can be expanded from the keyboard even when the item has no onClick/href
|
|
371
|
+
// (row-level onClick is the only click path in that case, but there is no
|
|
372
|
+
// focusable element to receive Enter/Space). The row's handleClick ignores
|
|
373
|
+
// clicks originating inside a <button>, so this never double-toggles.
|
|
347
374
|
<button
|
|
348
375
|
type="button"
|
|
349
376
|
aria-expanded={isExpanded}
|
|
350
377
|
aria-label="Toggle children"
|
|
378
|
+
disabled={isDisabled}
|
|
379
|
+
// Roving tabindex lives on the treeitem row; the chevron toggle is not
|
|
380
|
+
// a separate tab stop. Row-level Enter/Space forwards to this button.
|
|
381
|
+
tabIndex={-1}
|
|
351
382
|
onClick={handleToggle}
|
|
352
383
|
{...stylex.props(styles.chevronButton)}>
|
|
353
384
|
{chevronIcon}
|
|
354
385
|
</button>
|
|
355
386
|
) : (
|
|
356
|
-
// Non-interactive chevron when
|
|
387
|
+
// Non-interactive chevron only when toggling is not wired up at all
|
|
357
388
|
<span {...stylex.props(styles.chevronContainer)}>{chevronIcon}</span>
|
|
358
389
|
)
|
|
359
390
|
) : null;
|
|
@@ -371,7 +402,9 @@ export function TreeListItem({
|
|
|
371
402
|
aria-disabled={isDisabled || undefined}
|
|
372
403
|
aria-labelledby={labelId}
|
|
373
404
|
aria-describedby={description != null ? descriptionId : undefined}
|
|
374
|
-
|
|
405
|
+
// Roving tabindex lives on the treeitem row; inner action is not a
|
|
406
|
+
// separate tab stop. Activation is forwarded from the row.
|
|
407
|
+
tabIndex={-1}
|
|
375
408
|
{...stylex.props(styles.invisibleAnchor)}>
|
|
376
409
|
{labelAndDescription}
|
|
377
410
|
</LinkComponent>
|
|
@@ -382,6 +415,9 @@ export function TreeListItem({
|
|
|
382
415
|
disabled={isDisabled}
|
|
383
416
|
aria-labelledby={labelId}
|
|
384
417
|
aria-describedby={description != null ? descriptionId : undefined}
|
|
418
|
+
// Roving tabindex lives on the treeitem row; inner action is not a
|
|
419
|
+
// separate tab stop. Activation is forwarded from the row.
|
|
420
|
+
tabIndex={-1}
|
|
385
421
|
{...stylex.props(styles.invisibleButton)}>
|
|
386
422
|
{labelAndDescription}
|
|
387
423
|
</button>
|
|
@@ -400,7 +436,17 @@ export function TreeListItem({
|
|
|
400
436
|
aria-expanded={hasChildren ? isExpanded : undefined}
|
|
401
437
|
aria-selected={isSelected || undefined}
|
|
402
438
|
aria-disabled={isDisabled || undefined}
|
|
403
|
-
{
|
|
439
|
+
aria-level={nestedLevel + 1}
|
|
440
|
+
aria-posinset={posInSet}
|
|
441
|
+
aria-setsize={setSize}
|
|
442
|
+
// Roving tabindex: exactly one visible treeitem is tabbable at a time.
|
|
443
|
+
// Disabled items are skipped by the tree keyboard handler but remain
|
|
444
|
+
// in the accessibility tree.
|
|
445
|
+
tabIndex={isDisabled ? -1 : isTabbable ? 0 : -1}
|
|
446
|
+
data-tree-id={id}
|
|
447
|
+
data-tree-level={nestedLevel + 1}
|
|
448
|
+
data-tree-disabled={isDisabled || undefined}
|
|
449
|
+
{...stylex.props(styles.wrapper, treeItemScope)}>
|
|
404
450
|
<div {...stylex.props(styles.treeBranches)}>
|
|
405
451
|
<TreeListBranches
|
|
406
452
|
ancestorsIsLast={ancestorsIsLast}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file treeListItem.markers.stylex.ts
|
|
5
|
+
* @input Uses StyleX defineMarker
|
|
6
|
+
* @output Exports treeItemScope marker
|
|
7
|
+
* @position Scoped marker; consumed by TreeListItem.tsx
|
|
8
|
+
*
|
|
9
|
+
* SYNC: When modified, update /packages/core/src/TreeList/TreeListItem.tsx
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import * as stylex from '@stylexjs/stylex';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Scoped marker placed on each treeitem row (`<li role="treeitem">`).
|
|
16
|
+
* Binds the row's `:focus-visible` outline to its OWN treeitem, so focusing
|
|
17
|
+
* a parent treeitem does not leak the focus ring onto descendant rows.
|
|
18
|
+
*/
|
|
19
|
+
export const treeItemScope: ReturnType<typeof stylex.defineMarker> =
|
|
20
|
+
stylex.defineMarker();
|
|
@@ -29,6 +29,7 @@ import React, {
|
|
|
29
29
|
import * as stylex from '@stylexjs/stylex';
|
|
30
30
|
import type {StyleXStyles} from '@stylexjs/stylex';
|
|
31
31
|
import {usePopover} from '../Popover/usePopover';
|
|
32
|
+
import {useAnnounce} from '../hooks/useAnnounce';
|
|
32
33
|
import {TypeaheadItem} from './TypeaheadItem';
|
|
33
34
|
import {Icon} from '../Icon';
|
|
34
35
|
import {
|
|
@@ -48,9 +49,10 @@ import {themeProps} from '../utils/themeProps';
|
|
|
48
49
|
// Types
|
|
49
50
|
// =============================================================================
|
|
50
51
|
|
|
51
|
-
export interface BaseTypeaheadProps<
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
export interface BaseTypeaheadProps<T extends SearchableItem> extends Omit<
|
|
53
|
+
BaseProps<HTMLElement>,
|
|
54
|
+
'onChange'
|
|
55
|
+
> {
|
|
54
56
|
ref?: React.Ref<HTMLInputElement>;
|
|
55
57
|
/**
|
|
56
58
|
* Search source providing items.
|
|
@@ -101,6 +103,16 @@ export interface BaseTypeaheadProps<
|
|
|
101
103
|
*/
|
|
102
104
|
isDisabled?: boolean;
|
|
103
105
|
|
|
106
|
+
/**
|
|
107
|
+
* When disabled with a reason, keeps the input focusable via `aria-disabled`
|
|
108
|
+
* (instead of the native `disabled` attribute) and `readOnly` so an
|
|
109
|
+
* associated disabled-reason tooltip stays discoverable by keyboard and
|
|
110
|
+
* assistive technology. Value mutation is still blocked by the `isDisabled`
|
|
111
|
+
* guards. Consumers (Typeahead) own the tooltip and wrapper.
|
|
112
|
+
* @default false
|
|
113
|
+
*/
|
|
114
|
+
isFocusableDisabled?: boolean;
|
|
115
|
+
|
|
104
116
|
/**
|
|
105
117
|
* Auto-focus on mount.
|
|
106
118
|
* @default false
|
|
@@ -134,6 +146,11 @@ export interface BaseTypeaheadProps<
|
|
|
134
146
|
*/
|
|
135
147
|
ariaDescribedBy?: string;
|
|
136
148
|
|
|
149
|
+
/**
|
|
150
|
+
* Additional aria-labelledby IDs.
|
|
151
|
+
*/
|
|
152
|
+
ariaLabelledBy?: string;
|
|
153
|
+
|
|
137
154
|
/**
|
|
138
155
|
* Additional StyleX styles for the input element.
|
|
139
156
|
*/
|
|
@@ -280,9 +297,7 @@ const itemSizeStyles = stylex.create({
|
|
|
280
297
|
* />
|
|
281
298
|
* ```
|
|
282
299
|
*/
|
|
283
|
-
export const BaseTypeahead = function BaseTypeahead<
|
|
284
|
-
T extends SearchableItem,
|
|
285
|
-
>({
|
|
300
|
+
export const BaseTypeahead = function BaseTypeahead<T extends SearchableItem>({
|
|
286
301
|
searchSource,
|
|
287
302
|
value,
|
|
288
303
|
onChange,
|
|
@@ -292,11 +307,13 @@ export const BaseTypeahead = function BaseTypeahead<
|
|
|
292
307
|
maxMenuItems = 10,
|
|
293
308
|
emptySearchResultsText = 'No results found',
|
|
294
309
|
isDisabled = false,
|
|
310
|
+
isFocusableDisabled = false,
|
|
295
311
|
hasAutoFocus = false,
|
|
296
312
|
onChangeQuery,
|
|
297
313
|
onOpenChange,
|
|
298
314
|
inputId: externalInputId,
|
|
299
315
|
ariaDescribedBy,
|
|
316
|
+
ariaLabelledBy,
|
|
300
317
|
inputXStyle,
|
|
301
318
|
anchorRef,
|
|
302
319
|
onKeyDown: externalOnKeyDown,
|
|
@@ -311,6 +328,11 @@ export const BaseTypeahead = function BaseTypeahead<
|
|
|
311
328
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
312
329
|
const fallbackAnchorRef = useRef<HTMLInputElement>(null);
|
|
313
330
|
|
|
331
|
+
// Announce result counts / "no results" to screen readers via a persistent
|
|
332
|
+
// live region (comboboxes-6). The combobox's own popup carries no working
|
|
333
|
+
// live region, so highlight/result changes were previously silent.
|
|
334
|
+
const announce = useAnnounce();
|
|
335
|
+
|
|
314
336
|
const [query, setQuery] = useState('');
|
|
315
337
|
const [results, setResults] = useState<T[]>([]);
|
|
316
338
|
const [highlightedIndex, setHighlightedIndex] = useState(-1);
|
|
@@ -353,6 +375,9 @@ export const BaseTypeahead = function BaseTypeahead<
|
|
|
353
375
|
hasLightDismiss: true,
|
|
354
376
|
hasCloseButton: false,
|
|
355
377
|
hasAutoFocus: false,
|
|
378
|
+
// The popup's own role="listbox" is the exposed semantics; the input keeps
|
|
379
|
+
// DOM focus, so wrapping it in a modal dialog would misrepresent it.
|
|
380
|
+
role: 'none',
|
|
356
381
|
});
|
|
357
382
|
|
|
358
383
|
// Show the layer, deferring past the active click if a pointer is down.
|
|
@@ -394,11 +419,21 @@ export const BaseTypeahead = function BaseTypeahead<
|
|
|
394
419
|
return;
|
|
395
420
|
}
|
|
396
421
|
resultsGenRef.current = gen;
|
|
397
|
-
|
|
422
|
+
const shown = searchResults.slice(0, maxMenuItems);
|
|
423
|
+
setResults(shown);
|
|
398
424
|
setHighlightedIndex(searchResults.length > 0 ? 0 : -1);
|
|
399
425
|
if (searchResults.length > 0 || searchQuery.length > 0) {
|
|
400
426
|
showLayer();
|
|
401
427
|
}
|
|
428
|
+
// Announce the outcome only for an active query (not the initial
|
|
429
|
+
// focus-open), so screen-reader users hear result counts / no-results.
|
|
430
|
+
if (searchQuery.length > 0) {
|
|
431
|
+
announce(
|
|
432
|
+
shown.length === 0
|
|
433
|
+
? emptySearchResultsText
|
|
434
|
+
: `${shown.length} ${shown.length === 1 ? 'result' : 'results'}`,
|
|
435
|
+
);
|
|
436
|
+
}
|
|
402
437
|
} catch {
|
|
403
438
|
if (searchGenRef.current !== gen) {
|
|
404
439
|
return;
|
|
@@ -411,7 +446,7 @@ export const BaseTypeahead = function BaseTypeahead<
|
|
|
411
446
|
}
|
|
412
447
|
}
|
|
413
448
|
},
|
|
414
|
-
[searchSource, maxMenuItems, showLayer],
|
|
449
|
+
[searchSource, maxMenuItems, showLayer, announce, emptySearchResultsText],
|
|
415
450
|
);
|
|
416
451
|
|
|
417
452
|
// Perform bootstrap
|
|
@@ -456,6 +491,8 @@ export const BaseTypeahead = function BaseTypeahead<
|
|
|
456
491
|
searchSource.cancel?.();
|
|
457
492
|
setResults([]);
|
|
458
493
|
setHasSearched(false);
|
|
494
|
+
// Clear any lingering result-count / no-results announcement.
|
|
495
|
+
announce('');
|
|
459
496
|
popover.hide();
|
|
460
497
|
return;
|
|
461
498
|
}
|
|
@@ -482,6 +519,7 @@ export const BaseTypeahead = function BaseTypeahead<
|
|
|
482
519
|
popover,
|
|
483
520
|
debounceMs,
|
|
484
521
|
searchSource,
|
|
522
|
+
announce,
|
|
485
523
|
],
|
|
486
524
|
);
|
|
487
525
|
|
|
@@ -539,6 +577,32 @@ export const BaseTypeahead = function BaseTypeahead<
|
|
|
539
577
|
showLayer,
|
|
540
578
|
]);
|
|
541
579
|
|
|
580
|
+
// Handle blur — close the dropdown when focus leaves the input for an
|
|
581
|
+
// element that is neither inside the field wrapper (anchor) nor inside the
|
|
582
|
+
// dropdown popover. The native popover="auto" light-dismiss only fires on
|
|
583
|
+
// outside pointer clicks and Escape; it does not close when focus moves away
|
|
584
|
+
// via the keyboard (Tab) or programmatically, which would otherwise leave an
|
|
585
|
+
// orphaned open menu. Clicking a result moves focus onto the option (it is
|
|
586
|
+
// tabIndex={-1}, so it lives inside the popover) and selection re-focuses the
|
|
587
|
+
// input, so this only closes on a genuine focus-out of the whole field.
|
|
588
|
+
const handleBlur = useCallback(
|
|
589
|
+
(e: React.FocusEvent<HTMLInputElement>) => {
|
|
590
|
+
if (!popover.isOpen) {
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
const next = e.relatedTarget as Node | null;
|
|
594
|
+
if (next) {
|
|
595
|
+
const anchorEl = anchorRef?.current ?? fallbackAnchorRef.current;
|
|
596
|
+
const popoverEl = document.getElementById(popover.id);
|
|
597
|
+
if (anchorEl?.contains(next) || popoverEl?.contains(next)) {
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
popover.hide();
|
|
602
|
+
},
|
|
603
|
+
[popover, anchorRef],
|
|
604
|
+
);
|
|
605
|
+
|
|
542
606
|
// Keyboard navigation
|
|
543
607
|
const handleKeyDown = useCallback(
|
|
544
608
|
(e: React.KeyboardEvent<HTMLInputElement>) => {
|
|
@@ -615,6 +679,19 @@ export const BaseTypeahead = function BaseTypeahead<
|
|
|
615
679
|
[listboxId],
|
|
616
680
|
);
|
|
617
681
|
|
|
682
|
+
// Keep the highlighted option visible during keyboard navigation. The
|
|
683
|
+
// listbox is a fixed-height scroll container, so without this the virtual
|
|
684
|
+
// cursor walks off-screen once navigation passes the visible window. Mirrors
|
|
685
|
+
// CommandPaletteItem's scrollIntoView({block: 'nearest'}) behavior.
|
|
686
|
+
useEffect(() => {
|
|
687
|
+
if (!popover.isOpen || highlightedIndex < 0) {
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
document
|
|
691
|
+
.getElementById(getItemId(highlightedIndex))
|
|
692
|
+
?.scrollIntoView?.({block: 'nearest'});
|
|
693
|
+
}, [popover.isOpen, highlightedIndex, getItemId]);
|
|
694
|
+
|
|
618
695
|
const selectedKey =
|
|
619
696
|
value == null ? null : getKey(value.id, () => results.indexOf(value));
|
|
620
697
|
|
|
@@ -644,6 +721,8 @@ export const BaseTypeahead = function BaseTypeahead<
|
|
|
644
721
|
}
|
|
645
722
|
aria-autocomplete="list"
|
|
646
723
|
aria-describedby={ariaDescribedBy}
|
|
724
|
+
aria-labelledby={ariaLabelledBy}
|
|
725
|
+
aria-disabled={isFocusableDisabled ? 'true' : undefined}
|
|
647
726
|
value={query}
|
|
648
727
|
onChange={handleInputChange}
|
|
649
728
|
onPointerDown={() => {
|
|
@@ -657,9 +736,14 @@ export const BaseTypeahead = function BaseTypeahead<
|
|
|
657
736
|
);
|
|
658
737
|
}}
|
|
659
738
|
onFocus={handleFocus}
|
|
739
|
+
onBlur={handleBlur}
|
|
660
740
|
onKeyDown={handleKeyDown}
|
|
661
741
|
placeholder={placeholder}
|
|
662
|
-
disabled
|
|
742
|
+
// When a disabled-reason tooltip is shown the input keeps focusability
|
|
743
|
+
// via aria-disabled + readOnly instead of the native disabled
|
|
744
|
+
// attribute; value mutation stays blocked by the isDisabled guards.
|
|
745
|
+
disabled={isDisabled && !isFocusableDisabled}
|
|
746
|
+
readOnly={isFocusableDisabled || undefined}
|
|
663
747
|
autoFocus={hasAutoFocus}
|
|
664
748
|
data-autofocus={hasAutoFocus || undefined}
|
|
665
749
|
autoComplete="off"
|
|
@@ -7,8 +7,21 @@ export const docs = {
|
|
|
7
7
|
displayName: 'Typeahead',
|
|
8
8
|
group: 'Typeahead',
|
|
9
9
|
category: 'Data Input',
|
|
10
|
-
keywords: [
|
|
11
|
-
|
|
10
|
+
keywords: [
|
|
11
|
+
'typeahead',
|
|
12
|
+
'autocomplete',
|
|
13
|
+
'combobox',
|
|
14
|
+
'searchbox',
|
|
15
|
+
'autosuggest',
|
|
16
|
+
'select',
|
|
17
|
+
'dropdown',
|
|
18
|
+
'lookup',
|
|
19
|
+
'searchable',
|
|
20
|
+
'suggestion',
|
|
21
|
+
'picker',
|
|
22
|
+
],
|
|
23
|
+
description:
|
|
24
|
+
'Styled typeahead with label, description, validation, and all field features. Wraps BaseTypeahead with Field for the primary use case.',
|
|
12
25
|
props: [
|
|
13
26
|
{
|
|
14
27
|
name: 'label',
|
|
@@ -19,7 +32,8 @@ export const docs = {
|
|
|
19
32
|
{
|
|
20
33
|
name: 'searchSource',
|
|
21
34
|
type: 'SearchSource<T>',
|
|
22
|
-
description:
|
|
35
|
+
description:
|
|
36
|
+
'Data source providing search and bootstrap methods for populating the dropdown.',
|
|
23
37
|
required: true,
|
|
24
38
|
},
|
|
25
39
|
{
|
|
@@ -57,6 +71,12 @@ export const docs = {
|
|
|
57
71
|
description: 'Disables the input.',
|
|
58
72
|
default: 'false',
|
|
59
73
|
},
|
|
74
|
+
{
|
|
75
|
+
name: 'disabledMessage',
|
|
76
|
+
type: 'string',
|
|
77
|
+
description:
|
|
78
|
+
'Explains why the input is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the field focusable via aria-disabled (activation stays blocked). Use this instead of wrapping a disabled Typeahead in Tooltip — disabled controls swallow the hover events an external Tooltip needs.',
|
|
79
|
+
},
|
|
60
80
|
{
|
|
61
81
|
name: 'maxMenuItems',
|
|
62
82
|
type: 'number',
|
|
@@ -66,12 +86,14 @@ export const docs = {
|
|
|
66
86
|
{
|
|
67
87
|
name: 'status',
|
|
68
88
|
type: 'InputStatus',
|
|
69
|
-
description:
|
|
89
|
+
description:
|
|
90
|
+
'Validation status object with type and message for error/warning/success states.',
|
|
70
91
|
},
|
|
71
92
|
{
|
|
72
93
|
name: 'renderItem',
|
|
73
94
|
type: '(item: T) => ReactNode',
|
|
74
|
-
description:
|
|
95
|
+
description:
|
|
96
|
+
'Custom render function for dropdown items. Default renders TypeaheadItem.',
|
|
75
97
|
},
|
|
76
98
|
{
|
|
77
99
|
name: 'isLabelHidden',
|
|
@@ -122,7 +144,8 @@ export const docs = {
|
|
|
122
144
|
{
|
|
123
145
|
name: 'debounceMs',
|
|
124
146
|
type: 'number',
|
|
125
|
-
description:
|
|
147
|
+
description:
|
|
148
|
+
'Debounce delay in ms before triggering search. Set to 0 for synchronous sources.',
|
|
126
149
|
default: '150',
|
|
127
150
|
},
|
|
128
151
|
{
|
|
@@ -138,13 +161,11 @@ export const docs = {
|
|
|
138
161
|
{
|
|
139
162
|
name: 'xstyle',
|
|
140
163
|
type: 'StyleXStyles',
|
|
141
|
-
description:
|
|
164
|
+
description:
|
|
165
|
+
'StyleX styles for layout customization (margins, positioning, sizing). Must be a stylex.create() value: not an inline style object like style={{}}.',
|
|
142
166
|
},
|
|
143
167
|
],
|
|
144
|
-
components: [
|
|
145
|
-
{name: 'BaseTypeahead'},
|
|
146
|
-
{name: 'TypeaheadItem'},
|
|
147
|
-
],
|
|
168
|
+
components: [{name: 'BaseTypeahead'}, {name: 'TypeaheadItem'}],
|
|
148
169
|
theming: {
|
|
149
170
|
targets: [
|
|
150
171
|
{className: 'astryx-typeahead', visualProps: ['status']},
|
|
@@ -156,12 +177,45 @@ export const docs = {
|
|
|
156
177
|
description:
|
|
157
178
|
'A searchable input for selecting a single item from a large or dynamic dataset. Results appear as the user types, with support for async data sources, debounced search, and custom item rendering. Use it when the option list is too large for a Selector dropdown.',
|
|
158
179
|
bestPractices: [
|
|
159
|
-
{
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
{
|
|
180
|
+
{
|
|
181
|
+
guidance: true,
|
|
182
|
+
description:
|
|
183
|
+
'Provide descriptive placeholder text that hints at what users can search for.',
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
guidance: true,
|
|
187
|
+
description:
|
|
188
|
+
'Show suggestions on focus when users benefit from seeing popular or recent options before typing.',
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
guidance: true,
|
|
192
|
+
description:
|
|
193
|
+
'Add a search delay for remote data sources to avoid excessive network requests.',
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
guidance: true,
|
|
197
|
+
description:
|
|
198
|
+
'Use inside InputGroup when the typeahead needs a single-line prefix or suffix addon.',
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
guidance: false,
|
|
202
|
+
description:
|
|
203
|
+
'Use for short, static option lists; use Selector for better discoverability.',
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
guidance: false,
|
|
207
|
+
description: 'Use for multi-selection; use Tokenizer instead.',
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
guidance: false,
|
|
211
|
+
description:
|
|
212
|
+
'Place multiple Typeaheads adjacent to each other without clear labels differentiating them.',
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
guidance: false,
|
|
216
|
+
description:
|
|
217
|
+
'Wrap a disabled Typeahead in Tooltip to explain why it is disabled; disabled triggers swallow the hover events the wrapper needs. Use the disabledMessage prop instead.',
|
|
218
|
+
},
|
|
165
219
|
],
|
|
166
220
|
},
|
|
167
221
|
};
|
|
@@ -172,29 +226,86 @@ export const docsZh = {
|
|
|
172
226
|
description:
|
|
173
227
|
'A searchable input for selecting a single item from a large or dynamic dataset. Results appear as the user types, with support for async data sources, debounced search, and custom item rendering. Use it when the option list is too large for a Selector dropdown.',
|
|
174
228
|
bestPractices: [
|
|
175
|
-
{
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
{
|
|
229
|
+
{
|
|
230
|
+
guidance: true,
|
|
231
|
+
description:
|
|
232
|
+
'Provide descriptive placeholder text that hints at what users can search for.',
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
guidance: true,
|
|
236
|
+
description:
|
|
237
|
+
'Show suggestions on focus when users benefit from seeing popular or recent options before typing.',
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
guidance: true,
|
|
241
|
+
description:
|
|
242
|
+
'Add a search delay for remote data sources to avoid excessive network requests.',
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
guidance: false,
|
|
246
|
+
description:
|
|
247
|
+
'Use for short, static option lists; use Selector for better discoverability.',
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
guidance: false,
|
|
251
|
+
description: 'Use for multi-selection; use Tokenizer instead.',
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
guidance: false,
|
|
255
|
+
description:
|
|
256
|
+
'Place multiple Typeaheads adjacent to each other without clear labels differentiating them.',
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
guidance: false,
|
|
260
|
+
description:
|
|
261
|
+
'Wrap a disabled Typeahead in Tooltip to explain why it is disabled; disabled triggers swallow the hover events the wrapper needs. Use the disabledMessage prop instead.',
|
|
262
|
+
},
|
|
181
263
|
],
|
|
182
264
|
},
|
|
183
265
|
};
|
|
184
266
|
|
|
185
267
|
/** @type {import('../docs-types').TranslationDoc} */
|
|
186
268
|
export const docsDense = {
|
|
187
|
-
description:
|
|
269
|
+
description:
|
|
270
|
+
'Searchable dropdown for single-item selection w/ keyboard navigation. Supports async+sync search via searchSource interface.',
|
|
188
271
|
usage: {
|
|
189
272
|
description:
|
|
190
273
|
'A searchable input for selecting a single item from a large or dynamic dataset. Results appear as the user types, with support for async data sources, debounced search, and custom item rendering. Use it when the option list is too large for a Selector dropdown.',
|
|
191
274
|
bestPractices: [
|
|
192
|
-
{
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
{
|
|
275
|
+
{
|
|
276
|
+
guidance: true,
|
|
277
|
+
description:
|
|
278
|
+
'Provide descriptive placeholder text that hints at what users can search for.',
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
guidance: true,
|
|
282
|
+
description:
|
|
283
|
+
'Show suggestions on focus when users benefit from seeing popular or recent options before typing.',
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
guidance: true,
|
|
287
|
+
description:
|
|
288
|
+
'Add a search delay for remote data sources to avoid excessive network requests.',
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
guidance: false,
|
|
292
|
+
description:
|
|
293
|
+
'Use for short, static option lists; use Selector for better discoverability.',
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
guidance: false,
|
|
297
|
+
description: 'Use for multi-selection; use Tokenizer instead.',
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
guidance: false,
|
|
301
|
+
description:
|
|
302
|
+
'Place multiple Typeaheads adjacent to each other without clear labels differentiating them.',
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
guidance: false,
|
|
306
|
+
description:
|
|
307
|
+
'Wrap a disabled Typeahead in Tooltip to explain why it is disabled; disabled triggers swallow the hover events the wrapper needs. Use the disabledMessage prop instead.',
|
|
308
|
+
},
|
|
198
309
|
],
|
|
199
310
|
},
|
|
200
311
|
};
|