@astryxdesign/core 0.1.3 → 0.1.4-canary.01e5b29
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 +51 -0
- package/dist/AlertDialog/AlertDialog.d.ts +1 -1
- package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
- package/dist/AlertDialog/AlertDialog.js +20 -18
- package/dist/AlertDialog/useImperativeAlertDialog.js +3 -3
- package/dist/AppShell/AppShell.d.ts +1 -1
- package/dist/AppShell/AppShell.d.ts.map +1 -1
- package/dist/AppShell/AppShell.js +55 -53
- package/dist/AspectRatio/AspectRatio.js +5 -5
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +27 -25
- package/dist/Avatar/AvatarStatusDot.js +5 -5
- package/dist/AvatarGroup/AvatarGroup.js +5 -5
- package/dist/AvatarGroup/AvatarGroupOverflow.js +5 -5
- package/dist/Badge/Badge.js +3 -3
- package/dist/Banner/Banner.d.ts.map +1 -1
- package/dist/Banner/Banner.js +32 -25
- package/dist/Blockquote/Blockquote.js +7 -7
- package/dist/Breadcrumbs/BreadcrumbItem.js +17 -17
- package/dist/Breadcrumbs/Breadcrumbs.js +7 -7
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +47 -26
- package/dist/ButtonGroup/ButtonGroup.js +7 -7
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +108 -64
- 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/styles.d.ts +2 -2
- package/dist/Calendar/styles.d.ts.map +1 -1
- package/dist/Calendar/styles.js +2 -2
- package/dist/Card/Card.d.ts +4 -2
- package/dist/Card/Card.d.ts.map +1 -1
- package/dist/Card/Card.js +18 -10
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +20 -19
- package/dist/Center/Center.js +3 -3
- package/dist/Chat/ChatComposer.js +23 -23
- package/dist/Chat/ChatComposerDrawer.js +14 -14
- package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
- package/dist/Chat/ChatComposerInput.js +27 -15
- package/dist/Chat/ChatDictationButton.d.ts +1 -1
- package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
- package/dist/Chat/ChatDictationButton.js +13 -11
- package/dist/Chat/ChatLayout.js +17 -17
- package/dist/Chat/ChatLayoutScrollButton.d.ts +1 -1
- package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
- package/dist/Chat/ChatLayoutScrollButton.js +12 -10
- package/dist/Chat/ChatMessage.js +12 -12
- package/dist/Chat/ChatMessageBubble.js +7 -7
- package/dist/Chat/ChatMessageList.js +14 -14
- package/dist/Chat/ChatMessageMetadata.d.ts +1 -1
- package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
- package/dist/Chat/ChatMessageMetadata.js +14 -12
- package/dist/Chat/ChatPastedTextToken.js +13 -13
- package/dist/Chat/ChatSendButton.js +3 -3
- package/dist/Chat/ChatSystemMessage.d.ts +1 -1
- package/dist/Chat/ChatSystemMessage.d.ts.map +1 -1
- package/dist/Chat/ChatSystemMessage.js +17 -17
- package/dist/Chat/ChatTokenizedText.d.ts +1 -1
- package/dist/Chat/ChatTokenizedText.d.ts.map +1 -1
- package/dist/Chat/ChatTokenizedText.js +24 -15
- package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
- package/dist/Chat/ChatToolCalls.js +81 -74
- package/dist/Chat/index.d.ts +1 -1
- package/dist/Chat/index.d.ts.map +1 -1
- package/dist/Chat/useTriggerMenu.js +15 -15
- package/dist/CheckboxInput/CheckboxInput.d.ts +6 -1
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +32 -24
- package/dist/CheckboxList/CheckboxList.js +9 -9
- package/dist/CheckboxList/CheckboxListItem.d.ts +1 -1
- package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxListItem.js +8 -6
- package/dist/Citation/Citation.js +10 -10
- package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
- package/dist/ClickableCard/ClickableCard.js +32 -9
- package/dist/Code/Code.d.ts +15 -1
- package/dist/Code/Code.d.ts.map +1 -1
- package/dist/Code/Code.js +35 -5
- package/dist/Code/index.d.ts +1 -1
- package/dist/Code/index.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.d.ts +10 -1
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +88 -52
- package/dist/CodeBlock/index.d.ts +1 -1
- package/dist/CodeBlock/index.d.ts.map +1 -1
- package/dist/Collapsible/Collapsible.d.ts +9 -3
- package/dist/Collapsible/Collapsible.d.ts.map +1 -1
- package/dist/Collapsible/Collapsible.js +110 -22
- package/dist/Collapsible/CollapsibleGroup.d.ts +39 -7
- package/dist/Collapsible/CollapsibleGroup.d.ts.map +1 -1
- package/dist/Collapsible/CollapsibleGroup.js +73 -12
- package/dist/Collapsible/CollapsibleGroupContext.d.ts +31 -0
- package/dist/Collapsible/CollapsibleGroupContext.d.ts.map +1 -1
- package/dist/Collapsible/CollapsibleGroupContext.js +33 -3
- package/dist/Collapsible/index.d.ts +1 -0
- package/dist/Collapsible/index.d.ts.map +1 -1
- package/dist/Collapsible/useCollapsible.d.ts +4 -1
- package/dist/Collapsible/useCollapsible.d.ts.map +1 -1
- package/dist/Collapsible/useCollapsible.js +20 -6
- package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPalette.js +36 -34
- package/dist/CommandPalette/CommandPaletteEmpty.d.ts +1 -1
- package/dist/CommandPalette/CommandPaletteEmpty.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteEmpty.js +27 -7
- package/dist/CommandPalette/CommandPaletteFooter.js +16 -16
- package/dist/CommandPalette/CommandPaletteGroup.js +5 -5
- package/dist/CommandPalette/CommandPaletteInput.js +13 -13
- package/dist/CommandPalette/CommandPaletteItem.js +3 -3
- package/dist/CommandPalette/CommandPaletteList.js +3 -3
- package/dist/ContextMenu/ContextMenu.d.ts +9 -1
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +16 -11
- package/dist/DateInput/DateInput.js +18 -18
- package/dist/DateRangeInput/DateRangeInput.js +23 -23
- package/dist/DateTimeInput/DateTimeInput.d.ts +5 -7
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +30 -26
- package/dist/DateTimeInput/index.d.ts +1 -1
- package/dist/DateTimeInput/index.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +9 -9
- package/dist/Dialog/DialogHeader.js +16 -16
- package/dist/Dialog/useImperativeDialog.js +3 -3
- package/dist/Divider/Divider.d.ts +0 -22
- package/dist/Divider/Divider.d.ts.map +1 -1
- package/dist/Divider/Divider.js +7 -7
- package/dist/DropdownMenu/DropdownMenu.js +10 -10
- package/dist/DropdownMenu/DropdownMenuItem.d.ts +2 -17
- package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuItem.js +3 -3
- package/dist/DropdownMenu/renderDropdownItems.js +10 -10
- package/dist/EmptyState/EmptyState.js +9 -9
- package/dist/Field/Field.js +17 -17
- package/dist/Field/FieldLabel.js +15 -15
- package/dist/Field/InputClearButton.js +5 -5
- package/dist/FieldStatus/FieldStatus.js +3 -3
- package/dist/FileInput/FileInput.js +29 -29
- package/dist/FormLayout/FormLayout.js +5 -5
- package/dist/Grid/Grid.d.ts +4 -3
- package/dist/Grid/Grid.d.ts.map +1 -1
- package/dist/Grid/Grid.js +29 -12
- package/dist/Grid/GridSpan.js +3 -3
- package/dist/HStack/HStack.js +3 -3
- package/dist/Heading/Heading.js +10 -10
- package/dist/HoverCard/HoverCard.js +9 -9
- package/dist/HoverCard/useHoverCard.js +3 -3
- package/dist/Icon/Icon.d.ts.map +1 -1
- package/dist/Icon/Icon.js +16 -12
- package/dist/Icon/defaultIcons.js +116 -116
- package/dist/IconButton/IconButton.js +3 -3
- package/dist/InputGroup/InputGroup.js +11 -11
- package/dist/InputGroup/InputGroupText.js +3 -3
- package/dist/Item/Item.js +18 -18
- package/dist/Kbd/Kbd.js +5 -5
- package/dist/Layer/LayerProvider.js +7 -7
- package/dist/Layer/useLayer.js +5 -5
- package/dist/Layout/Layout.js +21 -21
- package/dist/Layout/LayoutContent.js +3 -3
- package/dist/Layout/LayoutFooter.js +5 -5
- package/dist/Layout/LayoutHeader.js +5 -5
- package/dist/Layout/LayoutPanel.js +3 -3
- package/dist/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/Lightbox/Lightbox.js +55 -31
- package/dist/Lightbox/useLightbox.js +3 -3
- package/dist/Link/Link.js +15 -15
- package/dist/Link/LinkProvider.js +3 -3
- package/dist/Link/useLinkify.js +3 -3
- package/dist/List/List.js +11 -11
- package/dist/List/ListItem.js +11 -11
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.js +102 -102
- package/dist/Markdown/parser.d.ts +7 -0
- package/dist/Markdown/parser.d.ts.map +1 -1
- package/dist/Markdown/parser.js +300 -6
- package/dist/MetadataList/MetadataList.js +10 -10
- package/dist/MetadataList/MetadataListItem.js +15 -15
- package/dist/MobileNav/MobileNav.js +15 -15
- package/dist/MobileNav/MobileNavToggle.js +5 -5
- package/dist/MoreMenu/MoreMenu.js +3 -3
- package/dist/MultiSelector/MultiSelector.d.ts +7 -1
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +64 -55
- package/dist/NavIcon/NavIcon.js +3 -3
- package/dist/NavMenu/NavHeadingMenu.js +5 -5
- package/dist/NavMenu/NavHeadingMenuItem.js +8 -8
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +48 -32
- package/dist/Outline/Outline.js +15 -15
- package/dist/OverflowList/OverflowList.js +8 -8
- package/dist/Overlay/Overlay.js +3 -3
- package/dist/Overlay/OverlayScrim.js +5 -5
- package/dist/Overlay/useOverlay.js +3 -3
- package/dist/Pagination/Pagination.d.ts +1 -1
- package/dist/Pagination/Pagination.d.ts.map +1 -1
- package/dist/Pagination/Pagination.js +125 -72
- package/dist/Popover/Popover.js +16 -16
- package/dist/Popover/usePopover.js +7 -7
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +110 -92
- package/dist/PowerSearch/PowerSearchEditPopover.js +84 -84
- package/dist/PowerSearch/PowerSearchFilterEditor.js +3 -3
- package/dist/PowerSearch/PowerSearchToken.js +5 -5
- package/dist/PowerSearch/PowerSearchValueEditor.js +54 -54
- package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
- package/dist/ProgressBar/ProgressBar.js +25 -18
- package/dist/RadioList/RadioList.d.ts +7 -1
- package/dist/RadioList/RadioList.d.ts.map +1 -1
- package/dist/RadioList/RadioList.js +10 -8
- package/dist/RadioList/RadioListItem.d.ts +1 -1
- package/dist/RadioList/RadioListItem.d.ts.map +1 -1
- package/dist/RadioList/RadioListItem.js +30 -22
- package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
- package/dist/Resizable/ResizeHandle.js +28 -10
- package/dist/Section/Section.js +5 -5
- package/dist/SegmentedControl/SegmentedControl.d.ts +1 -1
- package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControl.js +32 -10
- package/dist/SegmentedControl/SegmentedControlItem.d.ts +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.js +18 -12
- package/dist/SelectableCard/SelectableCard.js +5 -5
- package/dist/Selector/Selector.d.ts +6 -0
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +54 -45
- package/dist/Selector/SelectorOption.js +3 -3
- package/dist/SideNav/SideNav.d.ts.map +1 -1
- package/dist/SideNav/SideNav.js +38 -34
- package/dist/SideNav/SideNavCollapseButton.d.ts +1 -1
- package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
- package/dist/SideNav/SideNavCollapseButton.js +8 -6
- package/dist/SideNav/SideNavHeading.js +87 -87
- package/dist/SideNav/SideNavItem.js +42 -42
- package/dist/SideNav/SideNavSection.d.ts +1 -1
- package/dist/SideNav/SideNavSection.d.ts.map +1 -1
- package/dist/SideNav/SideNavSection.js +18 -16
- package/dist/Skeleton/Skeleton.js +3 -3
- package/dist/Slider/Slider.d.ts +6 -0
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +31 -22
- package/dist/Spinner/Spinner.d.ts.map +1 -1
- package/dist/Spinner/Spinner.js +10 -10
- package/dist/StatusDot/StatusDot.js +5 -5
- package/dist/Switch/Switch.d.ts +13 -4
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +41 -30
- package/dist/TabList/Tab.js +18 -18
- package/dist/TabList/TabList.js +5 -5
- package/dist/TabList/TabMenu.d.ts.map +1 -1
- package/dist/TabList/TabMenu.js +57 -30
- package/dist/TabList/tab.markers.stylex.d.ts +1 -1
- package/dist/Table/BaseTable.d.ts.map +1 -1
- package/dist/Table/BaseTable.js +51 -39
- package/dist/Table/Table.js +7 -7
- package/dist/Table/TableBody.d.ts +1 -1
- package/dist/Table/TableBody.d.ts.map +1 -1
- package/dist/Table/TableBody.js +9 -5
- package/dist/Table/TableCell.d.ts.map +1 -1
- package/dist/Table/TableCell.js +76 -7
- package/dist/Table/TableFooter.d.ts +1 -1
- package/dist/Table/TableFooter.d.ts.map +1 -1
- package/dist/Table/TableFooter.js +9 -5
- package/dist/Table/TableHeader.d.ts +1 -1
- package/dist/Table/TableHeader.d.ts.map +1 -1
- package/dist/Table/TableHeader.js +9 -5
- package/dist/Table/TableHeaderCell.js +3 -3
- package/dist/Table/TableRow.js +5 -5
- package/dist/Table/index.d.ts +2 -0
- package/dist/Table/index.d.ts.map +1 -1
- package/dist/Table/index.js +1 -0
- package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
- package/dist/Table/plugins/columnResize/useTableColumnResize.js +14 -11
- package/dist/Table/plugins/filtering/useTableFiltering.js +71 -71
- package/dist/Table/plugins/pagination/paginateData.d.ts.map +1 -1
- package/dist/Table/plugins/pagination/paginateData.js +5 -1
- package/dist/Table/plugins/pagination/useTablePagination.js +7 -7
- 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/selection/useTableSelection.js +18 -18
- package/dist/Table/plugins/selection/useTableSelectionState.d.ts.map +1 -1
- package/dist/Table/plugins/selection/useTableSelectionState.js +11 -1
- package/dist/Table/plugins/sortable/useTableSortable.js +17 -17
- package/dist/Table/plugins/sortable/useTableSortableState.d.ts.map +1 -1
- package/dist/Table/plugins/sortable/useTableSortableState.js +8 -4
- package/dist/Table/tableContextMenu.d.ts +5 -1
- package/dist/Table/tableContextMenu.d.ts.map +1 -1
- package/dist/Table/tableContextMenu.js +19 -12
- package/dist/Text/Text.d.ts +1 -1
- package/dist/Text/Text.d.ts.map +1 -1
- package/dist/Text/Text.js +14 -13
- package/dist/Text/text.stylex.d.ts +35 -0
- package/dist/Text/text.stylex.d.ts.map +1 -1
- package/dist/Text/text.stylex.js +52 -1
- package/dist/TextArea/TextArea.js +14 -14
- package/dist/TextInput/TextInput.js +15 -15
- package/dist/Thumbnail/Thumbnail.d.ts +3 -2
- package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
- package/dist/Thumbnail/Thumbnail.js +30 -29
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +26 -21
- package/dist/Timestamp/Timestamp.d.ts +1 -1
- package/dist/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +37 -26
- package/dist/Toast/Toast.d.ts.map +1 -1
- package/dist/Toast/Toast.js +25 -17
- package/dist/Toast/ToastViewport.d.ts.map +1 -1
- package/dist/Toast/ToastViewport.js +23 -11
- package/dist/Toast/useToast.js +4 -4
- package/dist/ToggleButton/ToggleButton.js +12 -12
- package/dist/ToggleButton/ToggleButtonGroup.js +5 -5
- package/dist/Token/Token.js +21 -21
- package/dist/Tokenizer/Tokenizer.d.ts +6 -1
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +38 -29
- package/dist/Toolbar/Toolbar.js +18 -18
- package/dist/Tooltip/Tooltip.js +11 -11
- package/dist/Tooltip/useTooltip.js +3 -3
- package/dist/TopNav/TopNav.js +32 -32
- package/dist/TopNav/TopNavHeading.js +67 -67
- package/dist/TopNav/TopNavItem.js +5 -5
- package/dist/TopNav/TopNavMegaMenu.js +30 -30
- package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts +1 -1
- package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts.map +1 -1
- package/dist/TopNav/TopNavMegaMenuFeaturedCard.js +25 -14
- package/dist/TopNav/TopNavMegaMenuItem.js +16 -16
- package/dist/TopNav/TopNavMenu.js +32 -32
- package/dist/TreeList/TreeList.js +8 -8
- package/dist/TreeList/TreeListBranches.js +11 -11
- package/dist/TreeList/TreeListItem.js +30 -30
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +23 -20
- package/dist/Typeahead/Typeahead.js +12 -12
- package/dist/Typeahead/TypeaheadItem.js +10 -10
- package/dist/VStack/VStack.js +3 -3
- package/dist/astryx.css +23 -0
- package/dist/astryx.umd.js +60 -58
- package/dist/astryx.umd.js.map +4 -4
- package/dist/docs-types.d.ts +13 -1
- package/dist/docs-types.d.ts.map +1 -1
- package/dist/hooks/focusableSelector.d.ts +1 -1
- package/dist/hooks/focusableSelector.d.ts.map +1 -1
- package/dist/hooks/focusableSelector.js +1 -1
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/useFocusTrap.d.ts +3 -0
- package/dist/hooks/useFocusTrap.d.ts.map +1 -1
- package/dist/hooks/useFocusTrap.js +38 -1
- package/dist/hooks/useHotkeys.d.ts +51 -0
- package/dist/hooks/useHotkeys.d.ts.map +1 -0
- package/dist/hooks/useHotkeys.js +160 -0
- package/dist/hooks/useInteractiveRole.d.ts +6 -2
- package/dist/hooks/useInteractiveRole.d.ts.map +1 -1
- package/dist/hooks/useInteractiveRole.js +6 -2
- package/dist/hooks/useKeyboardHint.js +9 -9
- package/dist/hooks/useStreamingText.d.ts +3 -1
- package/dist/hooks/useStreamingText.d.ts.map +1 -1
- package/dist/hooks/useStreamingText.js +14 -5
- package/dist/theme/MediaTheme.js +3 -3
- package/dist/theme/Theme.js +7 -7
- package/dist/theme/defineTheme.d.ts +1 -1
- package/dist/theme/defineTheme.d.ts.map +1 -1
- package/dist/theme/expandColorScale.d.ts.map +1 -1
- package/dist/theme/expandColorScale.js +10 -3
- package/dist/theme/hct.d.ts +0 -15
- package/dist/theme/hct.d.ts.map +1 -1
- package/dist/theme/hct.js +9 -9
- package/dist/theme/syntax/SyntaxTheme.js +5 -5
- package/dist/theme/tokens.d.ts +10 -2
- package/dist/theme/tokens.d.ts.map +1 -1
- package/dist/theme/tokens.js +220 -4
- package/dist/utils/color.d.ts +42 -0
- package/dist/utils/color.d.ts.map +1 -0
- package/dist/utils/color.js +150 -0
- package/dist/utils/composeEventHandlers.d.ts +30 -0
- package/dist/utils/composeEventHandlers.d.ts.map +1 -0
- package/dist/utils/composeEventHandlers.js +40 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +3 -1
- package/dist/utils/timeParser.d.ts.map +1 -1
- package/dist/utils/timeParser.js +8 -5
- package/package.json +3 -3
- package/src/AlertDialog/AlertDialog.tsx +2 -0
- package/src/AppShell/AppShell.tsx +2 -0
- package/src/AspectRatio/AspectRatio.doc.mjs +1 -1
- package/src/Avatar/Avatar.doc.mjs +13 -2
- package/src/Avatar/Avatar.test.tsx +32 -1
- package/src/Avatar/Avatar.tsx +12 -20
- package/src/Banner/Banner.doc.mjs +8 -0
- package/src/Banner/Banner.test.tsx +38 -0
- package/src/Banner/Banner.tsx +8 -1
- package/src/Button/Button.tsx +39 -6
- package/src/ButtonGroup/ButtonGroup.doc.mjs +1 -1
- package/src/Calendar/Calendar.doc.mjs +1 -1
- package/src/Calendar/Calendar.test.tsx +201 -17
- package/src/Calendar/Calendar.tsx +79 -26
- package/src/Calendar/dayCellUtils.test.ts +306 -1
- package/src/Calendar/dayCellUtils.ts +206 -13
- package/src/Calendar/styles.ts +12 -2
- package/src/Card/Card.doc.mjs +1 -1
- package/src/Card/Card.tsx +16 -6
- package/src/Carousel/Carousel.doc.mjs +12 -12
- package/src/Carousel/Carousel.test.tsx +13 -0
- package/src/Carousel/Carousel.tsx +1 -0
- package/src/Chat/Chat.doc.mjs +1 -1
- package/src/Chat/ChatComposerInput.test.tsx +24 -0
- package/src/Chat/ChatComposerInput.tsx +17 -1
- package/src/Chat/ChatDictationButton.test.tsx +43 -0
- package/src/Chat/ChatDictationButton.tsx +4 -4
- package/src/Chat/ChatLayoutScrollButton.test.tsx +33 -0
- package/src/Chat/ChatLayoutScrollButton.tsx +3 -1
- package/src/Chat/ChatMessageMetadata.test.tsx +32 -0
- package/src/Chat/ChatMessageMetadata.tsx +4 -6
- package/src/Chat/ChatSystemMessage.test.tsx +26 -11
- package/src/Chat/ChatSystemMessage.tsx +7 -7
- package/src/Chat/ChatTokenizedText.test.tsx +29 -16
- package/src/Chat/ChatTokenizedText.tsx +15 -8
- package/src/Chat/ChatToolCalls.test.tsx +55 -0
- package/src/Chat/ChatToolCalls.tsx +10 -12
- package/src/Chat/index.ts +1 -4
- package/src/Chat/useChatNewMessages.test.tsx +4 -4
- package/src/CheckboxInput/CheckboxInput.doc.mjs +12 -4
- package/src/CheckboxInput/CheckboxInput.test.tsx +103 -0
- package/src/CheckboxInput/CheckboxInput.tsx +13 -0
- package/src/CheckboxList/CheckboxList.doc.mjs +1 -1
- package/src/CheckboxList/CheckboxList.test.tsx +19 -0
- package/src/CheckboxList/CheckboxListItem.tsx +11 -2
- package/src/Citation/Citation.doc.mjs +5 -0
- package/src/ClickableCard/ClickableCard.tsx +45 -2
- package/src/Code/Code.test.tsx +54 -0
- package/src/Code/Code.tsx +48 -4
- package/src/Code/index.ts +1 -1
- package/src/CodeBlock/CodeBlock.doc.mjs +7 -2
- package/src/CodeBlock/CodeBlock.test.tsx +122 -3
- package/src/CodeBlock/CodeBlock.tsx +62 -4
- package/src/CodeBlock/index.ts +1 -1
- package/src/Collapsible/Collapsible.doc.mjs +8 -4
- package/src/Collapsible/Collapsible.test.tsx +405 -0
- package/src/Collapsible/Collapsible.tsx +86 -10
- package/src/Collapsible/CollapsibleGroup.doc.mjs +27 -3
- package/src/Collapsible/CollapsibleGroup.test.tsx +318 -0
- package/src/Collapsible/CollapsibleGroup.tsx +107 -9
- package/src/Collapsible/CollapsibleGroupContext.tsx +42 -2
- package/src/Collapsible/index.ts +4 -0
- package/src/Collapsible/useCollapsible.ts +20 -6
- package/src/CommandPalette/CommandPalette.tsx +5 -3
- package/src/CommandPalette/CommandPaletteEmpty.doc.mjs +5 -0
- package/src/CommandPalette/CommandPaletteEmpty.tsx +15 -1
- package/src/CommandPalette/CommandPaletteGroup.doc.mjs +10 -0
- package/src/CommandPalette/CommandPaletteInput.doc.mjs +6 -0
- package/src/CommandPalette/CommandPaletteItem.doc.mjs +6 -0
- package/src/CommandPalette/CommandPaletteList.doc.mjs +9 -0
- package/src/ContextMenu/ContextMenu.doc.mjs +15 -0
- package/src/ContextMenu/ContextMenu.test.tsx +15 -0
- package/src/ContextMenu/ContextMenu.tsx +19 -1
- package/src/ContextMenu/ContextMenuItem.doc.mjs +6 -0
- package/src/DateInput/DateInput.doc.mjs +6 -1
- package/src/DateInput/DateInput.test.tsx +11 -20
- package/src/DateRangeInput/DateRangeInput.doc.mjs +1 -1
- package/src/DateRangeInput/DateRangeInput.test.tsx +31 -44
- package/src/DateRangeInput/DateRangeInput.tsx +2 -2
- package/src/DateTimeInput/DateTimeInput.doc.mjs +4 -3
- package/src/DateTimeInput/DateTimeInput.test.tsx +118 -16
- package/src/DateTimeInput/DateTimeInput.tsx +9 -8
- package/src/DateTimeInput/index.ts +1 -0
- package/src/Dialog/DialogHeader.doc.mjs +45 -0
- package/src/Divider/Divider.tsx +1 -23
- package/src/DropdownMenu/DropdownMenu.doc.mjs +1 -1
- package/src/DropdownMenu/DropdownMenu.test.tsx +5 -3
- package/src/DropdownMenu/DropdownMenuItem.tsx +5 -17
- package/src/EmptyState/EmptyState.doc.mjs +1 -1
- package/src/Field/Field.doc.mjs +1 -1
- package/src/Field/FieldLabel.test.tsx +2 -2
- package/src/FieldStatus/FieldStatus.test.tsx +282 -0
- package/src/FileInput/FileInput.doc.mjs +1 -1
- package/src/FormLayout/__snapshots__/FormLayout.test.tsx.snap +0 -3
- package/src/Grid/Grid.doc.mjs +3 -3
- package/src/Grid/Grid.test.tsx +43 -18
- package/src/Grid/Grid.tsx +26 -9
- package/src/Icon/Icon.test.tsx +41 -29
- package/src/Icon/Icon.tsx +6 -2
- package/src/InputGroup/InputGroup.tsx +2 -2
- package/src/InteractiveRoleContext/InteractiveRoleContext.test.tsx +185 -0
- package/src/Item/Item.tsx +1 -1
- package/src/Layout/Layout.test.tsx +285 -0
- package/src/Layout/LayoutContent.doc.mjs +12 -0
- package/src/Layout/LayoutPanel.doc.mjs +40 -0
- package/src/Layout/LayoutSlots.test.tsx +364 -0
- package/src/Layout/__tests__/edgeCompensation.test.tsx +72 -0
- package/src/Lightbox/Lightbox.doc.mjs +5 -0
- package/src/Lightbox/Lightbox.test.tsx +123 -2
- package/src/Lightbox/Lightbox.tsx +29 -1
- package/src/Markdown/Markdown.test.tsx +23 -0
- package/src/Markdown/Markdown.tsx +9 -7
- package/src/Markdown/incremental.test.ts +36 -0
- package/src/Markdown/parser.perf.test.ts +34 -12
- package/src/Markdown/parser.test.ts +210 -0
- package/src/Markdown/parser.ts +301 -6
- package/src/MobileNav/MobileNav.doc.mjs +20 -0
- package/src/MultiSelector/MultiSelector.doc.mjs +14 -1
- package/src/MultiSelector/MultiSelector.test.tsx +33 -0
- package/src/MultiSelector/MultiSelector.tsx +20 -0
- package/src/NavMenu/NavMenu.doc.mjs +15 -0
- package/src/NumberInput/NumberInput.test.tsx +48 -3
- package/src/NumberInput/NumberInput.tsx +32 -15
- package/src/Outline/parseOutlineFromMarkdown.test.ts +80 -0
- package/src/OverflowList/OverflowList.test.tsx +416 -0
- package/src/Overlay/Overlay.doc.mjs +6 -0
- package/src/Overlay/Overlay.test.tsx +356 -0
- package/src/Pagination/Pagination.test.tsx +162 -0
- package/src/Pagination/Pagination.tsx +80 -26
- package/src/Popover/Popover.test.tsx +65 -0
- package/src/PowerSearch/PowerSearch.doc.mjs +4 -4
- package/src/PowerSearch/PowerSearch.test.tsx +109 -1
- package/src/PowerSearch/PowerSearch.tsx +37 -16
- package/src/ProgressBar/ProgressBar.test.tsx +30 -0
- package/src/ProgressBar/ProgressBar.tsx +12 -5
- package/src/RadioList/RadioList.doc.mjs +7 -1
- package/src/RadioList/RadioList.test.tsx +65 -0
- package/src/RadioList/RadioList.tsx +10 -1
- package/src/RadioList/RadioListItem.tsx +13 -4
- package/src/Resizable/ResizeHandle.test.tsx +218 -0
- package/src/Resizable/ResizeHandle.tsx +22 -4
- package/src/Section/Section.test.tsx +4 -10
- package/src/SegmentedControl/SegmentedControl.doc.mjs +2 -2
- package/src/SegmentedControl/SegmentedControl.test.tsx +192 -0
- package/src/SegmentedControl/SegmentedControl.tsx +27 -5
- package/src/SegmentedControl/SegmentedControlItem.tsx +9 -4
- package/src/SelectableCard/SelectableCard.doc.mjs +1 -1
- package/src/Selector/Selector.doc.mjs +12 -1
- package/src/Selector/Selector.test.tsx +30 -0
- package/src/Selector/Selector.tsx +18 -0
- package/src/SideNav/SideNav.doc.mjs +7 -1
- package/src/SideNav/SideNav.test.tsx +66 -0
- package/src/SideNav/SideNav.tsx +6 -2
- package/src/SideNav/SideNavCollapseButton.tsx +4 -3
- package/src/SideNav/SideNavSection.tsx +6 -4
- package/src/SizeContext/SizeContext.test.tsx +226 -0
- package/src/Slider/Slider.doc.mjs +14 -2
- package/src/Slider/Slider.test.tsx +30 -0
- package/src/Slider/Slider.tsx +20 -0
- package/src/Spinner/Spinner.tsx +1 -0
- package/src/Switch/Switch.doc.mjs +21 -9
- package/src/Switch/Switch.test.tsx +137 -0
- package/src/Switch/Switch.tsx +32 -7
- package/src/TabList/TabList.doc.mjs +3 -3
- package/src/TabList/TabList.test.tsx +185 -1
- package/src/TabList/TabMenu.tsx +45 -9
- package/src/Table/BaseTable.tsx +16 -3
- package/src/Table/Table.test.tsx +87 -0
- package/src/Table/TableBody.tsx +15 -2
- package/src/Table/TableCell.tsx +87 -8
- package/src/Table/TableFooter.tsx +15 -2
- package/src/Table/TableHeader.tsx +15 -2
- package/src/Table/index.ts +5 -0
- package/src/Table/plugins/columnResize/useTableColumnResize.test.tsx +13 -0
- package/src/Table/plugins/columnResize/useTableColumnResize.tsx +3 -1
- package/src/Table/plugins/pagination/paginateData.ts +5 -1
- package/src/Table/plugins/pagination/useTablePagination.test.tsx +13 -0
- 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/selection/useTableSelectionState.test.tsx +23 -0
- package/src/Table/plugins/selection/useTableSelectionState.tsx +11 -6
- package/src/Table/plugins/sortable/useTableSortableState.test.tsx +35 -1
- package/src/Table/plugins/sortable/useTableSortableState.tsx +8 -4
- package/src/Table/tableContextMenu.test.tsx +27 -3
- package/src/Table/tableContextMenu.tsx +20 -2
- package/src/Table/useTablePagination.doc.mjs +4 -1
- package/src/Table/useTableRowExpansion.doc.mjs +80 -0
- package/src/Table/useTableSortable.doc.mjs +4 -1
- package/src/Text/Text.doc.mjs +2 -2
- package/src/Text/Text.test.tsx +11 -0
- package/src/Text/Text.tsx +4 -2
- package/src/Text/text.stylex.ts +41 -0
- package/src/TextArea/TextArea.doc.mjs +1 -1
- package/src/TextArea/TextArea.test.tsx +3 -3
- package/src/TextInput/TextInput.doc.mjs +1 -1
- package/src/TextInput/TextInput.test.tsx +3 -3
- package/src/Thumbnail/Thumbnail.test.tsx +36 -2
- package/src/Thumbnail/Thumbnail.tsx +4 -2
- package/src/TimeInput/TimeInput.doc.mjs +11 -6
- package/src/TimeInput/TimeInput.test.tsx +37 -0
- package/src/TimeInput/TimeInput.tsx +11 -1
- package/src/Timestamp/Timestamp.doc.mjs +1 -1
- package/src/Timestamp/Timestamp.test.tsx +52 -0
- package/src/Timestamp/Timestamp.tsx +30 -16
- package/src/Toast/Toast.tsx +11 -3
- package/src/Toast/ToastViewport.test.tsx +64 -0
- package/src/Toast/ToastViewport.tsx +12 -0
- package/src/ToggleButton/ToggleButton.doc.mjs +1 -0
- package/src/Tokenizer/Tokenizer.doc.mjs +16 -4
- package/src/Tokenizer/Tokenizer.test.tsx +33 -0
- package/src/Tokenizer/Tokenizer.tsx +19 -0
- package/src/Toolbar/Toolbar.test.tsx +1 -1
- package/src/TopNav/TopNav.doc.mjs +1 -1
- package/src/TopNav/TopNav.test.tsx +18 -0
- package/src/TopNav/TopNavMegaMenuFeaturedCard.tsx +9 -2
- package/src/TreeList/TreeList.doc.mjs +2 -2
- package/src/Typeahead/BaseTypeahead.doc.mjs +19 -0
- package/src/Typeahead/BaseTypeahead.tsx +5 -2
- package/src/Typeahead/Typeahead.doc.mjs +7 -2
- package/src/Typeahead/Typeahead.test.tsx +45 -1
- package/src/__tests__/TestIcon.tsx +26 -0
- package/src/__tests__/fastRoleQueries.ts +66 -0
- package/src/docPropReferences.test.ts +178 -0
- package/src/docs-types.ts +14 -0
- package/src/hooks/focusableSelector.ts +1 -1
- package/src/hooks/index.ts +3 -0
- package/src/hooks/useFocusTrap.doc.mjs +4 -2
- package/src/hooks/useFocusTrap.test.tsx +149 -1
- package/src/hooks/useFocusTrap.ts +50 -1
- package/src/hooks/useHotkeys.doc.mjs +52 -0
- package/src/hooks/useHotkeys.test.ts +245 -0
- package/src/hooks/useHotkeys.ts +203 -0
- package/src/hooks/useInteractiveRole.ts +12 -4
- package/src/hooks/useKeyboardHint.doc.mjs +6 -6
- package/src/hooks/useStreamingText.test.ts +54 -19
- package/src/hooks/useStreamingText.ts +16 -5
- package/src/theme/SyntaxTheme.doc.mjs +4 -4
- package/src/theme/defineTheme.ts +4 -13
- package/src/theme/derivedVarRegistry.test.ts +2 -2
- package/src/theme/expandColorScale.test.ts +29 -0
- package/src/theme/expandColorScale.ts +11 -6
- package/src/theme/hct.ts +9 -17
- package/src/theme/tokens.test.ts +182 -9
- package/src/theme/tokens.ts +239 -4
- package/src/theme/useTheme.test.tsx +20 -0
- package/src/utils/color.test.ts +133 -0
- package/src/utils/color.ts +148 -0
- package/src/utils/composeEventHandlers.test.ts +71 -0
- package/src/utils/composeEventHandlers.ts +44 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/mergeProps.test.ts +166 -0
- package/src/utils/sharedResizeObserver.test.ts +2 -2
- package/src/utils/timeParser.test.ts +13 -0
- package/src/utils/timeParser.ts +8 -5
|
@@ -168,14 +168,18 @@ function defaultCompare<T extends Record<string, unknown>>(
|
|
|
168
168
|
const aVal = a[sortKey];
|
|
169
169
|
const bVal = b[sortKey];
|
|
170
170
|
|
|
171
|
-
// null/undefined sort to the end
|
|
172
|
-
|
|
171
|
+
// null/undefined/NaN sort to the end. NaN must not reach the numeric fast
|
|
172
|
+
// path: a NaN comparator result reads as "equal" to Array.sort, which makes
|
|
173
|
+
// the comparator inconsistent and corrupts the order of the other rows.
|
|
174
|
+
const aMissing = aVal == null || (typeof aVal === 'number' && Number.isNaN(aVal));
|
|
175
|
+
const bMissing = bVal == null || (typeof bVal === 'number' && Number.isNaN(bVal));
|
|
176
|
+
if (aMissing && bMissing) {
|
|
173
177
|
return 0;
|
|
174
178
|
}
|
|
175
|
-
if (
|
|
179
|
+
if (aMissing) {
|
|
176
180
|
return 1;
|
|
177
181
|
}
|
|
178
|
-
if (
|
|
182
|
+
if (bMissing) {
|
|
179
183
|
return -1;
|
|
180
184
|
}
|
|
181
185
|
|
|
@@ -99,9 +99,7 @@ describe('Table header context menu', () => {
|
|
|
99
99
|
],
|
|
100
100
|
}),
|
|
101
101
|
};
|
|
102
|
-
render(
|
|
103
|
-
<Table data={data} columns={columns} idKey="id" plugins={{a, b}} />,
|
|
104
|
-
);
|
|
102
|
+
render(<Table data={data} columns={columns} idKey="id" plugins={{a, b}} />);
|
|
105
103
|
fireEvent.contextMenu(screen.getByText('Name'));
|
|
106
104
|
expect(
|
|
107
105
|
screen.getAllByRole('menuitem', {name: 'Action A', hidden: true}).length,
|
|
@@ -154,4 +152,30 @@ describe('Table body context menu', () => {
|
|
|
154
152
|
fireEvent.click(items[0]);
|
|
155
153
|
expect(onSelect).toHaveBeenCalledWith('1');
|
|
156
154
|
});
|
|
155
|
+
|
|
156
|
+
it('trigger wrapper fills the full cell so the whole cell is right-clickable', () => {
|
|
157
|
+
const plugin: TablePlugin<Row> = {
|
|
158
|
+
transformBodyCell: props => ({
|
|
159
|
+
...props,
|
|
160
|
+
contextMenuActions: [{id: 'act', label: 'Act', onSelect: () => {}}],
|
|
161
|
+
}),
|
|
162
|
+
};
|
|
163
|
+
render(
|
|
164
|
+
<Table data={data} columns={columns} idKey="id" plugins={{plugin}} />,
|
|
165
|
+
);
|
|
166
|
+
// The context-menu trigger wraps the cell content. It must fill the cell
|
|
167
|
+
// (block display + 100% width) so right-clicking anywhere in the cell —
|
|
168
|
+
// not just on the content — opens the menu. Regression test for the bug
|
|
169
|
+
// where only the wide first column responded to right-click.
|
|
170
|
+
const alice = screen.getByText('Alice');
|
|
171
|
+
const trigger = alice.closest('div');
|
|
172
|
+
expect(trigger).not.toBeNull();
|
|
173
|
+
expect(trigger?.className).toBeTruthy();
|
|
174
|
+
// The fillCell style sets inline-size:100% + display:block on the trigger.
|
|
175
|
+
const styleAttr = trigger?.getAttribute('class') ?? '';
|
|
176
|
+
// StyleX compiles to atomic classes; just assert the wrapper carries styles
|
|
177
|
+
// (the visual fill is covered by the compiled CSS). The key contract is
|
|
178
|
+
// that the trigger is a styled block wrapper, not a bare inline element.
|
|
179
|
+
expect(styleAttr.length).toBeGreaterThan(0);
|
|
180
|
+
});
|
|
157
181
|
});
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
import {useState, type ReactNode} from 'react';
|
|
17
17
|
import {ContextMenu, type ContextMenuOption} from '../ContextMenu';
|
|
18
18
|
import {Icon} from '../Icon';
|
|
19
|
+
import type {StyleXStyles} from '../theme/types';
|
|
19
20
|
import type {TableContextAction, TableContextActions} from './types';
|
|
20
21
|
|
|
21
22
|
/**
|
|
@@ -99,14 +100,17 @@ function toContextMenuOptions(
|
|
|
99
100
|
function LazyTableContextMenu({
|
|
100
101
|
element,
|
|
101
102
|
getActions,
|
|
103
|
+
triggerXstyle,
|
|
102
104
|
}: {
|
|
103
105
|
element: ReactNode;
|
|
104
106
|
getActions: () => TableContextAction[];
|
|
107
|
+
triggerXstyle?: StyleXStyles | StyleXStyles[];
|
|
105
108
|
}): ReactNode {
|
|
106
109
|
const [options, setOptions] = useState<ContextMenuOption[] | null>(null);
|
|
107
110
|
return (
|
|
108
111
|
<ContextMenu
|
|
109
112
|
items={options ?? []}
|
|
113
|
+
triggerXstyle={triggerXstyle}
|
|
110
114
|
onOpenChange={open => {
|
|
111
115
|
// Resolve actions when opening; clear on close so state derived later
|
|
112
116
|
// (e.g. current sort direction) is always fresh next open.
|
|
@@ -122,14 +126,24 @@ function LazyTableContextMenu({
|
|
|
122
126
|
* context menu rendering the aggregated `actions`. Accepts a static array or a
|
|
123
127
|
* getter (resolved lazily on open). When there are no actions the element is
|
|
124
128
|
* returned untouched so the native browser menu passes through.
|
|
129
|
+
*
|
|
130
|
+
* `triggerXstyle` styles the right-click target wrapper. Cells pass a fill +
|
|
131
|
+
* padding style so the entire cell (padding included) opens the menu.
|
|
125
132
|
*/
|
|
126
133
|
export function wrapInTableContextMenu(
|
|
127
134
|
element: ReactNode,
|
|
128
135
|
actions: TableContextActions | undefined,
|
|
136
|
+
triggerXstyle?: StyleXStyles | StyleXStyles[],
|
|
129
137
|
): ReactNode {
|
|
130
138
|
// Getter form → resolve lazily on open.
|
|
131
139
|
if (typeof actions === 'function') {
|
|
132
|
-
return
|
|
140
|
+
return (
|
|
141
|
+
<LazyTableContextMenu
|
|
142
|
+
element={element}
|
|
143
|
+
getActions={actions}
|
|
144
|
+
triggerXstyle={triggerXstyle}
|
|
145
|
+
/>
|
|
146
|
+
);
|
|
133
147
|
}
|
|
134
148
|
if (!actions || actions.length === 0) {
|
|
135
149
|
return element;
|
|
@@ -137,6 +151,10 @@ export function wrapInTableContextMenu(
|
|
|
137
151
|
// item (it looked like "ascending" was always selected). Focus moves only
|
|
138
152
|
// when the user arrow-keys into the menu.
|
|
139
153
|
return (
|
|
140
|
-
<ContextMenu
|
|
154
|
+
<ContextMenu
|
|
155
|
+
items={toContextMenuOptions(actions)}
|
|
156
|
+
triggerXstyle={triggerXstyle}>
|
|
157
|
+
{element}
|
|
158
|
+
</ContextMenu>
|
|
141
159
|
);
|
|
142
160
|
}
|
|
@@ -6,7 +6,10 @@ export const docs = {
|
|
|
6
6
|
name: 'useTablePagination',
|
|
7
7
|
subComponentOf: 'Table',
|
|
8
8
|
displayName: 'useTablePagination',
|
|
9
|
-
description: 'Headless pagination plugin for Table.
|
|
9
|
+
description: 'Headless pagination plugin for Table. Call with a config object: `useTablePagination({ page, onPageChange, totalItems })`. Returns a TablePlugin to pass to `<Table plugins={{ pagination: paginationPlugin }} />`.',
|
|
10
|
+
usage: {
|
|
11
|
+
description: 'Call useTablePagination with a config object containing page state and callback. Pass the returned plugin to Table via the plugins prop.',
|
|
12
|
+
},
|
|
10
13
|
props: [
|
|
11
14
|
{
|
|
12
15
|
name: 'page',
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/** @type {import('../docs-types').ComponentDoc} */
|
|
4
|
+
|
|
5
|
+
export const docs = {
|
|
6
|
+
name: 'useTableRowExpansion',
|
|
7
|
+
subComponentOf: 'Table',
|
|
8
|
+
displayName: 'useTableRowExpansion',
|
|
9
|
+
description:
|
|
10
|
+
'Hook that returns a TablePlugin implementing expandable rows with inherited columns. Child rows use the same columns as their parents, indented by depth. Clicking the chevron (or right-click context menu) toggles expansion. Pair with useTableRowExpansionState, which flattens the tree and derives this config (expand/collapse handlers + expand-all state) from a single expandedKeys set.',
|
|
11
|
+
props: [
|
|
12
|
+
{
|
|
13
|
+
name: 'expandedKeys',
|
|
14
|
+
type: 'Set<string>',
|
|
15
|
+
description: 'Set of currently-expanded row keys.',
|
|
16
|
+
required: true,
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: 'onToggle',
|
|
20
|
+
type: '(key: string) => void',
|
|
21
|
+
description: 'Called when a row expansion is toggled.',
|
|
22
|
+
required: true,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: 'getRowKey',
|
|
26
|
+
type: '(item: T) => string',
|
|
27
|
+
description: 'Derive a stable unique key from a row item.',
|
|
28
|
+
required: true,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: 'getChildren',
|
|
32
|
+
type: '(item: T) => T[]',
|
|
33
|
+
description: 'Return the children of a row (determines expandability).',
|
|
34
|
+
required: true,
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: 'getDepth',
|
|
38
|
+
type: '(item: T) => number',
|
|
39
|
+
description: 'Return the depth of a row in the hierarchy (0 = top-level). Used for indentation.',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: 'getIsItemExpandable',
|
|
43
|
+
type: '(item: T) => boolean',
|
|
44
|
+
description: 'Control which rows are expandable. Defaults to checking getChildren length.',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'hasRowClickExpansion',
|
|
48
|
+
type: 'boolean',
|
|
49
|
+
description: 'When true, clicking anywhere on the row toggles expansion.',
|
|
50
|
+
default: 'false',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: 'isAllExpanded',
|
|
54
|
+
type: "boolean | 'indeterminate'",
|
|
55
|
+
description: 'State of the expand-all toggle in the header. Enables the header toggle button.',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: 'onToggleExpandAll',
|
|
59
|
+
type: '(expand: boolean) => void',
|
|
60
|
+
description: 'Callback when the expand-all header toggle is clicked.',
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/** @type {import('../docs-types').TranslationDoc} */
|
|
66
|
+
export const docsDense = {
|
|
67
|
+
description:
|
|
68
|
+
'Returns a TablePlugin for expandable rows w/ inherited columns. Child rows reuse parent columns, indented by depth. Chevron click (or right-click menu) toggles expansion. Pair w/ useTableRowExpansionState, which flattens the tree + derives this config from one expandedKeys set.',
|
|
69
|
+
propDescriptions: {
|
|
70
|
+
expandedKeys: 'Set of currently-expanded row keys.',
|
|
71
|
+
onToggle: 'Called when a row expansion is toggled.',
|
|
72
|
+
getRowKey: 'Derive a stable unique key from a row item.',
|
|
73
|
+
getChildren: 'Return children of a row; determines expandability.',
|
|
74
|
+
getDepth: 'Return depth of a row (0 = top-level). Used for indentation.',
|
|
75
|
+
getIsItemExpandable: 'Control which rows are expandable. Defaults to checking getChildren length.',
|
|
76
|
+
hasRowClickExpansion: 'If true, clicking anywhere on the row toggles expansion. Default false.',
|
|
77
|
+
isAllExpanded: 'State of the expand-all header toggle. Enables the header toggle button.',
|
|
78
|
+
onToggleExpandAll: 'Callback when the expand-all header toggle is clicked.',
|
|
79
|
+
},
|
|
80
|
+
};
|
|
@@ -6,7 +6,10 @@ export const docs = {
|
|
|
6
6
|
name: 'useTableSortable',
|
|
7
7
|
subComponentOf: 'Table',
|
|
8
8
|
displayName: 'useTableSortable',
|
|
9
|
-
description: 'Headless multi-sort plugin for Table.
|
|
9
|
+
description: 'Headless multi-sort plugin for Table. Call with a config object: `useTableSortable({ sort, onSortChange })`. Returns a TablePlugin to pass to `<Table plugins={{ sort: sortPlugin }} />`.',
|
|
10
|
+
usage: {
|
|
11
|
+
description: 'Call useTableSortable with a config object containing sort state and callback. Pass the returned plugin to Table via the plugins prop.',
|
|
12
|
+
},
|
|
10
13
|
props: [
|
|
11
14
|
{
|
|
12
15
|
name: 'sort',
|
package/src/Text/Text.doc.mjs
CHANGED
|
@@ -16,7 +16,7 @@ export const docs = {
|
|
|
16
16
|
theming: {
|
|
17
17
|
targets: [
|
|
18
18
|
{className: 'astryx-heading', visualProps: ['level', 'color']},
|
|
19
|
-
{className: 'astryx-text', visualProps: ['type', 'color']},
|
|
19
|
+
{className: 'astryx-text', visualProps: ['type', 'size', 'color']},
|
|
20
20
|
],
|
|
21
21
|
},
|
|
22
22
|
description: 'Semantic body text component that renders text with type-based styling from the theme, with optional truncation, decoration, and layout props.',
|
|
@@ -174,4 +174,4 @@ export const docsDense = {
|
|
|
174
174
|
{ guidance: false, description: 'Text for headings: use Heading with level (1\u20136).' },
|
|
175
175
|
],
|
|
176
176
|
},
|
|
177
|
-
};
|
|
177
|
+
};
|
package/src/Text/Text.test.tsx
CHANGED
|
@@ -114,6 +114,17 @@ describe('Text', () => {
|
|
|
114
114
|
expect(screen.getByText('Bold text')).toBeInTheDocument();
|
|
115
115
|
});
|
|
116
116
|
|
|
117
|
+
it('reflects explicit size overrides for styling and theming', () => {
|
|
118
|
+
render(
|
|
119
|
+
<Text type="code" size="2xs">
|
|
120
|
+
Tiny code
|
|
121
|
+
</Text>,
|
|
122
|
+
);
|
|
123
|
+
const element = screen.getByText('Tiny code');
|
|
124
|
+
expect(element).toHaveAttribute('data-size', '2xs');
|
|
125
|
+
expect(element.className).toContain('size-2xs');
|
|
126
|
+
});
|
|
127
|
+
|
|
117
128
|
it('accepts display prop', () => {
|
|
118
129
|
render(
|
|
119
130
|
<Text type="body" display="block">
|
package/src/Text/Text.tsx
CHANGED
|
@@ -32,6 +32,7 @@ import type {
|
|
|
32
32
|
import {
|
|
33
33
|
colorStyles,
|
|
34
34
|
defaultWeightByTypeStyles,
|
|
35
|
+
sizeStyles,
|
|
35
36
|
sizeByTypeStyles,
|
|
36
37
|
weightStyles,
|
|
37
38
|
displayStyles,
|
|
@@ -201,7 +202,7 @@ function resolveStyleType(type: TextType): BuiltinTextType {
|
|
|
201
202
|
*/
|
|
202
203
|
export function Text({
|
|
203
204
|
type = 'body',
|
|
204
|
-
size
|
|
205
|
+
size,
|
|
205
206
|
color,
|
|
206
207
|
weight,
|
|
207
208
|
display = 'inline',
|
|
@@ -254,10 +255,11 @@ export function Text({
|
|
|
254
255
|
<Component
|
|
255
256
|
ref={mergeRefs(ref, truncation.ref, textRef)}
|
|
256
257
|
{...mergeProps(
|
|
257
|
-
themeProps('text', {type, color: resolvedColor}),
|
|
258
|
+
themeProps('text', {type, size, color: resolvedColor}),
|
|
258
259
|
stylex.props(
|
|
259
260
|
colorStyles[resolvedColor],
|
|
260
261
|
sizeByTypeStyles[styleType],
|
|
262
|
+
size && sizeStyles[size],
|
|
261
263
|
defaultWeightByTypeStyles[styleType],
|
|
262
264
|
weight && weightStyles[weight],
|
|
263
265
|
// Display: use truncation styles when maxLines > 0
|
package/src/Text/text.stylex.ts
CHANGED
|
@@ -14,6 +14,7 @@ import * as stylex from '@stylexjs/stylex';
|
|
|
14
14
|
import {
|
|
15
15
|
colorVars,
|
|
16
16
|
fontWeightVars,
|
|
17
|
+
textSizeVars,
|
|
17
18
|
typeScaleVars,
|
|
18
19
|
typographyVars,
|
|
19
20
|
} from '../theme/tokens.stylex';
|
|
@@ -145,6 +146,46 @@ export const sizeByTypeStyles = stylex.create({
|
|
|
145
146
|
},
|
|
146
147
|
});
|
|
147
148
|
|
|
149
|
+
// =============================================================================
|
|
150
|
+
// Explicit Size Override
|
|
151
|
+
// =============================================================================
|
|
152
|
+
|
|
153
|
+
export const sizeStyles = stylex.create({
|
|
154
|
+
'4xs': {
|
|
155
|
+
fontSize: textSizeVars['--font-size-4xs'],
|
|
156
|
+
},
|
|
157
|
+
'3xs': {
|
|
158
|
+
fontSize: textSizeVars['--font-size-3xs'],
|
|
159
|
+
},
|
|
160
|
+
'2xs': {
|
|
161
|
+
fontSize: textSizeVars['--font-size-2xs'],
|
|
162
|
+
},
|
|
163
|
+
xsm: {
|
|
164
|
+
fontSize: textSizeVars['--font-size-xs'],
|
|
165
|
+
},
|
|
166
|
+
sm: {
|
|
167
|
+
fontSize: textSizeVars['--font-size-sm'],
|
|
168
|
+
},
|
|
169
|
+
base: {
|
|
170
|
+
fontSize: textSizeVars['--font-size-base'],
|
|
171
|
+
},
|
|
172
|
+
lg: {
|
|
173
|
+
fontSize: textSizeVars['--font-size-lg'],
|
|
174
|
+
},
|
|
175
|
+
xl: {
|
|
176
|
+
fontSize: textSizeVars['--font-size-xl'],
|
|
177
|
+
},
|
|
178
|
+
'2xl': {
|
|
179
|
+
fontSize: textSizeVars['--font-size-2xl'],
|
|
180
|
+
},
|
|
181
|
+
'3xl': {
|
|
182
|
+
fontSize: textSizeVars['--font-size-3xl'],
|
|
183
|
+
},
|
|
184
|
+
'4xl': {
|
|
185
|
+
fontSize: textSizeVars['--font-size-4xl'],
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
|
|
148
189
|
// =============================================================================
|
|
149
190
|
// Baseline Size/Leading by Heading Level (from type-scale tokens)
|
|
150
191
|
//
|
|
@@ -74,7 +74,7 @@ export const docs = {
|
|
|
74
74
|
name: 'disabledMessage',
|
|
75
75
|
type: 'string',
|
|
76
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
|
|
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
78
|
},
|
|
79
79
|
{
|
|
80
80
|
name: 'isLoading',
|
|
@@ -13,7 +13,7 @@ import {useState} from 'react';
|
|
|
13
13
|
import {describe, it, expect, vi, beforeEach} from 'vitest';
|
|
14
14
|
import {render, screen, fireEvent, waitFor} from '@testing-library/react';
|
|
15
15
|
import userEvent from '@testing-library/user-event';
|
|
16
|
-
import {
|
|
16
|
+
import {TestIcon} from '../__tests__/TestIcon';
|
|
17
17
|
import {TextArea} from './TextArea';
|
|
18
18
|
|
|
19
19
|
// Mock showPopover/hidePopover since jsdom does not implement them. Used by the
|
|
@@ -193,7 +193,7 @@ describe('TextArea', () => {
|
|
|
193
193
|
label="Description"
|
|
194
194
|
value=""
|
|
195
195
|
onChange={() => {}}
|
|
196
|
-
startIcon={
|
|
196
|
+
startIcon={TestIcon}
|
|
197
197
|
/>,
|
|
198
198
|
);
|
|
199
199
|
expect(screen.getByRole('textbox')).toBeInTheDocument();
|
|
@@ -577,7 +577,7 @@ describe('TextArea', () => {
|
|
|
577
577
|
label="Notes"
|
|
578
578
|
value=""
|
|
579
579
|
onChange={() => {}}
|
|
580
|
-
startIcon={<
|
|
580
|
+
startIcon={<TestIcon />}
|
|
581
581
|
/>,
|
|
582
582
|
);
|
|
583
583
|
|
|
@@ -82,7 +82,7 @@ export const docs = {
|
|
|
82
82
|
name: 'disabledMessage',
|
|
83
83
|
type: 'string',
|
|
84
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
|
|
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
86
|
},
|
|
87
87
|
{
|
|
88
88
|
name: 'isLoading',
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import {describe, it, expect, vi, beforeEach} from 'vitest';
|
|
13
13
|
import {render, screen, fireEvent, waitFor} from '@testing-library/react';
|
|
14
14
|
import userEvent from '@testing-library/user-event';
|
|
15
|
-
import {
|
|
15
|
+
import {TestIcon} from '../__tests__/TestIcon';
|
|
16
16
|
import {TextInput} from './TextInput';
|
|
17
17
|
|
|
18
18
|
// Mock showPopover/hidePopover since jsdom does not implement them. Used by the
|
|
@@ -163,7 +163,7 @@ describe('TextInput', () => {
|
|
|
163
163
|
label="Search"
|
|
164
164
|
value=""
|
|
165
165
|
onChange={() => {}}
|
|
166
|
-
startIcon={
|
|
166
|
+
startIcon={TestIcon}
|
|
167
167
|
/>,
|
|
168
168
|
);
|
|
169
169
|
expect(screen.getByRole('textbox')).toBeInTheDocument();
|
|
@@ -482,7 +482,7 @@ describe('TextInput', () => {
|
|
|
482
482
|
label="Search"
|
|
483
483
|
value=""
|
|
484
484
|
onChange={() => {}}
|
|
485
|
-
startIcon={<
|
|
485
|
+
startIcon={<TestIcon />}
|
|
486
486
|
/>,
|
|
487
487
|
);
|
|
488
488
|
|
|
@@ -37,11 +37,45 @@ describe('Thumbnail', () => {
|
|
|
37
37
|
expect(screen.getByRole('status')).toBeInTheDocument();
|
|
38
38
|
});
|
|
39
39
|
|
|
40
|
-
it('
|
|
40
|
+
it('exposes the label as an accessible name via a valid group role', () => {
|
|
41
41
|
render(<Thumbnail label="photo.png" data-testid="thumb" />);
|
|
42
|
-
|
|
42
|
+
// The accessible name must be carried by a valid named role (group),
|
|
43
|
+
// not by a bare aria-label on a generic div (aria-prohibited-attr).
|
|
44
|
+
const group = screen.getByRole('group', {name: 'photo.png'});
|
|
45
|
+
expect(group).toBe(screen.getByTestId('thumb'));
|
|
43
46
|
});
|
|
44
47
|
|
|
48
|
+
it('does not put aria-label on a generic (roleless) element', () => {
|
|
49
|
+
render(<Thumbnail label="photo.png" data-testid="thumb" />);
|
|
50
|
+
const thumb = screen.getByTestId('thumb');
|
|
51
|
+
// The labeled element must declare a role so the name is legitimate.
|
|
52
|
+
expect(thumb).toHaveAttribute('role', 'group');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('keeps interactive children accessible while exposing the group name', () => {
|
|
56
|
+
const onRemove = vi.fn();
|
|
57
|
+
render(
|
|
58
|
+
<Thumbnail
|
|
59
|
+
src="/img.jpg"
|
|
60
|
+
alt="Clickable"
|
|
61
|
+
label="file.png"
|
|
62
|
+
onClick={vi.fn()}
|
|
63
|
+
onRemove={onRemove}
|
|
64
|
+
/>,
|
|
65
|
+
);
|
|
66
|
+
// A group role (unlike img) must not hide descendant controls.
|
|
67
|
+
expect(
|
|
68
|
+
screen.getByRole('group', {name: 'file.png — Clickable'}),
|
|
69
|
+
).toBeInTheDocument();
|
|
70
|
+
expect(
|
|
71
|
+
screen.getByRole('button', {name: 'Open file.png — Clickable'}),
|
|
72
|
+
).toBeInTheDocument();
|
|
73
|
+
expect(
|
|
74
|
+
screen.getByRole('button', {name: 'Remove file.png — Clickable'}),
|
|
75
|
+
).toBeInTheDocument();
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
|
|
45
79
|
it('label is shown via tooltip, not as inline text', () => {
|
|
46
80
|
render(<Thumbnail label="photo.png" data-testid="thumb" />);
|
|
47
81
|
// Label should exist in DOM (tooltip) but not as a direct child text node
|
|
@@ -58,8 +58,9 @@ export interface ThumbnailProps extends BaseProps<HTMLDivElement> {
|
|
|
58
58
|
alt?: string;
|
|
59
59
|
/**
|
|
60
60
|
* Accessible label for the thumbnail (e.g. file name).
|
|
61
|
-
* Not rendered visually — shown in a tooltip on hover
|
|
62
|
-
*
|
|
61
|
+
* Not rendered visually — shown in a tooltip on hover, exposed as the
|
|
62
|
+
* accessible name of the thumbnail group, and used as the accessible
|
|
63
|
+
* name for the remove button.
|
|
63
64
|
*/
|
|
64
65
|
label?: string;
|
|
65
66
|
/**
|
|
@@ -296,6 +297,7 @@ export function Thumbnail({
|
|
|
296
297
|
<div
|
|
297
298
|
ref={ref}
|
|
298
299
|
data-testid={testId}
|
|
300
|
+
role="group"
|
|
299
301
|
aria-label={accessibleName}
|
|
300
302
|
{...mergeProps(
|
|
301
303
|
themeProps('thumbnail'),
|
|
@@ -26,7 +26,7 @@ export const docs = {
|
|
|
26
26
|
{
|
|
27
27
|
guidance: true,
|
|
28
28
|
description:
|
|
29
|
-
'Choose the hour format (12h or 24h) that matches your audience\'s locale
|
|
29
|
+
'Choose the hour format (12h or 24h) that matches your audience\'s locale: 12-hour with AM/PM for US-centric UIs, 24-hour for international or technical contexts.',
|
|
30
30
|
},
|
|
31
31
|
{
|
|
32
32
|
guidance: true,
|
|
@@ -41,7 +41,7 @@ export const docs = {
|
|
|
41
41
|
{
|
|
42
42
|
guidance: true,
|
|
43
43
|
description:
|
|
44
|
-
'Use the status prop to surface validation errors inline
|
|
44
|
+
'Use the status prop to surface validation errors inline: show a message like "Time must be during business hours" so users know exactly what to fix.',
|
|
45
45
|
},
|
|
46
46
|
{
|
|
47
47
|
guidance: true,
|
|
@@ -146,7 +146,7 @@ export const docs = {
|
|
|
146
146
|
name: 'disabledMessage',
|
|
147
147
|
type: 'string',
|
|
148
148
|
description:
|
|
149
|
-
'Explains why the input is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the field focusable via aria-disabled (activation stays blocked). Use this instead of wrapping a disabled TimeInput in Tooltip
|
|
149
|
+
'Explains why the input is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the field focusable via aria-disabled (activation stays blocked). Use this instead of wrapping a disabled TimeInput in Tooltip. Disabled controls swallow the hover events an external Tooltip needs.',
|
|
150
150
|
},
|
|
151
151
|
{
|
|
152
152
|
name: 'value',
|
|
@@ -396,7 +396,7 @@ export const docsZh = {
|
|
|
396
396
|
{
|
|
397
397
|
guidance: true,
|
|
398
398
|
description:
|
|
399
|
-
'Choose the hour format (12h or 24h) that matches your audience\'s locale
|
|
399
|
+
'Choose the hour format (12h or 24h) that matches your audience\'s locale: 12-hour with AM/PM for US-centric UIs, 24-hour for international or technical contexts.',
|
|
400
400
|
},
|
|
401
401
|
{
|
|
402
402
|
guidance: true,
|
|
@@ -411,7 +411,7 @@ export const docsZh = {
|
|
|
411
411
|
{
|
|
412
412
|
guidance: true,
|
|
413
413
|
description:
|
|
414
|
-
'Use the status prop to surface validation errors inline
|
|
414
|
+
'Use the status prop to surface validation errors inline: show a message like "Time must be during business hours" so users know exactly what to fix.',
|
|
415
415
|
},
|
|
416
416
|
{
|
|
417
417
|
guidance: true,
|
|
@@ -480,7 +480,7 @@ export const docsDense = {
|
|
|
480
480
|
{
|
|
481
481
|
guidance: true,
|
|
482
482
|
description:
|
|
483
|
-
'Choose hour format (12h/24h) to match locale
|
|
483
|
+
'Choose hour format (12h/24h) to match locale: 12h for US, 24h for international.',
|
|
484
484
|
},
|
|
485
485
|
{
|
|
486
486
|
guidance: true,
|
|
@@ -497,6 +497,11 @@ export const docsDense = {
|
|
|
497
497
|
description: 'Use status prop for inline validation errors.',
|
|
498
498
|
},
|
|
499
499
|
{guidance: true, description: 'Enable hasClear for optional fields.'},
|
|
500
|
+
{
|
|
501
|
+
guidance: true,
|
|
502
|
+
description:
|
|
503
|
+
'Place inside InputGroup for a single-line prefix or suffix addon, like a label or timezone marker.',
|
|
504
|
+
},
|
|
500
505
|
{
|
|
501
506
|
guidance: false,
|
|
502
507
|
description:
|
|
@@ -160,6 +160,43 @@ describe('TimeInput', () => {
|
|
|
160
160
|
expect(onChange).not.toHaveBeenCalled();
|
|
161
161
|
});
|
|
162
162
|
|
|
163
|
+
it('sets aria-invalid="true" when typed input is out of range', () => {
|
|
164
|
+
render(<TimeInput label="Time" onChange={() => {}} />);
|
|
165
|
+
|
|
166
|
+
const input = screen.getByRole('textbox');
|
|
167
|
+
fireEvent.change(input, {target: {value: '25:99'}});
|
|
168
|
+
|
|
169
|
+
expect(input).toHaveAttribute('aria-invalid', 'true');
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it('does not set aria-invalid when typed input is a valid time', () => {
|
|
173
|
+
render(<TimeInput label="Time" onChange={() => {}} />);
|
|
174
|
+
|
|
175
|
+
const input = screen.getByRole('textbox');
|
|
176
|
+
fireEvent.change(input, {target: {value: '3:45 pm'}});
|
|
177
|
+
|
|
178
|
+
expect(input).not.toHaveAttribute('aria-invalid');
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it('announces an alert message when typed input is invalid', () => {
|
|
182
|
+
render(<TimeInput label="Time" onChange={() => {}} />);
|
|
183
|
+
|
|
184
|
+
const input = screen.getByRole('textbox');
|
|
185
|
+
fireEvent.change(input, {target: {value: '25:99'}});
|
|
186
|
+
|
|
187
|
+
expect(screen.getByRole('alert')).toHaveTextContent('Invalid time');
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('does not announce an alert message when input is valid', () => {
|
|
191
|
+
render(<TimeInput label="Time" onChange={() => {}} />);
|
|
192
|
+
|
|
193
|
+
const input = screen.getByRole('textbox');
|
|
194
|
+
fireEvent.change(input, {target: {value: '3:45 pm'}});
|
|
195
|
+
|
|
196
|
+
expect(screen.getByRole('alert')).toHaveTextContent('');
|
|
197
|
+
expect(screen.queryByText('Invalid time')).not.toBeInTheDocument();
|
|
198
|
+
});
|
|
199
|
+
|
|
163
200
|
it('calls onChange on blur when input is valid', async () => {
|
|
164
201
|
const user = userEvent.setup();
|
|
165
202
|
const onChange = vi.fn();
|
|
@@ -635,7 +635,9 @@ export function TimeInput({
|
|
|
635
635
|
data-autofocus={hasAutoFocus || undefined}
|
|
636
636
|
aria-describedby={ariaDescribedBy}
|
|
637
637
|
aria-required={isRequired === true ? 'true' : undefined}
|
|
638
|
-
aria-invalid={
|
|
638
|
+
aria-invalid={
|
|
639
|
+
status?.type === 'error' || !isInputValid ? 'true' : undefined
|
|
640
|
+
}
|
|
639
641
|
aria-busy={isBusy || undefined}
|
|
640
642
|
aria-labelledby={ariaLabelledBy}
|
|
641
643
|
{...stylex.props(
|
|
@@ -644,6 +646,14 @@ export function TimeInput({
|
|
|
644
646
|
!isInputValid && styles.inputInvalid,
|
|
645
647
|
)}
|
|
646
648
|
/>
|
|
649
|
+
{/*
|
|
650
|
+
Live region announcing invalid typed input to assistive technology.
|
|
651
|
+
The value silently reverts on blur, so without this a screen-reader
|
|
652
|
+
user would get no feedback that their entry was rejected (WCAG 3.3.1).
|
|
653
|
+
*/}
|
|
654
|
+
<VisuallyHidden as="div" role="alert" aria-live="assertive">
|
|
655
|
+
{!isInputValid ? 'Invalid time' : ''}
|
|
656
|
+
</VisuallyHidden>
|
|
647
657
|
{isBusy && <Spinner size="sm" />}
|
|
648
658
|
{hasClear && value && !isDisabled && (
|
|
649
659
|
<button
|