@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
|
@@ -95,6 +95,12 @@ export const docs = {
|
|
|
95
95
|
description: 'Whether the slider is disabled.',
|
|
96
96
|
default: 'false',
|
|
97
97
|
},
|
|
98
|
+
{
|
|
99
|
+
name: 'disabledMessage',
|
|
100
|
+
type: 'string',
|
|
101
|
+
description:
|
|
102
|
+
'Explains why the slider is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the thumb focusable via aria-disabled (value changes stay blocked). Use this instead of wrapping a disabled Slider in Tooltip — disabled controls swallow the hover events an external Tooltip needs.',
|
|
103
|
+
},
|
|
98
104
|
{
|
|
99
105
|
name: 'isOptional',
|
|
100
106
|
type: 'boolean',
|
|
@@ -151,6 +157,7 @@ export const docs = {
|
|
|
151
157
|
{guidance: true, description: 'Format values with meaningful units like "$50" or "75%" instead of raw numbers.'},
|
|
152
158
|
{guidance: false, description: 'Use for precise numeric entry; pair with a text input or use NumberInput instead.'},
|
|
153
159
|
{guidance: false, description: 'Set a step size so large that only a few positions are possible; use SegmentedControl or radio buttons instead.'},
|
|
160
|
+
{guidance: false, description: 'Wrap a disabled slider in Tooltip to explain why it is disabled; disabled controls swallow the hover events the wrapper needs. Use the disabledMessage prop instead.'},
|
|
154
161
|
],
|
|
155
162
|
},
|
|
156
163
|
};
|
|
@@ -237,6 +244,12 @@ export const docsZh = {
|
|
|
237
244
|
description: '是否禁用滑块。',
|
|
238
245
|
default: 'false',
|
|
239
246
|
},
|
|
247
|
+
{
|
|
248
|
+
name: 'disabledMessage',
|
|
249
|
+
type: 'string',
|
|
250
|
+
description:
|
|
251
|
+
'Explains why the slider is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the thumb focusable via aria-disabled (value changes stay blocked). Use this instead of wrapping a disabled Slider in Tooltip — disabled controls swallow the hover events an external Tooltip needs.',
|
|
252
|
+
},
|
|
240
253
|
{
|
|
241
254
|
name: 'isOptional',
|
|
242
255
|
type: 'boolean',
|
|
@@ -293,6 +306,7 @@ export const docsZh = {
|
|
|
293
306
|
{guidance: true, description: 'Format values with meaningful units like "$50" or "75%" instead of raw numbers.'},
|
|
294
307
|
{guidance: false, description: 'Use for precise numeric entry; pair with a text input or use NumberInput instead.'},
|
|
295
308
|
{guidance: false, description: 'Set a step size so large that only a few positions are possible; use SegmentedControl or radio buttons instead.'},
|
|
309
|
+
{guidance: false, description: 'Wrap a disabled slider in Tooltip to explain why it is disabled; disabled controls swallow the hover events the wrapper needs. Use the disabledMessage prop instead.'},
|
|
296
310
|
],
|
|
297
311
|
},
|
|
298
312
|
};
|
|
@@ -307,6 +321,7 @@ export const docsDense = {
|
|
|
307
321
|
{guidance: true, description: 'Format values with meaningful units like "$50" or "75%" instead of raw numbers.'},
|
|
308
322
|
{guidance: false, description: 'Use for precise numeric entry; pair with a text input or use NumberInput instead.'},
|
|
309
323
|
{guidance: false, description: 'Set a step size so large that only a few positions are possible; use SegmentedControl or radio buttons instead.'},
|
|
324
|
+
{guidance: false, description: 'Wrap a disabled slider in Tooltip to explain why it is disabled; disabled controls swallow the hover events the wrapper needs. Use the disabledMessage prop instead.'},
|
|
310
325
|
],
|
|
311
326
|
},
|
|
312
327
|
propDescriptions: {
|
|
@@ -9,11 +9,44 @@
|
|
|
9
9
|
* SYNC: When Slider.tsx changes, update tests to match new behavior
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import {describe, it, expect, vi} from 'vitest';
|
|
13
|
-
import {render, screen, act, fireEvent} from '@testing-library/react';
|
|
12
|
+
import {describe, it, expect, vi, beforeEach} from 'vitest';
|
|
13
|
+
import {render, screen, act, fireEvent, waitFor} from '@testing-library/react';
|
|
14
14
|
import userEvent from '@testing-library/user-event';
|
|
15
15
|
import {Slider} from './Slider';
|
|
16
16
|
|
|
17
|
+
// Mock showPopover/hidePopover (not implemented in jsdom) so the tooltip layer
|
|
18
|
+
// reflects its open state via a `popover-open` attribute the tests can assert.
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
HTMLElement.prototype.showPopover = vi.fn(function (this: HTMLElement) {
|
|
21
|
+
this.setAttribute('popover-open', '');
|
|
22
|
+
const event = new Event('toggle', {bubbles: false});
|
|
23
|
+
Object.defineProperty(event, 'newState', {value: 'open'});
|
|
24
|
+
this.dispatchEvent(event);
|
|
25
|
+
});
|
|
26
|
+
HTMLElement.prototype.hidePopover = vi.fn(function (this: HTMLElement) {
|
|
27
|
+
this.removeAttribute('popover-open');
|
|
28
|
+
const event = new Event('toggle', {bubbles: false});
|
|
29
|
+
Object.defineProperty(event, 'newState', {value: 'closed'});
|
|
30
|
+
this.dispatchEvent(event);
|
|
31
|
+
});
|
|
32
|
+
const originalMatches = HTMLElement.prototype.matches;
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
34
|
+
(HTMLElement.prototype as any).matches = function (
|
|
35
|
+
selector: string,
|
|
36
|
+
): boolean {
|
|
37
|
+
if (selector === ':popover-open') {
|
|
38
|
+
return this.hasAttribute('popover-open');
|
|
39
|
+
}
|
|
40
|
+
// jsdom does not derive :focus-visible from keyboard focus for a
|
|
41
|
+
// div[role="slider"] thumb; treat the focused thumb as focus-visible so the
|
|
42
|
+
// disabled-reason tooltip's keyboard-focus path can be exercised.
|
|
43
|
+
if (selector === ':focus-visible') {
|
|
44
|
+
return this === document.activeElement;
|
|
45
|
+
}
|
|
46
|
+
return originalMatches.call(this, selector);
|
|
47
|
+
};
|
|
48
|
+
});
|
|
49
|
+
|
|
17
50
|
describe('Slider', () => {
|
|
18
51
|
// --- Aria labels ---
|
|
19
52
|
|
|
@@ -382,4 +415,124 @@ describe('Slider', () => {
|
|
|
382
415
|
await user.keyboard('{ArrowLeft}');
|
|
383
416
|
expect(handleChange).toHaveBeenCalledWith(0);
|
|
384
417
|
});
|
|
418
|
+
|
|
419
|
+
describe('disabledMessage', () => {
|
|
420
|
+
const h = {hidden: true} as const;
|
|
421
|
+
|
|
422
|
+
function getTrack(): HTMLElement {
|
|
423
|
+
return screen.getByRole('slider').parentElement!;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
it('shows the reason tooltip on hover when disabled with a reason', async () => {
|
|
427
|
+
render(
|
|
428
|
+
<Slider
|
|
429
|
+
label="Volume"
|
|
430
|
+
value={50}
|
|
431
|
+
valueDisplay="none"
|
|
432
|
+
isDisabled
|
|
433
|
+
disabledMessage="Volume is locked while sharing your screen"
|
|
434
|
+
/>,
|
|
435
|
+
);
|
|
436
|
+
const tooltip = screen.getByRole('tooltip', h);
|
|
437
|
+
expect(tooltip).toHaveTextContent(
|
|
438
|
+
'Volume is locked while sharing your screen',
|
|
439
|
+
);
|
|
440
|
+
fireEvent.mouseEnter(getTrack());
|
|
441
|
+
await waitFor(() => expect(tooltip).toHaveAttribute('popover-open'));
|
|
442
|
+
fireEvent.mouseLeave(getTrack());
|
|
443
|
+
await waitFor(() => expect(tooltip).not.toHaveAttribute('popover-open'));
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
it('shows the reason tooltip on keyboard focus', async () => {
|
|
447
|
+
const user = userEvent.setup();
|
|
448
|
+
render(
|
|
449
|
+
<Slider
|
|
450
|
+
label="Volume"
|
|
451
|
+
value={50}
|
|
452
|
+
valueDisplay="none"
|
|
453
|
+
isDisabled
|
|
454
|
+
disabledMessage="Volume is locked while sharing your screen"
|
|
455
|
+
/>,
|
|
456
|
+
);
|
|
457
|
+
const tooltip = screen.getByRole('tooltip', h);
|
|
458
|
+
await user.tab();
|
|
459
|
+
expect(screen.getByRole('slider')).toHaveFocus();
|
|
460
|
+
await waitFor(() => expect(tooltip).toHaveAttribute('popover-open'));
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
it('does not render a tooltip when not disabled', () => {
|
|
464
|
+
render(
|
|
465
|
+
<Slider
|
|
466
|
+
label="Volume"
|
|
467
|
+
value={50}
|
|
468
|
+
valueDisplay="none"
|
|
469
|
+
disabledMessage="Volume is locked while sharing your screen"
|
|
470
|
+
/>,
|
|
471
|
+
);
|
|
472
|
+
expect(screen.queryByRole('tooltip', h)).not.toBeInTheDocument();
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
it('does not render a tooltip when disabled without a reason', () => {
|
|
476
|
+
render(
|
|
477
|
+
<Slider label="Volume" value={50} valueDisplay="none" isDisabled />,
|
|
478
|
+
);
|
|
479
|
+
expect(screen.queryByRole('tooltip', h)).not.toBeInTheDocument();
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
it('keeps the thumb focusable via aria-disabled when a reason is provided', () => {
|
|
483
|
+
render(
|
|
484
|
+
<Slider
|
|
485
|
+
label="Volume"
|
|
486
|
+
value={50}
|
|
487
|
+
valueDisplay="none"
|
|
488
|
+
isDisabled
|
|
489
|
+
disabledMessage="Volume is locked while sharing your screen"
|
|
490
|
+
/>,
|
|
491
|
+
);
|
|
492
|
+
const thumb = screen.getByRole('slider');
|
|
493
|
+
expect(thumb).toHaveAttribute('aria-disabled', 'true');
|
|
494
|
+
expect(thumb).toHaveAttribute('tabindex', '0');
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
it('links the reason tooltip via aria-describedby', () => {
|
|
498
|
+
render(
|
|
499
|
+
<Slider
|
|
500
|
+
label="Volume"
|
|
501
|
+
value={50}
|
|
502
|
+
valueDisplay="none"
|
|
503
|
+
isDisabled
|
|
504
|
+
disabledMessage="Volume is locked while sharing your screen"
|
|
505
|
+
/>,
|
|
506
|
+
);
|
|
507
|
+
const thumb = screen.getByRole('slider');
|
|
508
|
+
const tooltip = screen.getByRole('tooltip', h);
|
|
509
|
+
expect(thumb.getAttribute('aria-describedby')).toContain(tooltip.id);
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
it('blocks value changes while focusable-disabled', async () => {
|
|
513
|
+
const user = userEvent.setup();
|
|
514
|
+
const onChange = vi.fn();
|
|
515
|
+
render(
|
|
516
|
+
<Slider
|
|
517
|
+
label="Volume"
|
|
518
|
+
value={50}
|
|
519
|
+
valueDisplay="none"
|
|
520
|
+
onChange={onChange}
|
|
521
|
+
isDisabled
|
|
522
|
+
disabledMessage="Volume is locked while sharing your screen"
|
|
523
|
+
/>,
|
|
524
|
+
);
|
|
525
|
+
const thumb = screen.getByRole('slider');
|
|
526
|
+
thumb.focus();
|
|
527
|
+
await user.keyboard('{ArrowRight}');
|
|
528
|
+
expect(onChange).not.toHaveBeenCalled();
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
it('remains non-focusable when disabled without a reason', () => {
|
|
532
|
+
render(
|
|
533
|
+
<Slider label="Volume" value={50} valueDisplay="none" isDisabled />,
|
|
534
|
+
);
|
|
535
|
+
expect(screen.getByRole('slider')).toHaveAttribute('tabindex', '-1');
|
|
536
|
+
});
|
|
537
|
+
});
|
|
385
538
|
});
|
package/src/Slider/Slider.tsx
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @file Slider.tsx
|
|
7
|
-
* @input Uses React, useId, useRef, useCallback, Field, Tooltip
|
|
7
|
+
* @input Uses React, useId, useRef, useCallback, Field, Tooltip, useTooltip
|
|
8
8
|
* @output Exports Slider component, SliderProps, SliderSingleProps, SliderRangeProps, SliderBaseProps
|
|
9
9
|
* @position Core implementation; consumed by index.ts, tested by Slider.test.tsx
|
|
10
10
|
*
|
|
@@ -37,6 +37,7 @@ import {
|
|
|
37
37
|
} from '../theme/tokens.stylex';
|
|
38
38
|
import {Field} from '../Field/Field';
|
|
39
39
|
import {Tooltip} from '../Tooltip/Tooltip';
|
|
40
|
+
import {useTooltip} from '../Tooltip';
|
|
40
41
|
import type {InputStatus} from '../Field/types';
|
|
41
42
|
import {mergeProps, mergeRefs} from '../utils';
|
|
42
43
|
import type {BaseProps} from '../BaseProps';
|
|
@@ -61,6 +62,27 @@ export interface SliderBaseProps extends Omit<
|
|
|
61
62
|
description?: string;
|
|
62
63
|
/** Whether the slider is disabled. @default false */
|
|
63
64
|
isDisabled?: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Explains why the slider is disabled. When set together with `isDisabled`,
|
|
67
|
+
* the slider shows a tooltip with this text on hover and keyboard focus, and
|
|
68
|
+
* the thumb stays focusable (via `aria-disabled`) so the reason is
|
|
69
|
+
* discoverable by keyboard and assistive technology. Value changes stay
|
|
70
|
+
* blocked.
|
|
71
|
+
*
|
|
72
|
+
* Use this instead of wrapping a disabled slider in `Tooltip` — disabled
|
|
73
|
+
* controls don't emit the pointer events an external tooltip needs.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```
|
|
77
|
+
* <Slider
|
|
78
|
+
* label="Volume"
|
|
79
|
+
* value={50}
|
|
80
|
+
* isDisabled
|
|
81
|
+
* disabledMessage="Volume is locked while sharing your screen"
|
|
82
|
+
* />
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
disabledMessage?: string;
|
|
64
86
|
/** Whether the field is optional. @default false */
|
|
65
87
|
isOptional?: boolean;
|
|
66
88
|
/** Whether the field is required. @default false */
|
|
@@ -331,6 +353,7 @@ export function Slider({ref, ...props}: SliderProps) {
|
|
|
331
353
|
isLabelHidden = false,
|
|
332
354
|
description,
|
|
333
355
|
isDisabled = false,
|
|
356
|
+
disabledMessage,
|
|
334
357
|
isOptional = false,
|
|
335
358
|
isRequired = false,
|
|
336
359
|
status,
|
|
@@ -368,6 +391,20 @@ export function Slider({ref, ...props}: SliderProps) {
|
|
|
368
391
|
const draggingThumbRef = useRef<number | null>(null);
|
|
369
392
|
const [draggingThumb, setDraggingThumb] = useState<number | null>(null);
|
|
370
393
|
|
|
394
|
+
// Disabled-reason tooltip. This is a *separate* useTooltip instance from the
|
|
395
|
+
// per-thumb value bubble (the `<Tooltip>` component below): it anchors to the
|
|
396
|
+
// track container and fires on hover/focus of the whole control. Disabled
|
|
397
|
+
// controls swallow pointer events, so the thumb stays perceivable via
|
|
398
|
+
// aria-disabled while pointer/keyboard handlers early-return on isDisabled.
|
|
399
|
+
const showsDisabledMessage = isDisabled && !!disabledMessage;
|
|
400
|
+
const disabledMessageTooltip = useTooltip({
|
|
401
|
+
placement: 'above',
|
|
402
|
+
// The track container is not naturally focusable; focusin bubbles up from
|
|
403
|
+
// the thumb, so always attach focus listeners.
|
|
404
|
+
focusTrigger: 'always',
|
|
405
|
+
isEnabled: showsDisabledMessage,
|
|
406
|
+
});
|
|
407
|
+
|
|
371
408
|
// Build aria-describedby
|
|
372
409
|
const describedByParts: string[] = [];
|
|
373
410
|
if (description) {
|
|
@@ -376,6 +413,9 @@ export function Slider({ref, ...props}: SliderProps) {
|
|
|
376
413
|
if (status?.message) {
|
|
377
414
|
describedByParts.push(statusMessageID);
|
|
378
415
|
}
|
|
416
|
+
if (showsDisabledMessage) {
|
|
417
|
+
describedByParts.push(disabledMessageTooltip.describedBy);
|
|
418
|
+
}
|
|
379
419
|
const ariaDescribedBy =
|
|
380
420
|
describedByParts.length > 0 ? describedByParts.join(' ') : undefined;
|
|
381
421
|
|
|
@@ -641,7 +681,10 @@ export function Slider({ref, ...props}: SliderProps) {
|
|
|
641
681
|
: `${label}, maximum value`
|
|
642
682
|
: label;
|
|
643
683
|
|
|
644
|
-
|
|
684
|
+
// Suppress the per-thumb value bubble while the disabled-message tooltip is
|
|
685
|
+
// showing, so a disabled slider surfaces the *reason* on hover/focus rather
|
|
686
|
+
// than stacking two tooltips over the same thumb.
|
|
687
|
+
const useValueTooltip = valueDisplay === 'tooltip' && !showsDisabledMessage;
|
|
645
688
|
const tooltipPlacement = isHorizontal ? 'above' : 'start';
|
|
646
689
|
|
|
647
690
|
const thumbElement = (
|
|
@@ -649,7 +692,10 @@ export function Slider({ref, ...props}: SliderProps) {
|
|
|
649
692
|
key={thumbIndex}
|
|
650
693
|
id={!isRange ? id : undefined}
|
|
651
694
|
role="slider"
|
|
652
|
-
|
|
695
|
+
// With a disabledMessage the thumb keeps focusability so the reason is
|
|
696
|
+
// focus-discoverable; value changes stay blocked by the isDisabled
|
|
697
|
+
// guards in the pointer/keyboard handlers.
|
|
698
|
+
tabIndex={isDisabled && !showsDisabledMessage ? -1 : 0}
|
|
653
699
|
aria-valuemin={min}
|
|
654
700
|
aria-valuemax={max}
|
|
655
701
|
aria-valuenow={val}
|
|
@@ -678,7 +724,7 @@ export function Slider({ref, ...props}: SliderProps) {
|
|
|
678
724
|
/>
|
|
679
725
|
);
|
|
680
726
|
|
|
681
|
-
if (
|
|
727
|
+
if (useValueTooltip) {
|
|
682
728
|
return (
|
|
683
729
|
<Tooltip
|
|
684
730
|
key={thumbIndex}
|
|
@@ -758,7 +804,7 @@ export function Slider({ref, ...props}: SliderProps) {
|
|
|
758
804
|
stylex.props(styles.sliderRow),
|
|
759
805
|
)}>
|
|
760
806
|
<div
|
|
761
|
-
ref={mergeRefs(ref, trackRef)}
|
|
807
|
+
ref={mergeRefs(ref, trackRef, disabledMessageTooltip.ref)}
|
|
762
808
|
{...(isRange ? {role: 'group', 'aria-label': label} : undefined)}
|
|
763
809
|
onPointerDown={handlePointerDown}
|
|
764
810
|
onPointerMove={handlePointerMove}
|
|
@@ -855,6 +901,8 @@ export function Slider({ref, ...props}: SliderProps) {
|
|
|
855
901
|
|
|
856
902
|
{textDisplay}
|
|
857
903
|
</div>
|
|
904
|
+
{showsDisabledMessage &&
|
|
905
|
+
disabledMessageTooltip.renderTooltip(disabledMessage)}
|
|
858
906
|
</Field>
|
|
859
907
|
);
|
|
860
908
|
}
|
package/src/Spinner/Spinner.tsx
CHANGED
|
@@ -70,7 +70,13 @@ const styles = stylex.create({
|
|
|
70
70
|
canvas: {
|
|
71
71
|
backfaceVisibility: 'hidden',
|
|
72
72
|
display: 'block',
|
|
73
|
-
|
|
73
|
+
// Slow the rotation dramatically under reduced-motion rather than freezing
|
|
74
|
+
// it (a frozen spinner reads as broken), matching ProgressBar's approach.
|
|
75
|
+
// The role="status" + "Loading" label still convey busy state (obs-6).
|
|
76
|
+
animationDuration: {
|
|
77
|
+
default: durationVars['--duration-slow-min'],
|
|
78
|
+
'@media (prefers-reduced-motion: reduce)': '3s',
|
|
79
|
+
},
|
|
74
80
|
animationIterationCount: 'infinite',
|
|
75
81
|
animationName: rotation,
|
|
76
82
|
animationTimingFunction: 'linear',
|
package/src/Stack/Stack.doc.mjs
CHANGED
|
@@ -28,6 +28,31 @@ export const docs = {
|
|
|
28
28
|
description:
|
|
29
29
|
'Spacing step (number literal): 0, 0.5, 1, 1.5, 2, 3, 4, 5, 6, 8, 10. Pass as a JSX number expression e.g. gap={4}, NOT a string like gap="4".',
|
|
30
30
|
},
|
|
31
|
+
{
|
|
32
|
+
name: 'padding',
|
|
33
|
+
type: 'SpacingStep',
|
|
34
|
+
description:
|
|
35
|
+
'Inner padding on all sides, using the spacing scale (0, 0.5, 1, 1.5, 2, 3, 4, 5, 6, 8, 10). Matches the padding prop on Card, LayoutContent, and LayoutPanel. Pass as a JSX number expression e.g. padding={3}.',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'paddingInline',
|
|
39
|
+
type: 'SpacingStep',
|
|
40
|
+
description:
|
|
41
|
+
'Inline (horizontal) padding, using the spacing scale. Overrides padding on the inline axis when both are set.',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: 'paddingBlock',
|
|
45
|
+
type: 'SpacingStep',
|
|
46
|
+
description:
|
|
47
|
+
'Block (vertical) padding, using the spacing scale. Overrides padding on the block axis when both are set.',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'isScrollable',
|
|
51
|
+
type: 'boolean',
|
|
52
|
+
description:
|
|
53
|
+
'Enables scrollable overflow (overflow: auto). Matches isScrollable on LayoutContent and LayoutPanel.',
|
|
54
|
+
default: 'false',
|
|
55
|
+
},
|
|
31
56
|
{
|
|
32
57
|
name: 'width',
|
|
33
58
|
type: 'SizeValue',
|
|
@@ -38,6 +63,16 @@ export const docs = {
|
|
|
38
63
|
type: 'SizeValue',
|
|
39
64
|
description: "Height of the stack container. Numbers are treated as pixels, strings are used as-is (e.g., '100%').",
|
|
40
65
|
},
|
|
66
|
+
{
|
|
67
|
+
name: 'maxWidth',
|
|
68
|
+
type: 'SizeValue',
|
|
69
|
+
description: "Maximum width of the stack container. Numbers are treated as pixels, strings are used as-is (e.g., '100%').",
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: 'minHeight',
|
|
73
|
+
type: 'SizeValue',
|
|
74
|
+
description: "Minimum height of the stack container. Numbers are treated as pixels, strings are used as-is (e.g., '100%').",
|
|
75
|
+
},
|
|
41
76
|
{
|
|
42
77
|
name: 'hAlign',
|
|
43
78
|
type: "'start' | 'center' | 'end' | 'between' | 'around' | 'evenly'",
|
|
@@ -96,6 +131,31 @@ export const docs = {
|
|
|
96
131
|
description:
|
|
97
132
|
'Spacing step (number literal): 0, 0.5, 1, 1.5, 2, 3, 4, 5, 6, 8, 10. Pass as a JSX number expression e.g. gap={4}, NOT a string like gap="4".',
|
|
98
133
|
},
|
|
134
|
+
{
|
|
135
|
+
name: 'padding',
|
|
136
|
+
type: 'SpacingStep',
|
|
137
|
+
description:
|
|
138
|
+
'Inner padding on all sides, using the spacing scale (0, 0.5, 1, 1.5, 2, 3, 4, 5, 6, 8, 10). Matches the padding prop on Card, LayoutContent, and LayoutPanel. Pass as a JSX number expression e.g. padding={3}.',
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
name: 'paddingInline',
|
|
142
|
+
type: 'SpacingStep',
|
|
143
|
+
description:
|
|
144
|
+
'Inline (horizontal) padding, using the spacing scale. Overrides padding on the inline axis when both are set.',
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
name: 'paddingBlock',
|
|
148
|
+
type: 'SpacingStep',
|
|
149
|
+
description:
|
|
150
|
+
'Block (vertical) padding, using the spacing scale. Overrides padding on the block axis when both are set.',
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
name: 'isScrollable',
|
|
154
|
+
type: 'boolean',
|
|
155
|
+
description:
|
|
156
|
+
'Enables scrollable overflow (overflow: auto). Matches isScrollable on LayoutContent and LayoutPanel.',
|
|
157
|
+
default: 'false',
|
|
158
|
+
},
|
|
99
159
|
{
|
|
100
160
|
name: 'width',
|
|
101
161
|
type: 'SizeValue',
|
|
@@ -106,6 +166,16 @@ export const docs = {
|
|
|
106
166
|
type: 'SizeValue',
|
|
107
167
|
description: "Height of the stack container. Numbers are treated as pixels, strings are used as-is (e.g., '100%').",
|
|
108
168
|
},
|
|
169
|
+
{
|
|
170
|
+
name: 'maxWidth',
|
|
171
|
+
type: 'SizeValue',
|
|
172
|
+
description: "Maximum width of the stack container. Numbers are treated as pixels, strings are used as-is (e.g., '100%').",
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
name: 'minHeight',
|
|
176
|
+
type: 'SizeValue',
|
|
177
|
+
description: "Minimum height of the stack container. Numbers are treated as pixels, strings are used as-is (e.g., '100%').",
|
|
178
|
+
},
|
|
109
179
|
{
|
|
110
180
|
name: 'hAlign',
|
|
111
181
|
type: "'start' | 'center' | 'end' | 'stretch'",
|
|
@@ -160,6 +230,13 @@ export const docs = {
|
|
|
160
230
|
'Flex grow behavior: static keeps natural size, fill expands to consume remaining space.',
|
|
161
231
|
default: "'static'",
|
|
162
232
|
},
|
|
233
|
+
{
|
|
234
|
+
name: 'isScrollable',
|
|
235
|
+
type: 'boolean',
|
|
236
|
+
description:
|
|
237
|
+
'Enables scrollable overflow (overflow: auto). StackItem already applies the flex min-height/min-width reset, so <StackItem size="fill" isScrollable> is a complete scroll region. Matches isScrollable on LayoutContent and LayoutPanel.',
|
|
238
|
+
default: 'false',
|
|
239
|
+
},
|
|
163
240
|
{
|
|
164
241
|
name: 'crossAlignSelf',
|
|
165
242
|
type: "'start' | 'center' | 'end' | 'stretch'",
|
package/src/Stack/Stack.test.tsx
CHANGED
|
@@ -253,15 +253,65 @@ describe('Stack', () => {
|
|
|
253
253
|
|
|
254
254
|
it('applies both width and height together', () => {
|
|
255
255
|
render(
|
|
256
|
-
<Stack
|
|
257
|
-
direction="vertical"
|
|
258
|
-
width={400}
|
|
259
|
-
height="100%"
|
|
260
|
-
data-testid="stack">
|
|
256
|
+
<Stack direction="vertical" width={400} height="100%" data-testid="stack">
|
|
261
257
|
<div>Item</div>
|
|
262
258
|
</Stack>,
|
|
263
259
|
);
|
|
264
260
|
const el = screen.getByTestId('stack');
|
|
265
261
|
expect(el).toHaveStyle({width: '400px', height: '100%'});
|
|
266
262
|
});
|
|
263
|
+
|
|
264
|
+
it('applies a class when padding is set', () => {
|
|
265
|
+
render(
|
|
266
|
+
<Stack padding={3} data-testid="stack">
|
|
267
|
+
<div>Item</div>
|
|
268
|
+
</Stack>,
|
|
269
|
+
);
|
|
270
|
+
expect(screen.getByTestId('stack').className).not.toBe('');
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
it('accepts paddingInline and paddingBlock without error', () => {
|
|
274
|
+
render(
|
|
275
|
+
<Stack paddingInline={4} paddingBlock={2} data-testid="stack">
|
|
276
|
+
<div>Item</div>
|
|
277
|
+
</Stack>,
|
|
278
|
+
);
|
|
279
|
+
expect(screen.getByTestId('stack')).toBeInTheDocument();
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
it('lets paddingInline/paddingBlock override padding on their axis', () => {
|
|
283
|
+
// padding sets both axes; paddingInline overrides the inline axis. The
|
|
284
|
+
// component should render without conflict and carry a class.
|
|
285
|
+
render(
|
|
286
|
+
<Stack padding={2} paddingInline={5} data-testid="stack">
|
|
287
|
+
<div>Item</div>
|
|
288
|
+
</Stack>,
|
|
289
|
+
);
|
|
290
|
+
expect(screen.getByTestId('stack').className).not.toBe('');
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
it('applies a class when isScrollable is set', () => {
|
|
294
|
+
render(
|
|
295
|
+
<Stack isScrollable data-testid="stack">
|
|
296
|
+
<div>Item</div>
|
|
297
|
+
</Stack>,
|
|
298
|
+
);
|
|
299
|
+
expect(screen.getByTestId('stack').className).not.toBe('');
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
it('does not set overflow class when isScrollable is false', () => {
|
|
303
|
+
const {rerender} = render(
|
|
304
|
+
<Stack data-testid="stack">
|
|
305
|
+
<div>Item</div>
|
|
306
|
+
</Stack>,
|
|
307
|
+
);
|
|
308
|
+
const withoutScroll = screen.getByTestId('stack').className;
|
|
309
|
+
rerender(
|
|
310
|
+
<Stack isScrollable data-testid="stack">
|
|
311
|
+
<div>Item</div>
|
|
312
|
+
</Stack>,
|
|
313
|
+
);
|
|
314
|
+
const withScroll = screen.getByTestId('stack').className;
|
|
315
|
+
expect(withScroll).not.toBe(withoutScroll);
|
|
316
|
+
});
|
|
267
317
|
});
|