@astryxdesign/core 0.1.2 → 0.1.3-canary.102854d
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 +31 -12
- 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 +124 -61
- package/dist/Calendar/dayCellUtils.d.ts +67 -5
- package/dist/Calendar/dayCellUtils.d.ts.map +1 -1
- package/dist/Calendar/dayCellUtils.js +139 -18
- 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 +12 -5
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +96 -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 +13 -9
- 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 +79 -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 +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/rowExpansion/index.d.ts +3 -0
- package/dist/Table/plugins/rowExpansion/index.d.ts.map +1 -0
- package/dist/Table/plugins/rowExpansion/index.js +3 -0
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts +90 -0
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -0
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +398 -0
- 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 +37 -0
- package/dist/Table/tableContextMenu.d.ts.map +1 -0
- package/dist/Table/tableContextMenu.js +140 -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 +22 -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.doc.mjs +2 -2
- 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 +42 -22
- 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 +247 -30
- package/src/Calendar/Calendar.tsx +173 -86
- package/src/Calendar/dayCellUtils.test.ts +306 -1
- package/src/Calendar/dayCellUtils.ts +206 -13
- 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 +129 -16
- package/src/DateInput/DateInput.doc.mjs +291 -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/__tests__/edgeCompensation.test.tsx +72 -0
- 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 +35 -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 +31 -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 +9 -3
- 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 +24 -18
- 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 +105 -24
- package/src/Table/TableHeaderCell.tsx +28 -29
- package/src/Table/index.ts +8 -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/rowExpansion/index.ts +7 -0
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +155 -0
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +590 -0
- 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 +181 -0
- package/src/Table/tableContextMenu.tsx +160 -0
- package/src/Table/types.ts +74 -0
- package/src/Table/useTableColumnResize.doc.mjs +3 -3
- package/src/Table/useTablePagination.doc.mjs +4 -1
- package/src/Table/useTableRowExpansion.doc.mjs +63 -0
- package/src/Table/useTableSortable.doc.mjs +4 -1
- 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 +345 -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 +146 -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
package/src/Text/Text.doc.mjs
CHANGED
|
@@ -124,15 +124,15 @@ export const docs = {
|
|
|
124
124
|
description:
|
|
125
125
|
'Text renders styled body text and headings from the theme. Use Text with a semantic type for body copy, labels, and captions, and Heading for section titles that output the correct h1\u2013h6 element.',
|
|
126
126
|
bestPractices: [
|
|
127
|
-
{ guidance: true, description: 'Pick a semantic type (body, label, supporting, large, code) instead of manually setting size and weight
|
|
127
|
+
{ guidance: true, description: 'Pick a semantic type (body, label, supporting, large, code) instead of manually setting size and weight; the theme handles the details.' },
|
|
128
128
|
{ guidance: true, description: 'Set accessibilityLevel on Heading when the visual level differs from the document outline so screen readers announce the correct hierarchy.' },
|
|
129
|
-
{ guidance: true, description: 'Use maxLines with a number to truncate long content
|
|
129
|
+
{ guidance: true, description: 'Use maxLines with a number to truncate long content; a tooltip appears automatically on hover so no text is lost.' },
|
|
130
130
|
{ guidance: true, description: 'Enable hasTabularNumbers for columns of numeric data so digits align vertically across rows.' },
|
|
131
|
-
{ guidance: false, description: 'Override size and weight when a semantic type already matches
|
|
132
|
-
{ guidance: false, description: 'Skip heading levels in the document outline
|
|
133
|
-
{ guidance: false, description: 'Use raw HTML tags like <p>, <h1>\u2013<h6>, or <span> for text
|
|
134
|
-
{ guidance: false, description: 'Pass a `variant` prop
|
|
135
|
-
{ guidance: false, description: 'Use Text for headings
|
|
131
|
+
{ guidance: false, description: 'Override size and weight when a semantic type already matches; extra overrides fight the theme and break when themes change.' },
|
|
132
|
+
{ guidance: false, description: 'Skip heading levels in the document outline; go h1 then h2 then h3, never h1 then h3.' },
|
|
133
|
+
{ guidance: false, description: 'Use raw HTML tags like <p>, <h1>\u2013<h6>, or <span> for text; Text and Heading apply the correct theme tokens automatically.' },
|
|
134
|
+
{ guidance: false, description: 'Pass a `variant` prop; Text does not have a `variant` prop. Use `type` for semantic styling (body, label, large, supporting, code) or use Heading for headings.' },
|
|
135
|
+
{ guidance: false, description: 'Use Text for headings; use Heading with a `level` prop (1\u20136) for section titles and headings.' },
|
|
136
136
|
],
|
|
137
137
|
},
|
|
138
138
|
};
|
|
@@ -143,15 +143,15 @@ export const docsZh = {
|
|
|
143
143
|
description:
|
|
144
144
|
'Text renders styled body text and headings from the theme. Use Text with a semantic type for body copy, labels, and captions, and Heading for section titles that output the correct h1\u2013h6 element.',
|
|
145
145
|
bestPractices: [
|
|
146
|
-
{ guidance: true, description: 'Pick a semantic type (body, label, supporting, large, code) instead of manually setting size and weight
|
|
146
|
+
{ guidance: true, description: 'Pick a semantic type (body, label, supporting, large, code) instead of manually setting size and weight; the theme handles the details.' },
|
|
147
147
|
{ guidance: true, description: 'Set accessibilityLevel on Heading when the visual level differs from the document outline so screen readers announce the correct hierarchy.' },
|
|
148
|
-
{ guidance: true, description: 'Use maxLines with a number to truncate long content
|
|
148
|
+
{ guidance: true, description: 'Use maxLines with a number to truncate long content; a tooltip appears automatically on hover so no text is lost.' },
|
|
149
149
|
{ guidance: true, description: 'Enable hasTabularNumbers for columns of numeric data so digits align vertically across rows.' },
|
|
150
|
-
{ guidance: false, description: 'Override size and weight when a semantic type already matches
|
|
151
|
-
{ guidance: false, description: 'Skip heading levels in the document outline
|
|
152
|
-
{ guidance: false, description: 'Use raw HTML tags like <p>, <h1>\u2013<h6>, or <span> for text
|
|
153
|
-
{ guidance: false, description: 'Pass a `variant` prop
|
|
154
|
-
{ guidance: false, description: 'Use Text for headings
|
|
150
|
+
{ guidance: false, description: 'Override size and weight when a semantic type already matches; extra overrides fight the theme and break when themes change.' },
|
|
151
|
+
{ guidance: false, description: 'Skip heading levels in the document outline; go h1 then h2 then h3, never h1 then h3.' },
|
|
152
|
+
{ guidance: false, description: 'Use raw HTML tags like <p>, <h1>\u2013<h6>, or <span> for text; Text and Heading apply the correct theme tokens automatically.' },
|
|
153
|
+
{ guidance: false, description: 'Pass a `variant` prop; Text does not have a `variant` prop. Use `type` for semantic styling (body, label, large, supporting, code) or use Heading for headings.' },
|
|
154
|
+
{ guidance: false, description: 'Use Text for headings; use Heading with a `level` prop (1\u20136) for section titles and headings.' },
|
|
155
155
|
],
|
|
156
156
|
},
|
|
157
157
|
};
|
|
@@ -165,12 +165,12 @@ export const docsDense = {
|
|
|
165
165
|
bestPractices: [
|
|
166
166
|
{ guidance: true, description: 'Semantic type (body, label, supporting, large, code) instead of manual size/weight.' },
|
|
167
167
|
{ guidance: true, description: 'accessibilityLevel on Heading when visual level differs from document outline.' },
|
|
168
|
-
{ guidance: true, description: 'maxLines for truncation
|
|
168
|
+
{ guidance: true, description: 'maxLines for truncation; tooltip shows full text on hover.' },
|
|
169
169
|
{ guidance: true, description: 'hasTabularNumbers for aligned numeric columns.' },
|
|
170
170
|
{ guidance: false, description: 'Override size/weight when a semantic type already matches.' },
|
|
171
|
-
{ guidance: false, description: 'Skip heading levels
|
|
172
|
-
{ guidance: false, description: 'Raw <p>/<h1>/<span
|
|
173
|
-
{ guidance: false, description: '`variant` prop
|
|
171
|
+
{ guidance: false, description: 'Skip heading levels; sequential h1 \u2192 h2 \u2192 h3.' },
|
|
172
|
+
{ guidance: false, description: 'Raw <p>/<h1>/<span>; use Text/Heading for theme tokens.' },
|
|
173
|
+
{ guidance: false, description: '`variant` prop, which does not exist. Use `type` for text styling or Heading for headings.' },
|
|
174
174
|
{ guidance: false, description: 'Text for headings: use Heading with level (1\u20136).' },
|
|
175
175
|
],
|
|
176
176
|
},
|
|
@@ -70,6 +70,12 @@ export const docs = {
|
|
|
70
70
|
description: 'Disables the textarea, preventing interaction.',
|
|
71
71
|
default: 'false',
|
|
72
72
|
},
|
|
73
|
+
{
|
|
74
|
+
name: 'disabledMessage',
|
|
75
|
+
type: 'string',
|
|
76
|
+
description:
|
|
77
|
+
'Explains why the textarea is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the textarea focusable via aria-disabled (the field becomes read-only). Use this instead of wrapping a disabled TextArea in Tooltip. Disabled controls swallow the hover events an external Tooltip needs.',
|
|
78
|
+
},
|
|
73
79
|
{
|
|
74
80
|
name: 'isLoading',
|
|
75
81
|
type: 'boolean',
|
|
@@ -174,6 +180,7 @@ export const docs = {
|
|
|
174
180
|
{ guidance: false, description: 'Avoid using TextArea for short, single-line values like names or emails; use TextInput instead.' },
|
|
175
181
|
{ guidance: false, description: 'Don\'t rely solely on placeholder text to communicate the purpose of the field; placeholders disappear on focus and are not accessible labels.' },
|
|
176
182
|
{ guidance: false, description: 'Don\'t show a status message without also setting the status type; the colored border and icon are what draw the user\'s attention to the message.' },
|
|
183
|
+
{ guidance: false, description: 'Don\'t wrap a disabled TextArea in Tooltip to explain why it\'s disabled; disabled controls swallow the hover events the wrapper needs. Use the disabledMessage prop instead.' },
|
|
177
184
|
],
|
|
178
185
|
},
|
|
179
186
|
};
|
|
@@ -239,6 +246,12 @@ export const docsZh = {
|
|
|
239
246
|
description: '禁用文本域,阻止交互。',
|
|
240
247
|
default: 'false',
|
|
241
248
|
},
|
|
249
|
+
{
|
|
250
|
+
name: 'disabledMessage',
|
|
251
|
+
type: 'string',
|
|
252
|
+
description:
|
|
253
|
+
'说明文本域被禁用的原因。与 isDisabled 一起使用时,在悬停/键盘聚焦时显示工具提示,并通过 aria-disabled 保持文本域可聚焦(字段变为只读)。请使用此属性,而不是用 Tooltip 包裹已禁用的 TextArea。',
|
|
254
|
+
},
|
|
242
255
|
{
|
|
243
256
|
name: 'isLoading',
|
|
244
257
|
type: 'boolean',
|
|
@@ -336,6 +349,7 @@ export const docsZh = {
|
|
|
336
349
|
{ guidance: false, description: 'Avoid using TextArea for short, single-line values like names or emails; use TextInput instead.' },
|
|
337
350
|
{ guidance: false, description: 'Don\'t rely solely on placeholder text to communicate the purpose of the field; placeholders disappear on focus and are not accessible labels.' },
|
|
338
351
|
{ guidance: false, description: 'Don\'t show a status message without also setting the status type; the colored border and icon are what draw the user\'s attention to the message.' },
|
|
352
|
+
{ guidance: false, description: 'Don\'t wrap a disabled TextArea in Tooltip to explain why it\'s disabled; disabled controls swallow the hover events the wrapper needs. Use the disabledMessage prop instead.' },
|
|
339
353
|
],
|
|
340
354
|
},
|
|
341
355
|
};
|
|
@@ -354,6 +368,7 @@ export const docsDense = {
|
|
|
354
368
|
{ guidance: false, description: 'Avoid TextArea for single-line values; use TextInput.' },
|
|
355
369
|
{ guidance: false, description: 'Don\'t use placeholder as only label; disappears on focus, not accessible.' },
|
|
356
370
|
{ guidance: false, description: 'Don\'t show status message without status type; border and icon draw attention.' },
|
|
371
|
+
{ guidance: false, description: 'Don\'t wrap a disabled TextArea in Tooltip to explain the disabled state; use the disabledMessage prop instead.' },
|
|
357
372
|
],
|
|
358
373
|
},
|
|
359
374
|
propDescriptions: {
|
|
@@ -367,6 +382,8 @@ export const docsDense = {
|
|
|
367
382
|
isOptional: 'Shows "Optional" indicator. Mutually exclusive w/ isRequired.',
|
|
368
383
|
isRequired: 'Shows "Required" indicator+sets aria-required. Mutually exclusive w/ isOptional.',
|
|
369
384
|
isDisabled: 'Disables textarea, prevents interaction.',
|
|
385
|
+
disabledMessage:
|
|
386
|
+
'Explains why textarea is disabled. With isDisabled, shows tooltip on hover/focus + keeps textarea focusable via aria-disabled (field becomes read-only). Use instead of wrapping a disabled TextArea in Tooltip.',
|
|
370
387
|
isLoading: 'Loading state w/ spinner inside input.',
|
|
371
388
|
placeholder: 'Placeholder when textarea empty.',
|
|
372
389
|
rows: 'Visible text rows.',
|
|
@@ -10,12 +10,43 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import {useState} from 'react';
|
|
13
|
-
import {describe, it, expect, vi} from 'vitest';
|
|
14
|
-
import {render, screen, fireEvent} from '@testing-library/react';
|
|
13
|
+
import {describe, it, expect, vi, beforeEach} from 'vitest';
|
|
14
|
+
import {render, screen, fireEvent, waitFor} from '@testing-library/react';
|
|
15
15
|
import userEvent from '@testing-library/user-event';
|
|
16
16
|
import {MagnifyingGlassIcon} from '@heroicons/react/24/outline';
|
|
17
17
|
import {TextArea} from './TextArea';
|
|
18
18
|
|
|
19
|
+
// Mock showPopover/hidePopover since jsdom does not implement them. Used by the
|
|
20
|
+
// disabledMessage tooltip.
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
HTMLElement.prototype.showPopover = vi.fn(function (this: HTMLElement) {
|
|
23
|
+
this.setAttribute('popover-open', '');
|
|
24
|
+
const event = new Event('toggle', {bubbles: false});
|
|
25
|
+
Object.defineProperty(event, 'newState', {value: 'open'});
|
|
26
|
+
this.dispatchEvent(event);
|
|
27
|
+
});
|
|
28
|
+
HTMLElement.prototype.hidePopover = vi.fn(function (this: HTMLElement) {
|
|
29
|
+
this.removeAttribute('popover-open');
|
|
30
|
+
const event = new Event('toggle', {bubbles: false});
|
|
31
|
+
Object.defineProperty(event, 'newState', {value: 'closed'});
|
|
32
|
+
this.dispatchEvent(event);
|
|
33
|
+
});
|
|
34
|
+
const originalMatches = HTMLElement.prototype.matches;
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
36
|
+
(HTMLElement.prototype as any).matches = function (
|
|
37
|
+
selector: string,
|
|
38
|
+
): boolean {
|
|
39
|
+
if (selector === ':popover-open') {
|
|
40
|
+
return this.hasAttribute('popover-open');
|
|
41
|
+
}
|
|
42
|
+
return originalMatches.call(this, selector);
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// jsdom popover content is in the DOM but may not be "visible" in the
|
|
47
|
+
// accessibility tree. Use hidden: true to find it.
|
|
48
|
+
const h = {hidden: true} as const;
|
|
49
|
+
|
|
19
50
|
describe('TextArea', () => {
|
|
20
51
|
it('renders with label', () => {
|
|
21
52
|
render(<TextArea label="Description" value="" onChange={() => {}} />);
|
|
@@ -39,9 +70,7 @@ describe('TextArea', () => {
|
|
|
39
70
|
it('calls onChange with value and event when typing', async () => {
|
|
40
71
|
const user = userEvent.setup();
|
|
41
72
|
const handleChange = vi.fn();
|
|
42
|
-
render(
|
|
43
|
-
<TextArea label="Description" value="" onChange={handleChange} />,
|
|
44
|
-
);
|
|
73
|
+
render(<TextArea label="Description" value="" onChange={handleChange} />);
|
|
45
74
|
|
|
46
75
|
const textarea = screen.getByRole('textbox');
|
|
47
76
|
await user.type(textarea, 'Hi');
|
|
@@ -73,24 +102,14 @@ describe('TextArea', () => {
|
|
|
73
102
|
it('forwards ref correctly', () => {
|
|
74
103
|
const ref = vi.fn();
|
|
75
104
|
render(
|
|
76
|
-
<TextArea
|
|
77
|
-
ref={ref}
|
|
78
|
-
label="Description"
|
|
79
|
-
value=""
|
|
80
|
-
onChange={() => {}}
|
|
81
|
-
/>,
|
|
105
|
+
<TextArea ref={ref} label="Description" value="" onChange={() => {}} />,
|
|
82
106
|
);
|
|
83
107
|
expect(ref).toHaveBeenCalledWith(expect.any(HTMLTextAreaElement));
|
|
84
108
|
});
|
|
85
109
|
|
|
86
110
|
it('visually hides label when isLabelHidden is true', () => {
|
|
87
111
|
render(
|
|
88
|
-
<TextArea
|
|
89
|
-
label="Comments"
|
|
90
|
-
isLabelHidden
|
|
91
|
-
value=""
|
|
92
|
-
onChange={() => {}}
|
|
93
|
-
/>,
|
|
112
|
+
<TextArea label="Comments" isLabelHidden value="" onChange={() => {}} />,
|
|
94
113
|
);
|
|
95
114
|
const label = screen.getByText('Comments');
|
|
96
115
|
expect(label).toBeInTheDocument();
|
|
@@ -133,12 +152,7 @@ describe('TextArea', () => {
|
|
|
133
152
|
|
|
134
153
|
it('is disabled when isDisabled is true', () => {
|
|
135
154
|
render(
|
|
136
|
-
<TextArea
|
|
137
|
-
label="Description"
|
|
138
|
-
isDisabled
|
|
139
|
-
value=""
|
|
140
|
-
onChange={() => {}}
|
|
141
|
-
/>,
|
|
155
|
+
<TextArea label="Description" isDisabled value="" onChange={() => {}} />,
|
|
142
156
|
);
|
|
143
157
|
expect(screen.getByRole('textbox')).toBeDisabled();
|
|
144
158
|
});
|
|
@@ -150,12 +164,7 @@ describe('TextArea', () => {
|
|
|
150
164
|
|
|
151
165
|
it('shows aria-busy when isLoading is true', () => {
|
|
152
166
|
render(
|
|
153
|
-
<TextArea
|
|
154
|
-
label="Description"
|
|
155
|
-
isLoading
|
|
156
|
-
value=""
|
|
157
|
-
onChange={() => {}}
|
|
158
|
-
/>,
|
|
167
|
+
<TextArea label="Description" isLoading value="" onChange={() => {}} />,
|
|
159
168
|
);
|
|
160
169
|
expect(screen.getByRole('textbox')).toHaveAttribute('aria-busy', 'true');
|
|
161
170
|
expect(screen.getByRole('textbox')).not.toBeDisabled();
|
|
@@ -340,12 +349,7 @@ describe('TextArea', () => {
|
|
|
340
349
|
|
|
341
350
|
it('renders with size="lg"', () => {
|
|
342
351
|
render(
|
|
343
|
-
<TextArea
|
|
344
|
-
label="Description"
|
|
345
|
-
value=""
|
|
346
|
-
onChange={() => {}}
|
|
347
|
-
size="lg"
|
|
348
|
-
/>,
|
|
352
|
+
<TextArea label="Description" value="" onChange={() => {}} size="lg" />,
|
|
349
353
|
);
|
|
350
354
|
expect(screen.getByLabelText('Description')).toBeInTheDocument();
|
|
351
355
|
});
|
|
@@ -595,4 +599,132 @@ describe('TextArea', () => {
|
|
|
595
599
|
expect(textarea).toHaveFocus();
|
|
596
600
|
});
|
|
597
601
|
});
|
|
602
|
+
|
|
603
|
+
describe('disabledMessage', () => {
|
|
604
|
+
it('shows the reason tooltip on hover when disabled with a reason', async () => {
|
|
605
|
+
render(
|
|
606
|
+
<TextArea
|
|
607
|
+
label="Notes"
|
|
608
|
+
value=""
|
|
609
|
+
onChange={() => {}}
|
|
610
|
+
isDisabled
|
|
611
|
+
disabledMessage="You need the Editor role"
|
|
612
|
+
/>,
|
|
613
|
+
);
|
|
614
|
+
|
|
615
|
+
const textarea = screen.getByRole('textbox');
|
|
616
|
+
const container = textarea.parentElement as HTMLElement;
|
|
617
|
+
const tooltip = screen.getByRole('tooltip', h);
|
|
618
|
+
expect(tooltip).toHaveTextContent('You need the Editor role');
|
|
619
|
+
|
|
620
|
+
fireEvent.mouseEnter(container);
|
|
621
|
+
await waitFor(() => {
|
|
622
|
+
expect(tooltip).toHaveAttribute('popover-open');
|
|
623
|
+
});
|
|
624
|
+
|
|
625
|
+
fireEvent.mouseLeave(container);
|
|
626
|
+
await waitFor(() => {
|
|
627
|
+
expect(tooltip).not.toHaveAttribute('popover-open');
|
|
628
|
+
});
|
|
629
|
+
});
|
|
630
|
+
|
|
631
|
+
it('shows the reason tooltip on keyboard focus', async () => {
|
|
632
|
+
const user = userEvent.setup();
|
|
633
|
+
render(
|
|
634
|
+
<TextArea
|
|
635
|
+
label="Notes"
|
|
636
|
+
value=""
|
|
637
|
+
onChange={() => {}}
|
|
638
|
+
isDisabled
|
|
639
|
+
disabledMessage="You need the Editor role"
|
|
640
|
+
/>,
|
|
641
|
+
);
|
|
642
|
+
|
|
643
|
+
const tooltip = screen.getByRole('tooltip', h);
|
|
644
|
+
await user.tab();
|
|
645
|
+
expect(screen.getByRole('textbox')).toHaveFocus();
|
|
646
|
+
await waitFor(() => {
|
|
647
|
+
expect(tooltip).toHaveAttribute('popover-open');
|
|
648
|
+
});
|
|
649
|
+
});
|
|
650
|
+
|
|
651
|
+
it('does not render a tooltip when not disabled', () => {
|
|
652
|
+
render(
|
|
653
|
+
<TextArea
|
|
654
|
+
label="Notes"
|
|
655
|
+
value=""
|
|
656
|
+
onChange={() => {}}
|
|
657
|
+
disabledMessage="You need the Editor role"
|
|
658
|
+
/>,
|
|
659
|
+
);
|
|
660
|
+
expect(screen.queryByRole('tooltip', h)).not.toBeInTheDocument();
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
it('does not render a tooltip when disabled without a reason', () => {
|
|
664
|
+
render(
|
|
665
|
+
<TextArea label="Notes" value="" onChange={() => {}} isDisabled />,
|
|
666
|
+
);
|
|
667
|
+
expect(screen.queryByRole('tooltip', h)).not.toBeInTheDocument();
|
|
668
|
+
});
|
|
669
|
+
|
|
670
|
+
it('keeps the textarea focusable via aria-disabled when a reason is provided', () => {
|
|
671
|
+
render(
|
|
672
|
+
<TextArea
|
|
673
|
+
label="Notes"
|
|
674
|
+
value=""
|
|
675
|
+
onChange={() => {}}
|
|
676
|
+
isDisabled
|
|
677
|
+
disabledMessage="You need the Editor role"
|
|
678
|
+
/>,
|
|
679
|
+
);
|
|
680
|
+
const textarea = screen.getByRole('textbox');
|
|
681
|
+
expect(textarea).not.toBeDisabled();
|
|
682
|
+
expect(textarea).toHaveAttribute('aria-disabled', 'true');
|
|
683
|
+
expect(textarea).toHaveAttribute('readonly');
|
|
684
|
+
});
|
|
685
|
+
|
|
686
|
+
it('links the reason tooltip from the textarea via aria-describedby', () => {
|
|
687
|
+
render(
|
|
688
|
+
<TextArea
|
|
689
|
+
label="Notes"
|
|
690
|
+
value=""
|
|
691
|
+
onChange={() => {}}
|
|
692
|
+
isDisabled
|
|
693
|
+
disabledMessage="You need the Editor role"
|
|
694
|
+
/>,
|
|
695
|
+
);
|
|
696
|
+
const textarea = screen.getByRole('textbox');
|
|
697
|
+
const tooltip = screen.getByRole('tooltip', h);
|
|
698
|
+
expect(textarea.getAttribute('aria-describedby')).toContain(tooltip.id);
|
|
699
|
+
});
|
|
700
|
+
|
|
701
|
+
it('blocks value changes while focusable-disabled', async () => {
|
|
702
|
+
const user = userEvent.setup();
|
|
703
|
+
const onChange = vi.fn();
|
|
704
|
+
render(
|
|
705
|
+
<TextArea
|
|
706
|
+
label="Notes"
|
|
707
|
+
value=""
|
|
708
|
+
onChange={onChange}
|
|
709
|
+
isDisabled
|
|
710
|
+
disabledMessage="You need the Editor role"
|
|
711
|
+
/>,
|
|
712
|
+
);
|
|
713
|
+
|
|
714
|
+
const textarea = screen.getByRole('textbox');
|
|
715
|
+
await user.click(textarea);
|
|
716
|
+
await user.keyboard('hello');
|
|
717
|
+
expect(onChange).not.toHaveBeenCalled();
|
|
718
|
+
expect(textarea).toHaveValue('');
|
|
719
|
+
});
|
|
720
|
+
|
|
721
|
+
it('remains natively disabled when disabled without a reason', () => {
|
|
722
|
+
render(
|
|
723
|
+
<TextArea label="Notes" value="" onChange={() => {}} isDisabled />,
|
|
724
|
+
);
|
|
725
|
+
const textarea = screen.getByRole('textbox');
|
|
726
|
+
expect(textarea).toBeDisabled();
|
|
727
|
+
expect(textarea).not.toHaveAttribute('aria-disabled');
|
|
728
|
+
});
|
|
729
|
+
});
|
|
598
730
|
});
|
|
@@ -43,12 +43,14 @@ import {
|
|
|
43
43
|
} from '../Field';
|
|
44
44
|
import {Icon, renderIconSlot, type IconType} from '../Icon';
|
|
45
45
|
import {Spinner} from '../Spinner';
|
|
46
|
+
import {useTooltip} from '../Tooltip';
|
|
46
47
|
import {mergeProps, mergeRefs} from '../utils';
|
|
47
48
|
import type {BaseProps} from '../BaseProps';
|
|
48
49
|
import type {SizeValue} from '../utils/types';
|
|
49
50
|
import {useInputContainer} from '../hooks/useInputContainer';
|
|
50
51
|
import {useSize} from '../SizeContext/SizeContext';
|
|
51
52
|
import {themeProps} from '../utils/themeProps';
|
|
53
|
+
import {VisuallyHidden} from '../VisuallyHidden';
|
|
52
54
|
|
|
53
55
|
const COUNTER_WARNING_THRESHOLD = 0.8;
|
|
54
56
|
|
|
@@ -93,17 +95,6 @@ const styles = stylex.create({
|
|
|
93
95
|
counterError: {
|
|
94
96
|
color: colorVars['--color-error'],
|
|
95
97
|
},
|
|
96
|
-
srOnly: {
|
|
97
|
-
position: 'absolute',
|
|
98
|
-
width: '1px',
|
|
99
|
-
height: '1px',
|
|
100
|
-
padding: 0,
|
|
101
|
-
margin: '-1px',
|
|
102
|
-
overflow: 'hidden',
|
|
103
|
-
clip: 'rect(0,0,0,0)',
|
|
104
|
-
whiteSpace: 'nowrap',
|
|
105
|
-
borderWidth: 0,
|
|
106
|
-
},
|
|
107
98
|
statusIcon: {
|
|
108
99
|
position: 'absolute',
|
|
109
100
|
top: spacingVars['--spacing-2'],
|
|
@@ -199,6 +190,27 @@ export interface TextAreaProps extends Omit<
|
|
|
199
190
|
* @default false
|
|
200
191
|
*/
|
|
201
192
|
isDisabled?: boolean;
|
|
193
|
+
/**
|
|
194
|
+
* Explains why the textarea is disabled. When set together with
|
|
195
|
+
* `isDisabled`, the textarea shows a tooltip with this text on hover and
|
|
196
|
+
* keyboard focus, and stays focusable (via `aria-disabled`) so the reason is
|
|
197
|
+
* discoverable by keyboard and assistive technology. The field cannot be
|
|
198
|
+
* edited (it becomes read-only) while disabled.
|
|
199
|
+
*
|
|
200
|
+
* Use this instead of wrapping a disabled textarea in `Tooltip` — disabled
|
|
201
|
+
* controls don't emit the pointer events an external tooltip needs.
|
|
202
|
+
*
|
|
203
|
+
* @example
|
|
204
|
+
* ```
|
|
205
|
+
* <TextArea
|
|
206
|
+
* label="Notes"
|
|
207
|
+
* value={notes}
|
|
208
|
+
* isDisabled
|
|
209
|
+
* disabledMessage="Notes are locked after submission"
|
|
210
|
+
* />
|
|
211
|
+
* ```
|
|
212
|
+
*/
|
|
213
|
+
disabledMessage?: string;
|
|
202
214
|
/**
|
|
203
215
|
* Status indicator for the textarea.
|
|
204
216
|
* When set, displays a colored border and status icon.
|
|
@@ -284,6 +296,7 @@ export function TextArea({
|
|
|
284
296
|
placeholder,
|
|
285
297
|
rows = 3,
|
|
286
298
|
isDisabled = false,
|
|
299
|
+
disabledMessage,
|
|
287
300
|
status,
|
|
288
301
|
labelTooltip,
|
|
289
302
|
startIcon,
|
|
@@ -314,6 +327,20 @@ export function TextArea({
|
|
|
314
327
|
const [optimisticValue, setOptimisticValue] = useOptimistic(value);
|
|
315
328
|
const isBusy = isLoading || optimisticValue !== value;
|
|
316
329
|
|
|
330
|
+
// Disabled-reason tooltip. Disabled controls swallow pointer events, so the
|
|
331
|
+
// tooltip listeners attach to the textarea container (which already exists)
|
|
332
|
+
// and the textarea stays perceivable via aria-disabled instead of the native
|
|
333
|
+
// disabled attribute. The field is made read-only so it can't be typed into,
|
|
334
|
+
// and value mutation is blocked by the isDisabled guard in handleChange.
|
|
335
|
+
const showsDisabledMessage = isDisabled && !!disabledMessage;
|
|
336
|
+
const disabledMessageTooltip = useTooltip({
|
|
337
|
+
placement: 'above',
|
|
338
|
+
// The container div is not naturally focusable; focusin bubbles up from
|
|
339
|
+
// the textarea, so always attach focus listeners.
|
|
340
|
+
focusTrigger: 'always',
|
|
341
|
+
isEnabled: showsDisabledMessage,
|
|
342
|
+
});
|
|
343
|
+
|
|
317
344
|
const statusIconMap: Record<TextAreaStatusType, IconName> = {
|
|
318
345
|
warning: 'warning',
|
|
319
346
|
error: 'error',
|
|
@@ -334,11 +361,18 @@ export function TextArea({
|
|
|
334
361
|
description ? descriptionID : null,
|
|
335
362
|
status?.message ? statusMessageID : null,
|
|
336
363
|
maxLength != null ? counterID : null,
|
|
364
|
+
showsDisabledMessage ? disabledMessageTooltip.describedBy : null,
|
|
337
365
|
]
|
|
338
366
|
.filter(Boolean)
|
|
339
367
|
.join(' ') || undefined;
|
|
340
368
|
|
|
341
369
|
const handleChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
|
|
370
|
+
// Value can't change while showing a disabled message (the field is
|
|
371
|
+
// read-only and non-native-disabled), but guard the handler too so the
|
|
372
|
+
// optimistic value and callbacks never fire.
|
|
373
|
+
if (isDisabled) {
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
342
376
|
const newValue = e.target.value;
|
|
343
377
|
onChange?.(newValue, e);
|
|
344
378
|
if (changeAction && !e.defaultPrevented) {
|
|
@@ -381,7 +415,13 @@ export function TextArea({
|
|
|
381
415
|
labelTooltip={labelTooltip}
|
|
382
416
|
width={width}>
|
|
383
417
|
<div
|
|
384
|
-
ref={
|
|
418
|
+
ref={el => {
|
|
419
|
+
containerRef.current = el;
|
|
420
|
+
// Anchor + hover/focus listeners for the disabled-message tooltip.
|
|
421
|
+
// Handlers are gated internally by isEnabled, and anchor names
|
|
422
|
+
// compose, so attaching unconditionally is safe.
|
|
423
|
+
disabledMessageTooltip.ref(el);
|
|
424
|
+
}}
|
|
385
425
|
onClick={handleWrapperClick}
|
|
386
426
|
onMouseUp={handleWrapperMouseUp}
|
|
387
427
|
{...mergeProps(
|
|
@@ -413,7 +453,12 @@ export function TextArea({
|
|
|
413
453
|
onBlur={onBlur}
|
|
414
454
|
placeholder={placeholder}
|
|
415
455
|
rows={rows}
|
|
416
|
-
|
|
456
|
+
// With a disabledMessage the textarea keeps focusability via
|
|
457
|
+
// aria-disabled so the reason is focus-discoverable; readOnly + the
|
|
458
|
+
// handleChange guard keep the value from changing.
|
|
459
|
+
disabled={isDisabled && !showsDisabledMessage}
|
|
460
|
+
aria-disabled={showsDisabledMessage ? 'true' : undefined}
|
|
461
|
+
readOnly={showsDisabledMessage || undefined}
|
|
417
462
|
spellCheck={hasSpellCheck}
|
|
418
463
|
autoFocus={hasAutoFocus}
|
|
419
464
|
data-autofocus={hasAutoFocus || undefined}
|
|
@@ -451,15 +496,17 @@ export function TextArea({
|
|
|
451
496
|
optimisticValue.length > maxLength && styles.counterError,
|
|
452
497
|
)}>
|
|
453
498
|
{optimisticValue.length}/{maxLength}
|
|
454
|
-
<
|
|
499
|
+
<VisuallyHidden aria-live="polite">
|
|
455
500
|
{optimisticValue.length >= maxLength * COUNTER_WARNING_THRESHOLD
|
|
456
501
|
? optimisticValue.length > maxLength
|
|
457
502
|
? `${optimisticValue.length - maxLength} characters over limit`
|
|
458
503
|
: `${maxLength - optimisticValue.length} characters remaining`
|
|
459
504
|
: ''}
|
|
460
|
-
</
|
|
505
|
+
</VisuallyHidden>
|
|
461
506
|
</div>
|
|
462
507
|
)}
|
|
508
|
+
{showsDisabledMessage &&
|
|
509
|
+
disabledMessageTooltip.renderTooltip(disabledMessage)}
|
|
463
510
|
</Field>
|
|
464
511
|
);
|
|
465
512
|
}
|
|
@@ -78,6 +78,12 @@ export const docs = {
|
|
|
78
78
|
'Disables the input, preventing interaction and dimming the element.',
|
|
79
79
|
default: 'false',
|
|
80
80
|
},
|
|
81
|
+
{
|
|
82
|
+
name: 'disabledMessage',
|
|
83
|
+
type: 'string',
|
|
84
|
+
description:
|
|
85
|
+
'Explains why the input is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the input focusable via aria-disabled (the field becomes read-only). Use this instead of wrapping a disabled TextInput in Tooltip. Disabled controls swallow the hover events an external Tooltip needs.',
|
|
86
|
+
},
|
|
81
87
|
{
|
|
82
88
|
name: 'isLoading',
|
|
83
89
|
type: 'boolean',
|
|
@@ -144,6 +150,7 @@ export const docs = {
|
|
|
144
150
|
{guidance: false, description: "Don't use placeholder text as a replacement for a label; placeholders disappear on focus and are not reliably read by screen readers."},
|
|
145
151
|
{guidance: false, description: "Don't use TextInput for multi-line content like comments or descriptions; use TextArea instead."},
|
|
146
152
|
{guidance: false, description: "Don't mark every field as required; only flag mandatory fields so users are not overwhelmed by validation errors."},
|
|
153
|
+
{guidance: false, description: "Don't wrap a disabled TextInput in Tooltip to explain why it's disabled; disabled controls swallow the hover events the wrapper needs. Use the disabledMessage prop instead."},
|
|
147
154
|
],
|
|
148
155
|
anatomy: [
|
|
149
156
|
{name: 'Label', required: true, description: 'Text that identifies the field. Always rendered for accessibility even when visually hidden.'},
|
|
@@ -231,6 +238,12 @@ export const docsZh = {
|
|
|
231
238
|
'禁用输入框,阻止交互并使元素变暗。',
|
|
232
239
|
default: 'false',
|
|
233
240
|
},
|
|
241
|
+
{
|
|
242
|
+
name: 'disabledMessage',
|
|
243
|
+
type: 'string',
|
|
244
|
+
description:
|
|
245
|
+
'说明输入框被禁用的原因。与 isDisabled 一起使用时,在悬停/键盘聚焦时显示工具提示,并通过 aria-disabled 保持输入框可聚焦(字段变为只读)。请使用此属性,而不是用 Tooltip 包裹已禁用的 TextInput——已禁用的控件会吞掉外部 Tooltip 所需的悬停事件。',
|
|
246
|
+
},
|
|
234
247
|
{
|
|
235
248
|
name: 'isLoading',
|
|
236
249
|
type: 'boolean',
|
|
@@ -296,6 +309,7 @@ export const docsZh = {
|
|
|
296
309
|
{guidance: false, description: "Don't use placeholder text as a replacement for a label; placeholders disappear on focus and are not reliably read by screen readers."},
|
|
297
310
|
{guidance: false, description: "Don't use TextInput for multi-line content like comments or descriptions; use TextArea instead."},
|
|
298
311
|
{guidance: false, description: "Don't mark every field as required; only flag mandatory fields so users are not overwhelmed by validation errors."},
|
|
312
|
+
{guidance: false, description: "Don't wrap a disabled TextInput in Tooltip to explain why it's disabled; disabled controls swallow the hover events the wrapper needs. Use the disabledMessage prop instead."},
|
|
299
313
|
],
|
|
300
314
|
anatomy: [
|
|
301
315
|
{name: 'Label', required: true, description: 'Text that identifies the field. Always rendered for accessibility even when visually hidden.'},
|
|
@@ -323,6 +337,7 @@ export const docsDense = {
|
|
|
323
337
|
{guidance: false, description: "Don't use placeholder text as a replacement for a label; placeholders disappear on focus and are not reliably read by screen readers."},
|
|
324
338
|
{guidance: false, description: "Don't use TextInput for multi-line content like comments or descriptions; use TextArea instead."},
|
|
325
339
|
{guidance: false, description: "Don't mark every field as required; only flag mandatory fields so users are not overwhelmed by validation errors."},
|
|
340
|
+
{guidance: false, description: "Don't wrap a disabled TextInput in Tooltip to explain why it's disabled; disabled controls swallow the hover events the wrapper needs. Use the disabledMessage prop instead."},
|
|
326
341
|
],
|
|
327
342
|
anatomy: [
|
|
328
343
|
{name: 'Label', required: true, description: 'Text that identifies the field. Always rendered for accessibility even when visually hidden.'},
|
|
@@ -346,6 +361,8 @@ export const docsDense = {
|
|
|
346
361
|
isOptional: 'Shows "Optional" indicator. Mutually exclusive w/ isRequired.',
|
|
347
362
|
isRequired: 'Shows "Required" indicator+sets aria-required. Mutually exclusive w/ isOptional.',
|
|
348
363
|
isDisabled: 'Disables input, prevents interaction, dims element.',
|
|
364
|
+
disabledMessage:
|
|
365
|
+
'Explains why input is disabled. With isDisabled, shows tooltip on hover/focus + keeps input focusable via aria-disabled (field becomes read-only). Use instead of wrapping a disabled TextInput in Tooltip.',
|
|
349
366
|
isLoading: 'Loading state w/ spinner+aria-busy.',
|
|
350
367
|
placeholder: 'Placeholder when input empty.',
|
|
351
368
|
labelTooltip: 'Tooltip in info icon at label end.',
|