@astryxdesign/core 0.1.1 → 0.1.2-canary.04e71b2
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 +105 -0
- package/README.md +131 -13
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +11 -5
- package/dist/AvatarGroup/AvatarGroupOverflow.d.ts +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.js +4 -1
- package/dist/Banner/Banner.d.ts +7 -0
- package/dist/Banner/Banner.d.ts.map +1 -1
- package/dist/Banner/Banner.js +9 -2
- 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 +12 -2
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +53 -17
- 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/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.map +1 -1
- package/dist/Chat/useTriggerMenu.js +4 -1
- 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/Citation/Citation.d.ts.map +1 -1
- package/dist/Citation/Citation.js +3 -3
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +49 -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 +59 -8
- 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/EmptyState/EmptyState.d.ts.map +1 -1
- package/dist/EmptyState/EmptyState.js +7 -1
- 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 +8 -0
- package/dist/HoverCard/HoverCard.d.ts +2 -2
- package/dist/HoverCard/HoverCard.d.ts.map +1 -1
- package/dist/HoverCard/HoverCard.js +18 -6
- package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
- package/dist/HoverCard/useHoverCard.js +7 -3
- package/dist/InputGroup/InputGroup.d.ts +2 -2
- package/dist/InputGroup/InputGroup.d.ts.map +1 -1
- package/dist/InputGroup/InputGroup.js +14 -5
- 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/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 +34 -2
- package/dist/Layer/anchorName.d.ts +20 -0
- package/dist/Layer/anchorName.d.ts.map +1 -0
- package/dist/Layer/anchorName.js +36 -0
- 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 +29 -0
- package/dist/Layer/useLayer.d.ts.map +1 -1
- package/dist/Layer/useLayer.js +55 -11
- 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 +17 -2
- package/dist/Link/Link.d.ts.map +1 -1
- package/dist/Link/Link.js +20 -9
- package/dist/Link/LinkProvider.d.ts +1 -0
- package/dist/Link/LinkProvider.d.ts.map +1 -1
- package/dist/Link/LinkProvider.js +1 -0
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.js +18 -3
- package/dist/MobileNav/MobileNav.d.ts.map +1 -1
- package/dist/MobileNav/MobileNav.js +13 -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 +25 -2
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +103 -22
- 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 +46 -28
- package/dist/Popover/usePopover.d.ts +25 -2
- package/dist/Popover/usePopover.d.ts.map +1 -1
- package/dist/Popover/usePopover.js +18 -6
- 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 +22 -1
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +84 -23
- 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/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 +38 -11
- 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 +86 -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 +38 -16
- package/dist/Table/Table.d.ts.map +1 -1
- package/dist/Table/Table.js +36 -7
- 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/TableRow.d.ts +6 -1
- package/dist/Table/TableRow.d.ts.map +1 -1
- package/dist/Table/TableRow.js +15 -7
- package/dist/Table/index.d.ts +4 -1
- package/dist/Table/index.d.ts.map +1 -1
- package/dist/Table/index.js +3 -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/plugins/stickyColumns/index.d.ts +3 -0
- package/dist/Table/plugins/stickyColumns/index.d.ts.map +1 -0
- package/dist/Table/plugins/stickyColumns/index.js +3 -0
- package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts +25 -0
- package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -0
- package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +369 -0
- 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 +161 -5
- package/dist/Table/types.d.ts.map +1 -1
- package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
- package/dist/Table/useBaseTablePlugins.js +1 -1
- package/dist/Text/text.stylex.d.ts +2 -2
- package/dist/Text/text.stylex.js +2 -2
- 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 +53 -10
- package/dist/Timestamp/Timestamp.d.ts +1 -1
- package/dist/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +28 -3
- 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 +132 -3
- package/dist/ToggleButton/ToggleButton.d.ts +7 -9
- package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
- package/dist/ToggleButton/ToggleButton.js +34 -57
- package/dist/Tokenizer/Tokenizer.d.ts +12 -1
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +27 -5
- 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 +57 -9
- 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 +9 -0
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +67 -6
- package/dist/Typeahead/Typeahead.d.ts +24 -1
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +29 -5
- 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 +40 -1
- package/dist/astryx.umd.js +147 -0
- package/dist/astryx.umd.js.map +7 -0
- 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/theme/generateThemeRules.js +1 -1
- package/dist/theme/syntax/SyntaxTheme.d.ts +1 -1
- package/dist/theme/syntax/SyntaxTheme.js +1 -1
- package/dist/theme/syntax/defineSyntaxTheme.d.ts.map +1 -1
- package/dist/theme/syntax/defineSyntaxTheme.js +2 -2
- package/dist/theme/syntax/presets.d.ts +1 -1
- package/dist/theme/syntax/presets.d.ts.map +1 -1
- package/dist/theme/syntax/presets.js +1 -1
- package/dist/theme/syntax/tokens.d.ts +1 -1
- package/dist/theme/syntax/tokens.js +1 -1
- package/dist/theme/types.d.ts +1 -1
- 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/package.json +15 -5
- package/src/Avatar/Avatar.test.tsx +37 -0
- package/src/Avatar/Avatar.tsx +10 -5
- package/src/AvatarGroup/AvatarGroupOverflow.tsx +3 -0
- package/src/Banner/Banner.doc.mjs +8 -0
- package/src/Banner/Banner.test.tsx +16 -7
- package/src/Banner/Banner.tsx +9 -2
- package/src/Breadcrumbs/BreadcrumbItem.tsx +25 -7
- package/src/Breadcrumbs/Breadcrumbs.test.tsx +31 -10
- package/src/Button/Button.doc.mjs +6 -0
- package/src/Button/Button.test.tsx +105 -11
- package/src/Button/Button.tsx +76 -21
- 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/ChatComposer.doc.mjs +3 -0
- package/src/Chat/ChatComposerDrawer.doc.mjs +12 -0
- 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 +3 -0
- package/src/CheckboxInput/CheckboxInput.doc.mjs +18 -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 +169 -16
- package/src/CheckboxList/CheckboxList.tsx +56 -3
- package/src/CheckboxList/CheckboxListContext.tsx +7 -0
- package/src/Citation/Citation.doc.mjs +10 -0
- package/src/Citation/Citation.test.tsx +117 -0
- package/src/Citation/Citation.tsx +9 -1
- package/src/ClickableCard/ClickableCard.doc.mjs +15 -0
- package/src/CodeBlock/CodeBlock.test.tsx +115 -0
- package/src/CodeBlock/CodeBlock.tsx +61 -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 +281 -56
- package/src/DateInput/DateInput.test.tsx +188 -2
- package/src/DateInput/DateInput.tsx +89 -10
- 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/EmptyState/EmptyState.test.tsx +4 -2
- package/src/EmptyState/EmptyState.tsx +6 -2
- 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 +14 -4
- package/src/Grid/Grid.tsx +20 -0
- package/src/HoverCard/HoverCard.doc.mjs +3 -0
- package/src/HoverCard/HoverCard.test.tsx +189 -2
- package/src/HoverCard/HoverCard.tsx +20 -16
- package/src/HoverCard/useHoverCard.tsx +13 -10
- package/src/Icon/Icon.doc.mjs +8 -0
- package/src/InputGroup/InputGroup.doc.mjs +2 -2
- package/src/InputGroup/InputGroup.test.tsx +98 -60
- package/src/InputGroup/InputGroup.tsx +21 -4
- package/src/InputGroup/InputGroupContext.ts +9 -4
- package/src/InputGroup/index.ts +1 -0
- package/src/Kbd/Kbd.test.tsx +22 -4
- package/src/Kbd/Kbd.tsx +37 -12
- package/src/Layer/anchorName.test.ts +146 -0
- package/src/Layer/anchorName.ts +46 -0
- package/src/Layer/layerAnimations.stylex.ts +20 -4
- package/src/Layer/useLayer.doc.mjs +12 -2
- package/src/Layer/useLayer.tsx +100 -15
- package/src/Layout/Layout.doc.mjs +1 -1
- 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 -2
- 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 +52 -2
- package/src/Link/Link.tsx +42 -7
- package/src/Link/LinkProvider.tsx +1 -0
- package/src/List/List.doc.mjs +7 -0
- package/src/Markdown/Markdown.doc.mjs +2 -0
- package/src/Markdown/Markdown.test.tsx +28 -26
- package/src/Markdown/Markdown.tsx +21 -6
- package/src/MetadataList/MetadataListItem.doc.mjs +4 -0
- package/src/MobileNav/MobileNav.doc.mjs +8 -8
- package/src/MobileNav/MobileNav.tsx +13 -0
- package/src/MobileNav/MobileNavReopen.test.tsx +118 -0
- package/src/MoreMenu/MoreMenu.doc.mjs +2 -17
- package/src/MoreMenu/MoreMenu.tsx +0 -9
- package/src/MultiSelector/MultiSelector.doc.mjs +25 -0
- package/src/MultiSelector/MultiSelector.test.tsx +375 -8
- package/src/MultiSelector/MultiSelector.tsx +145 -21
- 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/OverflowList/OverflowList.doc.mjs +17 -0
- package/src/Pagination/Pagination.doc.mjs +3 -3
- package/src/Pagination/Pagination.test.tsx +250 -14
- package/src/Pagination/Pagination.tsx +54 -29
- package/src/Popover/usePopover.doc.mjs +7 -3
- package/src/Popover/usePopover.tsx +49 -6
- 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 +45 -27
- 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/Resizable/Resizable.doc.mjs +1 -1
- package/src/Section/Section.doc.mjs +11 -0
- 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 +15 -0
- package/src/Selector/Selector.doc.mjs +25 -0
- package/src/Selector/Selector.test.tsx +322 -15
- package/src/Selector/Selector.tsx +126 -40
- package/src/Selector/hooks.ts +23 -0
- package/src/SideNav/SideNav.test.tsx +16 -0
- package/src/SideNav/SideNavItem.tsx +2 -4
- package/src/Skeleton/Skeleton.doc.mjs +11 -1
- package/src/Skeleton/Skeleton.test.tsx +25 -0
- package/src/Skeleton/Skeleton.tsx +11 -1
- package/src/Slider/Slider.doc.mjs +19 -0
- package/src/Slider/Slider.test.tsx +158 -18
- package/src/Slider/Slider.tsx +54 -6
- 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 +12 -0
- package/src/TabList/TabList.test.tsx +208 -0
- package/src/TabList/TabList.tsx +102 -12
- package/src/TabList/TabListContext.ts +7 -3
- package/src/TabList/TabMenu.tsx +6 -3
- package/src/Table/BaseTable.tsx +72 -41
- package/src/Table/Table.doc.mjs +14 -0
- package/src/Table/Table.test.tsx +39 -30
- package/src/Table/Table.tsx +27 -1
- package/src/Table/TableCell.tsx +25 -23
- package/src/Table/TableHeaderCell.tsx +28 -29
- package/src/Table/TableRow.tsx +37 -7
- package/src/Table/index.ts +6 -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/plugins/stickyColumns/index.ts +4 -0
- package/src/Table/plugins/stickyColumns/useTableStickyColumns.test.tsx +163 -0
- package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +407 -0
- package/src/Table/tableContextMenu.test.tsx +157 -0
- package/src/Table/tableContextMenu.tsx +142 -0
- package/src/Table/types.ts +175 -4
- package/src/Table/useBaseTablePlugins.ts +1 -0
- package/src/Table/useTableColumnResize.doc.mjs +96 -0
- package/src/Table/useTableStickyColumns.doc.mjs +59 -0
- package/src/Text/Heading.doc.mjs +15 -2
- package/src/Text/Text.doc.mjs +7 -1
- package/src/Text/text.stylex.ts +2 -2
- 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/TimeInput/TimeInput.doc.mjs +335 -60
- package/src/TimeInput/TimeInput.test.tsx +144 -7
- package/src/TimeInput/TimeInput.tsx +74 -5
- package/src/Timestamp/Timestamp.doc.mjs +9 -0
- package/src/Timestamp/Timestamp.test.tsx +44 -18
- package/src/Timestamp/Timestamp.tsx +30 -10
- package/src/Toast/Toast.tsx +14 -0
- package/src/Toast/ToastViewport.test.tsx +204 -0
- package/src/Toast/ToastViewport.tsx +167 -21
- package/src/ToggleButton/ToggleButton.doc.mjs +9 -3
- package/src/ToggleButton/ToggleButton.test.tsx +39 -18
- package/src/ToggleButton/ToggleButton.tsx +46 -83
- package/src/Tokenizer/Tokenizer.doc.mjs +15 -0
- package/src/Tokenizer/Tokenizer.test.tsx +105 -1
- package/src/Tokenizer/Tokenizer.tsx +41 -2
- package/src/Toolbar/Toolbar.doc.mjs +65 -5
- package/src/Toolbar/Toolbar.test.tsx +109 -6
- package/src/Toolbar/Toolbar.tsx +59 -5
- package/src/Tooltip/Tooltip.test.tsx +81 -0
- package/src/Tooltip/useTooltip.tsx +57 -11
- 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 +86 -9
- package/src/Typeahead/Typeahead.doc.mjs +136 -30
- package/src/Typeahead/Typeahead.test.tsx +331 -1
- package/src/Typeahead/Typeahead.tsx +52 -1
- 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/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/useImageMode.test.ts +133 -0
- 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 +4 -0
- package/src/theme/generateThemeRules.test.ts +7 -8
- package/src/theme/generateThemeRules.ts +1 -1
- package/src/theme/syntax/SyntaxTheme.tsx +1 -1
- package/src/theme/syntax/defineSyntaxTheme.ts +20 -11
- package/src/theme/syntax/presets.ts +5 -2
- package/src/theme/syntax/tokens.ts +1 -1
- package/src/theme/types.ts +1 -1
- 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
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @file CheckboxInput.tsx
|
|
7
|
-
* @input Uses React, useId, ChangeEvent, FieldLabel, FieldStatus, IconType, InputStatus
|
|
7
|
+
* @input Uses React, useId, ChangeEvent, FieldLabel, FieldStatus, IconType, InputStatus, useTooltip
|
|
8
8
|
* @output Exports CheckboxInput component, CheckboxInputProps
|
|
9
9
|
* @position Core implementation; consumed by index.ts, tested by CheckboxInput.test.tsx
|
|
10
10
|
*
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
import {
|
|
20
20
|
useId,
|
|
21
21
|
useCallback,
|
|
22
|
+
use,
|
|
22
23
|
useOptimistic,
|
|
23
24
|
useTransition,
|
|
24
25
|
type ChangeEvent,
|
|
@@ -44,9 +45,11 @@ import {FieldStatus} from '../FieldStatus/FieldStatus';
|
|
|
44
45
|
import type {IconType} from '../Icon';
|
|
45
46
|
import type {InputStatus} from '../Field/types';
|
|
46
47
|
import {Spinner} from '../Spinner';
|
|
48
|
+
import {useTooltip} from '../Tooltip';
|
|
47
49
|
import {mergeProps, mergeRefs} from '../utils';
|
|
48
50
|
import {checkboxScope} from './checkbox.markers.stylex';
|
|
49
51
|
import {themeProps} from '../utils/themeProps';
|
|
52
|
+
import {CheckboxListContext} from '../CheckboxList/CheckboxListContext';
|
|
50
53
|
|
|
51
54
|
const styles = stylex.create({
|
|
52
55
|
container: {
|
|
@@ -269,6 +272,27 @@ export interface CheckboxInputProps extends Omit<BaseProps, 'onChange'> {
|
|
|
269
272
|
* @default false
|
|
270
273
|
*/
|
|
271
274
|
isDisabled?: boolean;
|
|
275
|
+
/**
|
|
276
|
+
* Explains why the checkbox is disabled. When set together with
|
|
277
|
+
* `isDisabled`, the checkbox shows a tooltip with this text on hover and
|
|
278
|
+
* keyboard focus, and the control stays focusable (via `aria-disabled`) so
|
|
279
|
+
* the reason is discoverable by keyboard and assistive technology.
|
|
280
|
+
* Activation stays blocked.
|
|
281
|
+
*
|
|
282
|
+
* Use this instead of wrapping a disabled checkbox in `Tooltip` — disabled
|
|
283
|
+
* controls don't emit the pointer events an external tooltip needs.
|
|
284
|
+
*
|
|
285
|
+
* @example
|
|
286
|
+
* ```
|
|
287
|
+
* <CheckboxInput
|
|
288
|
+
* label="Accept terms"
|
|
289
|
+
* value={accepted}
|
|
290
|
+
* isDisabled
|
|
291
|
+
* disabledMessage="Terms are managed by your administrator"
|
|
292
|
+
* />
|
|
293
|
+
* ```
|
|
294
|
+
*/
|
|
295
|
+
disabledMessage?: string;
|
|
272
296
|
/**
|
|
273
297
|
* Whether the checkbox is read-only.
|
|
274
298
|
* Displays the current state at full opacity but prevents interaction.
|
|
@@ -350,6 +374,7 @@ export function CheckboxInput({
|
|
|
350
374
|
isLoading = false,
|
|
351
375
|
value,
|
|
352
376
|
isDisabled = false,
|
|
377
|
+
disabledMessage,
|
|
353
378
|
isReadOnly = false,
|
|
354
379
|
isOptional = false,
|
|
355
380
|
isRequired = false,
|
|
@@ -372,11 +397,37 @@ export function CheckboxInput({
|
|
|
372
397
|
const [optimisticValue, setOptimisticValue] = useOptimistic(value);
|
|
373
398
|
const isBusy = isLoading || optimisticValue !== value;
|
|
374
399
|
|
|
400
|
+
// Disabled-reason tooltip. Disabled controls swallow pointer events, so the
|
|
401
|
+
// tooltip listeners attach to the checkbox row (which already exists) and the
|
|
402
|
+
// native checkbox stays perceivable via aria-disabled instead of the disabled
|
|
403
|
+
// attribute. Value mutation is blocked by the isDisabled guard in onChange.
|
|
404
|
+
const showsDisabledMessage = isDisabled && !!disabledMessage;
|
|
405
|
+
// Keep the native checkbox focusable via aria-disabled either when it renders
|
|
406
|
+
// its own reason tooltip, or when it sits in a CheckboxList whose whole-group
|
|
407
|
+
// `disabledMessage` (shown on the group container) needs each checkbox to
|
|
408
|
+
// stay keyboard-perceivable. The group signals this through context rather
|
|
409
|
+
// than a public prop.
|
|
410
|
+
const checkboxListContext = use(CheckboxListContext);
|
|
411
|
+
const isFocusableDisabled =
|
|
412
|
+
isDisabled &&
|
|
413
|
+
(showsDisabledMessage ||
|
|
414
|
+
(checkboxListContext?.hasDisabledMessage ?? false));
|
|
415
|
+
const disabledMessageTooltip = useTooltip({
|
|
416
|
+
placement: 'above',
|
|
417
|
+
// The container row is not naturally focusable; focusin bubbles up from the
|
|
418
|
+
// native checkbox, so always attach focus listeners.
|
|
419
|
+
focusTrigger: 'always',
|
|
420
|
+
isEnabled: showsDisabledMessage,
|
|
421
|
+
});
|
|
422
|
+
|
|
375
423
|
const isIndeterminate = optimisticValue === 'indeterminate';
|
|
376
424
|
const isChecked = optimisticValue === true;
|
|
377
425
|
const isCheckedOrIndeterminate = isChecked || isIndeterminate;
|
|
378
426
|
|
|
379
|
-
// Sync the native indeterminate DOM property (can't be set via JSX
|
|
427
|
+
// Sync the native indeterminate DOM property (can't be set via JSX
|
|
428
|
+
// attribute). On a native checkbox this is the authoritative way to expose
|
|
429
|
+
// the mixed state — a separate aria-checked="mixed" would be redundant and
|
|
430
|
+
// can desync from / override the native state (forms-16), so it is omitted.
|
|
380
431
|
const indeterminateRef = useCallback(
|
|
381
432
|
(el: HTMLInputElement | null) => {
|
|
382
433
|
if (el) {
|
|
@@ -395,6 +446,9 @@ export function CheckboxInput({
|
|
|
395
446
|
if (status?.message) {
|
|
396
447
|
describedByParts.push(statusMessageID);
|
|
397
448
|
}
|
|
449
|
+
if (showsDisabledMessage) {
|
|
450
|
+
describedByParts.push(disabledMessageTooltip.describedBy);
|
|
451
|
+
}
|
|
398
452
|
const ariaDescribedBy =
|
|
399
453
|
describedByParts.length > 0 ? describedByParts.join(' ') : undefined;
|
|
400
454
|
|
|
@@ -407,6 +461,15 @@ export function CheckboxInput({
|
|
|
407
461
|
style,
|
|
408
462
|
)}>
|
|
409
463
|
<div
|
|
464
|
+
ref={el => {
|
|
465
|
+
// Interaction (hover/focus) listeners for the disabled-message
|
|
466
|
+
// tooltip attach to the whole row for a larger trigger target;
|
|
467
|
+
// positioning anchors on the checkbox itself (below) so the tooltip
|
|
468
|
+
// appears next to the control, not the far edge of the row.
|
|
469
|
+
// Handlers are gated internally by isEnabled, so attaching
|
|
470
|
+
// unconditionally is safe.
|
|
471
|
+
disabledMessageTooltip.interactionRef(el);
|
|
472
|
+
}}
|
|
410
473
|
{...stylex.props(
|
|
411
474
|
styles.container,
|
|
412
475
|
isLabelHidden && styles.containerLabelHidden,
|
|
@@ -414,15 +477,23 @@ export function CheckboxInput({
|
|
|
414
477
|
)}>
|
|
415
478
|
<div {...stylex.props(styles.checkboxWrapper, wrapperSizeStyles[size])}>
|
|
416
479
|
<input
|
|
417
|
-
ref={mergeRefs(
|
|
480
|
+
ref={mergeRefs(
|
|
481
|
+
ref,
|
|
482
|
+
indeterminateRef,
|
|
483
|
+
disabledMessageTooltip.positionRef,
|
|
484
|
+
)}
|
|
418
485
|
id={id}
|
|
419
486
|
type="checkbox"
|
|
420
487
|
checked={isChecked}
|
|
421
|
-
|
|
488
|
+
// With a disabledMessage the checkbox keeps focusability via
|
|
489
|
+
// aria-disabled so the reason is focus-discoverable; toggling is
|
|
490
|
+
// still blocked by the isDisabled guard in onChange below.
|
|
491
|
+
disabled={isDisabled && !isFocusableDisabled}
|
|
492
|
+
aria-disabled={isFocusableDisabled ? 'true' : undefined}
|
|
422
493
|
readOnly={isReadOnly}
|
|
423
494
|
required={isRequired}
|
|
424
495
|
onChange={e => {
|
|
425
|
-
if (isBusy || isReadOnly) {
|
|
496
|
+
if (isDisabled || isBusy || isReadOnly) {
|
|
426
497
|
return;
|
|
427
498
|
}
|
|
428
499
|
const checked = e.target.checked;
|
|
@@ -436,7 +507,6 @@ export function CheckboxInput({
|
|
|
436
507
|
}}
|
|
437
508
|
onFocus={onFocus}
|
|
438
509
|
onBlur={onBlur}
|
|
439
|
-
aria-checked={isIndeterminate ? 'mixed' : undefined}
|
|
440
510
|
aria-readonly={isReadOnly || undefined}
|
|
441
511
|
aria-describedby={ariaDescribedBy}
|
|
442
512
|
aria-invalid={status?.type === 'error' ? true : undefined}
|
|
@@ -525,6 +595,8 @@ export function CheckboxInput({
|
|
|
525
595
|
variant="detached"
|
|
526
596
|
/>
|
|
527
597
|
)}
|
|
598
|
+
{showsDisabledMessage &&
|
|
599
|
+
disabledMessageTooltip.renderTooltip(disabledMessage)}
|
|
528
600
|
</div>
|
|
529
601
|
);
|
|
530
602
|
}
|
|
@@ -77,6 +77,12 @@ export const docs = {
|
|
|
77
77
|
description: 'Whether all checkbox items are disabled.',
|
|
78
78
|
default: 'false',
|
|
79
79
|
},
|
|
80
|
+
{
|
|
81
|
+
name: 'disabledMessage',
|
|
82
|
+
type: 'string',
|
|
83
|
+
description:
|
|
84
|
+
'Explains why the group is disabled. Applies to the whole-group disabled state (isDisabled), not per item. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the checkboxes focusable via aria-disabled (toggling stays blocked). Use this instead of wrapping a disabled CheckboxList in Tooltip — disabled controls swallow the hover events an external Tooltip needs.',
|
|
85
|
+
},
|
|
80
86
|
{
|
|
81
87
|
name: 'status',
|
|
82
88
|
type: 'InputStatus',
|
|
@@ -99,6 +105,7 @@ export const docs = {
|
|
|
99
105
|
{ guidance: true, description: 'Write a group label that says what the choices represent: "Export formats" tells users more than "Options".' },
|
|
100
106
|
{ guidance: false, description: 'Show a CheckboxList when the user can only pick one thing; that is what RadioList is for.' },
|
|
101
107
|
{ guidance: false, description: 'Put buttons or links inside the trailing slot (endContent); the whole row is already tappable, so a nested button creates two competing click targets.' },
|
|
108
|
+
{ guidance: false, description: 'Wrap a disabled CheckboxList in Tooltip to explain why it is disabled; disabled controls swallow the hover events the wrapper needs. Use the disabledMessage prop instead.' },
|
|
102
109
|
],
|
|
103
110
|
},
|
|
104
111
|
};
|
|
@@ -113,6 +120,7 @@ export const docsZh = {
|
|
|
113
120
|
{ guidance: true, description: 'Write a group label that says what the choices represent: "Export formats" tells users more than "Options".' },
|
|
114
121
|
{ guidance: false, description: 'Show a CheckboxList when the user can only pick one thing; that is what RadioList is for.' },
|
|
115
122
|
{ guidance: false, description: 'Put buttons or links inside the trailing slot (endContent); the whole row is already tappable, so a nested button creates two competing click targets.' },
|
|
123
|
+
{ guidance: false, description: 'Wrap a disabled CheckboxList in Tooltip to explain why it is disabled; disabled controls swallow the hover events the wrapper needs. Use the disabledMessage prop instead.' },
|
|
116
124
|
],
|
|
117
125
|
},
|
|
118
126
|
};
|
|
@@ -129,6 +137,7 @@ export const docsDense = {
|
|
|
129
137
|
{ guidance: true, description: 'Write a group label that says what the choices represent: "Export formats" tells users more than "Options".' },
|
|
130
138
|
{ guidance: false, description: 'Show a CheckboxList when the user can only pick one thing; that is what RadioList is for.' },
|
|
131
139
|
{ guidance: false, description: 'Put buttons or links inside the trailing slot (endContent); the whole row is already tappable, so a nested button creates two competing click targets.' },
|
|
140
|
+
{ guidance: false, description: 'Wrap a disabled CheckboxList in Tooltip to explain why it is disabled; disabled controls swallow the hover events the wrapper needs. Use the disabledMessage prop instead.' },
|
|
132
141
|
],
|
|
133
142
|
},
|
|
134
143
|
};
|
|
@@ -9,13 +9,46 @@
|
|
|
9
9
|
* SYNC: When CheckboxList.tsx or CheckboxListItem.tsx changes, update tests to match new behavior
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import {describe, it, expect, vi} from 'vitest';
|
|
13
|
-
import {
|
|
12
|
+
import {describe, it, expect, vi, beforeEach} from 'vitest';
|
|
13
|
+
import {
|
|
14
|
+
render,
|
|
15
|
+
screen,
|
|
16
|
+
fireEvent,
|
|
17
|
+
within,
|
|
18
|
+
waitFor,
|
|
19
|
+
} from '@testing-library/react';
|
|
14
20
|
import userEvent from '@testing-library/user-event';
|
|
15
21
|
import {CheckboxList} from './CheckboxList';
|
|
16
22
|
import {CheckboxListItem} from './CheckboxListItem';
|
|
17
23
|
import {List} from '../List/List';
|
|
18
24
|
|
|
25
|
+
// Mock showPopover/hidePopover (not implemented in jsdom) so the tooltip layer
|
|
26
|
+
// reflects its open state via a `popover-open` attribute the tests can assert.
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
HTMLElement.prototype.showPopover = vi.fn(function (this: HTMLElement) {
|
|
29
|
+
this.setAttribute('popover-open', '');
|
|
30
|
+
const event = new Event('toggle', {bubbles: false});
|
|
31
|
+
Object.defineProperty(event, 'newState', {value: 'open'});
|
|
32
|
+
this.dispatchEvent(event);
|
|
33
|
+
});
|
|
34
|
+
HTMLElement.prototype.hidePopover = vi.fn(function (this: HTMLElement) {
|
|
35
|
+
this.removeAttribute('popover-open');
|
|
36
|
+
const event = new Event('toggle', {bubbles: false});
|
|
37
|
+
Object.defineProperty(event, 'newState', {value: 'closed'});
|
|
38
|
+
this.dispatchEvent(event);
|
|
39
|
+
});
|
|
40
|
+
const originalMatches = HTMLElement.prototype.matches;
|
|
41
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
42
|
+
(HTMLElement.prototype as any).matches = function (
|
|
43
|
+
selector: string,
|
|
44
|
+
): boolean {
|
|
45
|
+
if (selector === ':popover-open') {
|
|
46
|
+
return this.hasAttribute('popover-open');
|
|
47
|
+
}
|
|
48
|
+
return originalMatches.call(this, selector);
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
|
|
19
52
|
describe('CheckboxList', () => {
|
|
20
53
|
it('renders with label', () => {
|
|
21
54
|
render(
|
|
@@ -26,6 +59,25 @@ describe('CheckboxList', () => {
|
|
|
26
59
|
expect(screen.getByText('Preferences')).toBeInTheDocument();
|
|
27
60
|
});
|
|
28
61
|
|
|
62
|
+
it('wraps items in a group named by the label (forms audit: group role)', () => {
|
|
63
|
+
render(
|
|
64
|
+
<CheckboxList label="Preferences" value={[]} onChange={() => {}}>
|
|
65
|
+
<CheckboxListItem label="Option A" value="a" />
|
|
66
|
+
</CheckboxList>,
|
|
67
|
+
);
|
|
68
|
+
// The checkboxes are wrapped in a role="group" whose accessible name comes
|
|
69
|
+
// from the field label (via aria-labelledby). The label is rendered as a
|
|
70
|
+
// <span> (not a literal <label>, which can't name a group) with no
|
|
71
|
+
// orphaned htmlFor.
|
|
72
|
+
const group = screen.getByRole('group', {name: 'Preferences'});
|
|
73
|
+
expect(group).toBeInTheDocument();
|
|
74
|
+
const label = screen.getByText('Preferences');
|
|
75
|
+
expect(label.tagName).toBe('SPAN');
|
|
76
|
+
expect(label.closest('label')).toBeNull();
|
|
77
|
+
expect(label).not.toHaveAttribute('for');
|
|
78
|
+
expect(group.getAttribute('aria-labelledby')).toBe(label.id);
|
|
79
|
+
});
|
|
80
|
+
|
|
29
81
|
it('renders checkbox items', () => {
|
|
30
82
|
render(
|
|
31
83
|
<CheckboxList label="Preferences" value={[]} onChange={() => {}}>
|
|
@@ -39,10 +91,7 @@ describe('CheckboxList', () => {
|
|
|
39
91
|
|
|
40
92
|
it('checks the correct items based on value prop', () => {
|
|
41
93
|
render(
|
|
42
|
-
<CheckboxList
|
|
43
|
-
label="Preferences"
|
|
44
|
-
value={['a', 'c']}
|
|
45
|
-
onChange={() => {}}>
|
|
94
|
+
<CheckboxList label="Preferences" value={['a', 'c']} onChange={() => {}}>
|
|
46
95
|
<CheckboxListItem label="Option A" value="a" />
|
|
47
96
|
<CheckboxListItem label="Option B" value="b" />
|
|
48
97
|
<CheckboxListItem label="Option C" value="c" />
|
|
@@ -58,10 +107,7 @@ describe('CheckboxList', () => {
|
|
|
58
107
|
const user = userEvent.setup();
|
|
59
108
|
const handleChange = vi.fn();
|
|
60
109
|
render(
|
|
61
|
-
<CheckboxList
|
|
62
|
-
label="Preferences"
|
|
63
|
-
value={['a']}
|
|
64
|
-
onChange={handleChange}>
|
|
110
|
+
<CheckboxList label="Preferences" value={['a']} onChange={handleChange}>
|
|
65
111
|
<CheckboxListItem label="Option A" value="a" />
|
|
66
112
|
<CheckboxListItem label="Option B" value="b" />
|
|
67
113
|
</CheckboxList>,
|
|
@@ -272,11 +318,7 @@ describe('CheckboxList', () => {
|
|
|
272
318
|
isChecked={false}
|
|
273
319
|
onCheck={handleSelectAll}
|
|
274
320
|
/>
|
|
275
|
-
<CheckboxListItem
|
|
276
|
-
label="Name"
|
|
277
|
-
isChecked={true}
|
|
278
|
-
onCheck={handleCheck}
|
|
279
|
-
/>
|
|
321
|
+
<CheckboxListItem label="Name" isChecked={true} onCheck={handleCheck} />
|
|
280
322
|
<CheckboxListItem
|
|
281
323
|
label="Email"
|
|
282
324
|
isChecked={false}
|
|
@@ -347,8 +389,15 @@ describe('CheckboxListItem standalone mode', () => {
|
|
|
347
389
|
<CheckboxListItem label="Partial" isChecked="indeterminate" />
|
|
348
390
|
</List>,
|
|
349
391
|
);
|
|
392
|
+
// The inner native checkbox exposes mixed state via the indeterminate DOM
|
|
393
|
+
// property (not a redundant aria-checked, forms-16); the list row still
|
|
394
|
+
// carries aria-checked="mixed" for its own listitem semantics.
|
|
350
395
|
const checkbox = screen.getByRole('checkbox');
|
|
351
|
-
expect(checkbox).
|
|
396
|
+
expect(checkbox).toBeInstanceOf(HTMLInputElement);
|
|
397
|
+
if (checkbox instanceof HTMLInputElement) {
|
|
398
|
+
expect(checkbox.indeterminate).toBe(true);
|
|
399
|
+
}
|
|
400
|
+
expect(checkbox).not.toHaveAttribute('aria-checked');
|
|
352
401
|
});
|
|
353
402
|
|
|
354
403
|
it('calls onCheck with true when clicking indeterminate item', async () => {
|
|
@@ -500,4 +549,108 @@ describe('CheckboxListItem ARIA props', () => {
|
|
|
500
549
|
expect(item).toHaveAttribute('aria-describedby', 'help-text');
|
|
501
550
|
expect(item).toHaveAttribute('aria-label', 'custom label');
|
|
502
551
|
});
|
|
552
|
+
|
|
553
|
+
describe('disabledMessage', () => {
|
|
554
|
+
const h = {hidden: true} as const;
|
|
555
|
+
|
|
556
|
+
function renderGroup(props?: {onChange?: (v: string[]) => void}) {
|
|
557
|
+
return render(
|
|
558
|
+
<CheckboxList
|
|
559
|
+
label="Notifications"
|
|
560
|
+
value={['email']}
|
|
561
|
+
onChange={props?.onChange ?? (() => {})}
|
|
562
|
+
isDisabled
|
|
563
|
+
disabledMessage="Notifications are managed by your administrator">
|
|
564
|
+
<CheckboxListItem label="Email" value="email" />
|
|
565
|
+
<CheckboxListItem label="SMS" value="sms" />
|
|
566
|
+
</CheckboxList>,
|
|
567
|
+
);
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
it('shows the reason tooltip on hover when the group is disabled with a reason', async () => {
|
|
571
|
+
renderGroup();
|
|
572
|
+
const tooltip = screen.getByRole('tooltip', h);
|
|
573
|
+
expect(tooltip).toHaveTextContent(
|
|
574
|
+
'Notifications are managed by your administrator',
|
|
575
|
+
);
|
|
576
|
+
const group = screen.getByRole('group');
|
|
577
|
+
fireEvent.mouseEnter(group);
|
|
578
|
+
await waitFor(() => expect(tooltip).toHaveAttribute('popover-open'));
|
|
579
|
+
fireEvent.mouseLeave(group);
|
|
580
|
+
await waitFor(() => expect(tooltip).not.toHaveAttribute('popover-open'));
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
it('shows the reason tooltip on keyboard focus', async () => {
|
|
584
|
+
const user = userEvent.setup();
|
|
585
|
+
renderGroup();
|
|
586
|
+
const tooltip = screen.getByRole('tooltip', h);
|
|
587
|
+
await user.tab();
|
|
588
|
+
await waitFor(() => expect(tooltip).toHaveAttribute('popover-open'));
|
|
589
|
+
});
|
|
590
|
+
|
|
591
|
+
it('does not render a tooltip when not disabled', () => {
|
|
592
|
+
render(
|
|
593
|
+
<CheckboxList
|
|
594
|
+
label="Notifications"
|
|
595
|
+
value={['email']}
|
|
596
|
+
onChange={() => {}}
|
|
597
|
+
disabledMessage="Notifications are managed by your administrator">
|
|
598
|
+
<CheckboxListItem label="Email" value="email" />
|
|
599
|
+
</CheckboxList>,
|
|
600
|
+
);
|
|
601
|
+
expect(screen.queryByRole('tooltip', h)).not.toBeInTheDocument();
|
|
602
|
+
});
|
|
603
|
+
|
|
604
|
+
it('does not render a tooltip when disabled without a reason', () => {
|
|
605
|
+
render(
|
|
606
|
+
<CheckboxList
|
|
607
|
+
label="Notifications"
|
|
608
|
+
value={['email']}
|
|
609
|
+
onChange={() => {}}
|
|
610
|
+
isDisabled>
|
|
611
|
+
<CheckboxListItem label="Email" value="email" />
|
|
612
|
+
</CheckboxList>,
|
|
613
|
+
);
|
|
614
|
+
expect(screen.queryByRole('tooltip', h)).not.toBeInTheDocument();
|
|
615
|
+
});
|
|
616
|
+
|
|
617
|
+
it('keeps checkboxes focusable via aria-disabled when a reason is provided', () => {
|
|
618
|
+
renderGroup();
|
|
619
|
+
for (const checkbox of screen.getAllByRole('checkbox', h)) {
|
|
620
|
+
expect(checkbox).not.toBeDisabled();
|
|
621
|
+
expect(checkbox).toHaveAttribute('aria-disabled', 'true');
|
|
622
|
+
}
|
|
623
|
+
});
|
|
624
|
+
|
|
625
|
+
it('links the reason tooltip from the group via aria-describedby', () => {
|
|
626
|
+
renderGroup();
|
|
627
|
+
const group = screen.getByRole('group');
|
|
628
|
+
const tooltip = screen.getByRole('tooltip', h);
|
|
629
|
+
expect(group.getAttribute('aria-describedby')).toContain(tooltip.id);
|
|
630
|
+
});
|
|
631
|
+
|
|
632
|
+
it('blocks toggling while focusable-disabled', () => {
|
|
633
|
+
const onChange = vi.fn();
|
|
634
|
+
renderGroup({onChange});
|
|
635
|
+
const sms = screen.getByRole('checkbox', {name: 'SMS', hidden: true});
|
|
636
|
+
fireEvent.click(sms);
|
|
637
|
+
expect(onChange).not.toHaveBeenCalled();
|
|
638
|
+
});
|
|
639
|
+
|
|
640
|
+
it('keeps checkboxes natively disabled when disabled without a reason', () => {
|
|
641
|
+
render(
|
|
642
|
+
<CheckboxList
|
|
643
|
+
label="Notifications"
|
|
644
|
+
value={['email']}
|
|
645
|
+
onChange={() => {}}
|
|
646
|
+
isDisabled>
|
|
647
|
+
<CheckboxListItem label="Email" value="email" />
|
|
648
|
+
<CheckboxListItem label="SMS" value="sms" />
|
|
649
|
+
</CheckboxList>,
|
|
650
|
+
);
|
|
651
|
+
for (const checkbox of screen.getAllByRole('checkbox', h)) {
|
|
652
|
+
expect(checkbox).toBeDisabled();
|
|
653
|
+
}
|
|
654
|
+
});
|
|
655
|
+
});
|
|
503
656
|
});
|
|
@@ -30,6 +30,7 @@ import {Field} from '../Field/Field';
|
|
|
30
30
|
import type {InputStatus} from '../Field/types';
|
|
31
31
|
import {List} from '../List/List';
|
|
32
32
|
import type {ListDensity} from '../List/ListContext';
|
|
33
|
+
import {useTooltip} from '../Tooltip';
|
|
33
34
|
import {mergeProps} from '../utils';
|
|
34
35
|
import {themeProps} from '../utils/themeProps';
|
|
35
36
|
import {
|
|
@@ -93,6 +94,18 @@ export interface CheckboxListProps extends Omit<
|
|
|
93
94
|
* @default false
|
|
94
95
|
*/
|
|
95
96
|
isDisabled?: boolean;
|
|
97
|
+
/**
|
|
98
|
+
* Explains why the checkbox group is disabled. Applies to the whole-group
|
|
99
|
+
* disabled state (`isDisabled`), not individual items. When set together with
|
|
100
|
+
* `isDisabled`, the group shows a tooltip with this text on hover and keyboard
|
|
101
|
+
* focus, and its checkboxes stay focusable (via `aria-disabled`) so the reason
|
|
102
|
+
* is discoverable by keyboard and assistive technology. Toggling stays
|
|
103
|
+
* blocked.
|
|
104
|
+
*
|
|
105
|
+
* Use this instead of wrapping a disabled group in `Tooltip` — disabled
|
|
106
|
+
* controls don't emit the pointer events an external tooltip needs.
|
|
107
|
+
*/
|
|
108
|
+
disabledMessage?: string;
|
|
96
109
|
/**
|
|
97
110
|
* Whether all checkbox items are read-only.
|
|
98
111
|
* Displays the current state at full opacity but prevents interaction.
|
|
@@ -141,6 +154,7 @@ export function CheckboxList({
|
|
|
141
154
|
density = 'balanced',
|
|
142
155
|
hasDividers = false,
|
|
143
156
|
isDisabled = false,
|
|
157
|
+
disabledMessage,
|
|
144
158
|
isReadOnly = false,
|
|
145
159
|
children,
|
|
146
160
|
ref,
|
|
@@ -151,6 +165,7 @@ export function CheckboxList({
|
|
|
151
165
|
'data-testid': dataTestId,
|
|
152
166
|
}: CheckboxListProps) {
|
|
153
167
|
const inputID = useId();
|
|
168
|
+
const labelID = useId();
|
|
154
169
|
const descriptionID = useId();
|
|
155
170
|
const statusMessageID = useId();
|
|
156
171
|
|
|
@@ -162,6 +177,19 @@ export function CheckboxList({
|
|
|
162
177
|
// the transition settles, so the spinner clears without manual cleanup.
|
|
163
178
|
const [loadingValue, setLoadingValue] = useOptimistic<string | null>(null);
|
|
164
179
|
|
|
180
|
+
// Disabled-reason tooltip. Applies to the whole-group disabled state. Disabled
|
|
181
|
+
// controls swallow pointer events, so the tooltip listeners attach to the
|
|
182
|
+
// group container and the checkboxes stay perceivable via aria-disabled
|
|
183
|
+
// instead of the disabled attribute. Toggling is blocked in the item.
|
|
184
|
+
const showsDisabledMessage = isDisabled && !!disabledMessage;
|
|
185
|
+
const disabledMessageTooltip = useTooltip({
|
|
186
|
+
placement: 'above',
|
|
187
|
+
// The group container is not naturally focusable; focusin bubbles up from
|
|
188
|
+
// the checkboxes, so always attach focus listeners.
|
|
189
|
+
focusTrigger: 'always',
|
|
190
|
+
isEnabled: showsDisabledMessage,
|
|
191
|
+
});
|
|
192
|
+
|
|
165
193
|
const handleChange = useCallback(
|
|
166
194
|
(newValues: string[], toggledValue?: string) => {
|
|
167
195
|
onChange?.(newValues);
|
|
@@ -189,6 +217,7 @@ export function CheckboxList({
|
|
|
189
217
|
value: isCollectionMode ? optimisticValue : undefined,
|
|
190
218
|
onChange: isCollectionMode ? handleChange : undefined,
|
|
191
219
|
isDisabled,
|
|
220
|
+
hasDisabledMessage: showsDisabledMessage,
|
|
192
221
|
isReadOnly,
|
|
193
222
|
loadingValue,
|
|
194
223
|
}),
|
|
@@ -197,6 +226,7 @@ export function CheckboxList({
|
|
|
197
226
|
optimisticValue,
|
|
198
227
|
handleChange,
|
|
199
228
|
isDisabled,
|
|
229
|
+
showsDisabledMessage,
|
|
200
230
|
isReadOnly,
|
|
201
231
|
loadingValue,
|
|
202
232
|
],
|
|
@@ -210,6 +240,8 @@ export function CheckboxList({
|
|
|
210
240
|
isLabelHidden={isLabelHidden}
|
|
211
241
|
description={description}
|
|
212
242
|
inputID={inputID}
|
|
243
|
+
labelID={labelID}
|
|
244
|
+
isGroupLabel
|
|
213
245
|
descriptionID={description ? descriptionID : undefined}
|
|
214
246
|
isDisabled={isDisabled}
|
|
215
247
|
status={
|
|
@@ -226,10 +258,31 @@ export function CheckboxList({
|
|
|
226
258
|
xstyle={xstyle}
|
|
227
259
|
{...mergeProps(themeProps('checkbox-list'), {className, style})}>
|
|
228
260
|
<CheckboxListContext value={contextValue}>
|
|
229
|
-
<
|
|
230
|
-
{
|
|
231
|
-
|
|
261
|
+
<div
|
|
262
|
+
ref={el => {
|
|
263
|
+
// Anchor + hover/focus listeners for the disabled-message tooltip.
|
|
264
|
+
// Handlers are gated internally by isEnabled, so attaching
|
|
265
|
+
// unconditionally is safe.
|
|
266
|
+
disabledMessageTooltip.ref(el);
|
|
267
|
+
}}
|
|
268
|
+
role="group"
|
|
269
|
+
aria-labelledby={labelID}
|
|
270
|
+
aria-describedby={
|
|
271
|
+
[
|
|
272
|
+
description ? descriptionID : null,
|
|
273
|
+
status?.message ? statusMessageID : null,
|
|
274
|
+
showsDisabledMessage ? disabledMessageTooltip.describedBy : null,
|
|
275
|
+
]
|
|
276
|
+
.filter(Boolean)
|
|
277
|
+
.join(' ') || undefined
|
|
278
|
+
}>
|
|
279
|
+
<List density={density} hasDividers={hasDividers}>
|
|
280
|
+
{children}
|
|
281
|
+
</List>
|
|
282
|
+
</div>
|
|
232
283
|
</CheckboxListContext>
|
|
284
|
+
{showsDisabledMessage &&
|
|
285
|
+
disabledMessageTooltip.renderTooltip(disabledMessage)}
|
|
233
286
|
</Field>
|
|
234
287
|
);
|
|
235
288
|
}
|
|
@@ -21,6 +21,13 @@ export interface CheckboxListContextValue {
|
|
|
21
21
|
*/
|
|
22
22
|
onChange?: (values: string[], toggledValue?: string) => void;
|
|
23
23
|
isDisabled: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* True when the whole group is disabled *and* a `disabledMessage` is set. In
|
|
26
|
+
* that mode items stay focusable via `aria-disabled` (instead of the native
|
|
27
|
+
* `disabled` attribute) so the group's disabled-reason tooltip is keyboard-
|
|
28
|
+
* and AT-discoverable; toggling is still blocked.
|
|
29
|
+
*/
|
|
30
|
+
hasDisabledMessage?: boolean;
|
|
24
31
|
isReadOnly: boolean;
|
|
25
32
|
/**
|
|
26
33
|
* The value of the item with a pending `changeAction`, or null when idle.
|
|
@@ -56,6 +56,16 @@ export const docs = {
|
|
|
56
56
|
],
|
|
57
57
|
},
|
|
58
58
|
|
|
59
|
+
// `source` is a custom object type the docsite preview cannot generate
|
|
60
|
+
// automatically; without these defaults the properties tab shows the
|
|
61
|
+
// missing-required-props placeholder instead of an interactive preview.
|
|
62
|
+
playground: {
|
|
63
|
+
defaults: {
|
|
64
|
+
source: {title: 'Astryx Design', url: 'https://example.com'},
|
|
65
|
+
number: 1,
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
|
|
59
69
|
props: [
|
|
60
70
|
{
|
|
61
71
|
name: 'source',
|