@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
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file FieldStatus.test.tsx
|
|
5
|
+
* @input Uses vitest, @testing-library/react, FieldStatus component
|
|
6
|
+
* @output Characterization coverage for FieldStatus behavior
|
|
7
|
+
* @position Testing; validates FieldStatus.tsx implementation
|
|
8
|
+
*
|
|
9
|
+
* SYNC: When FieldStatus.tsx changes, update tests to match new behavior
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import {describe, it, expect, vi} from 'vitest';
|
|
13
|
+
import {render, screen} from '@testing-library/react';
|
|
14
|
+
import * as stylex from '@stylexjs/stylex';
|
|
15
|
+
import {FieldStatus} from './FieldStatus';
|
|
16
|
+
|
|
17
|
+
const testStyles = stylex.create({
|
|
18
|
+
custom: {color: 'rebeccapurple'},
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe('FieldStatus', () => {
|
|
22
|
+
it('renders the message text', () => {
|
|
23
|
+
render(<FieldStatus type="error" message="This field is required" />);
|
|
24
|
+
expect(screen.getByText('This field is required')).toBeInTheDocument();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('renders the message inside a <div>', () => {
|
|
28
|
+
render(<FieldStatus type="error" message="Boom" data-testid="fs" />);
|
|
29
|
+
expect(screen.getByTestId('fs').tagName).toBe('DIV');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
describe('role semantics', () => {
|
|
33
|
+
// Errors are urgent — they get role="alert" so assistive tech interrupts.
|
|
34
|
+
it('uses role="alert" for error status', () => {
|
|
35
|
+
render(<FieldStatus type="error" message="msg" />);
|
|
36
|
+
expect(screen.getByRole('alert')).toHaveTextContent('msg');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Non-error statuses are advisory — role="status" is a polite live region.
|
|
40
|
+
it('uses role="status" for warning status', () => {
|
|
41
|
+
render(<FieldStatus type="warning" message="msg" data-testid="fs" />);
|
|
42
|
+
expect(screen.getByTestId('fs')).toHaveAttribute('role', 'status');
|
|
43
|
+
expect(screen.queryByRole('alert')).not.toBeInTheDocument();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('uses role="status" for success status', () => {
|
|
47
|
+
render(<FieldStatus type="success" message="msg" data-testid="fs" />);
|
|
48
|
+
expect(screen.getByTestId('fs')).toHaveAttribute('role', 'status');
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe('aria-live politeness', () => {
|
|
53
|
+
// Error → assertive so screen readers announce immediately.
|
|
54
|
+
it('sets aria-live="assertive" for error', () => {
|
|
55
|
+
render(<FieldStatus type="error" message="msg" data-testid="fs" />);
|
|
56
|
+
expect(screen.getByTestId('fs')).toHaveAttribute(
|
|
57
|
+
'aria-live',
|
|
58
|
+
'assertive',
|
|
59
|
+
);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('sets aria-live="polite" for warning', () => {
|
|
63
|
+
render(<FieldStatus type="warning" message="msg" data-testid="fs" />);
|
|
64
|
+
expect(screen.getByTestId('fs')).toHaveAttribute('aria-live', 'polite');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('sets aria-live="polite" for success', () => {
|
|
68
|
+
render(<FieldStatus type="success" message="msg" data-testid="fs" />);
|
|
69
|
+
expect(screen.getByTestId('fs')).toHaveAttribute('aria-live', 'polite');
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// The element is a live region, never hidden from assistive tech.
|
|
73
|
+
it('does not mark itself aria-hidden', () => {
|
|
74
|
+
render(<FieldStatus type="error" message="msg" data-testid="fs" />);
|
|
75
|
+
expect(screen.getByTestId('fs')).not.toHaveAttribute('aria-hidden');
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe('theme class + data attribute reflection', () => {
|
|
80
|
+
it('renders the stable astryx-field-status class', () => {
|
|
81
|
+
render(<FieldStatus type="error" message="msg" data-testid="fs" />);
|
|
82
|
+
expect(screen.getByTestId('fs')).toHaveClass('astryx-field-status');
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('reflects the type as a class token and data-type attribute', () => {
|
|
86
|
+
render(<FieldStatus type="warning" message="msg" data-testid="fs" />);
|
|
87
|
+
const el = screen.getByTestId('fs');
|
|
88
|
+
expect(el).toHaveClass('warning');
|
|
89
|
+
expect(el).toHaveAttribute('data-type', 'warning');
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('reflects the variant as a class token and data-variant attribute', () => {
|
|
93
|
+
render(
|
|
94
|
+
<FieldStatus
|
|
95
|
+
type="error"
|
|
96
|
+
message="msg"
|
|
97
|
+
variant="detached"
|
|
98
|
+
data-testid="fs"
|
|
99
|
+
/>,
|
|
100
|
+
);
|
|
101
|
+
const el = screen.getByTestId('fs');
|
|
102
|
+
expect(el).toHaveClass('detached');
|
|
103
|
+
expect(el).toHaveAttribute('data-variant', 'detached');
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('defaults data-variant to "attached"', () => {
|
|
107
|
+
render(<FieldStatus type="error" message="msg" data-testid="fs" />);
|
|
108
|
+
const el = screen.getByTestId('fs');
|
|
109
|
+
expect(el).toHaveAttribute('data-variant', 'attached');
|
|
110
|
+
expect(el).toHaveClass('attached');
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
describe('color styling per status type', () => {
|
|
115
|
+
// Each status type maps to a distinct color treatment. The rendered class
|
|
116
|
+
// list must therefore differ between types — a regression that collapsed
|
|
117
|
+
// them onto one color would be caught here.
|
|
118
|
+
it('applies distinct StyleX classes for each type', () => {
|
|
119
|
+
const {rerender} = render(
|
|
120
|
+
<FieldStatus type="error" message="msg" data-testid="fs" />,
|
|
121
|
+
);
|
|
122
|
+
const errorClass = screen.getByTestId('fs').getAttribute('class');
|
|
123
|
+
|
|
124
|
+
rerender(<FieldStatus type="warning" message="msg" data-testid="fs" />);
|
|
125
|
+
const warningClass = screen.getByTestId('fs').getAttribute('class');
|
|
126
|
+
|
|
127
|
+
rerender(<FieldStatus type="success" message="msg" data-testid="fs" />);
|
|
128
|
+
const successClass = screen.getByTestId('fs').getAttribute('class');
|
|
129
|
+
|
|
130
|
+
expect(errorClass).not.toEqual(warningClass);
|
|
131
|
+
expect(warningClass).not.toEqual(successClass);
|
|
132
|
+
expect(errorClass).not.toEqual(successClass);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('applies distinct StyleX classes for each variant', () => {
|
|
136
|
+
const {rerender} = render(
|
|
137
|
+
<FieldStatus
|
|
138
|
+
type="error"
|
|
139
|
+
message="msg"
|
|
140
|
+
variant="attached"
|
|
141
|
+
data-testid="fs"
|
|
142
|
+
/>,
|
|
143
|
+
);
|
|
144
|
+
const attachedClass = screen.getByTestId('fs').getAttribute('class');
|
|
145
|
+
|
|
146
|
+
rerender(
|
|
147
|
+
<FieldStatus
|
|
148
|
+
type="error"
|
|
149
|
+
message="msg"
|
|
150
|
+
variant="detached"
|
|
151
|
+
data-testid="fs"
|
|
152
|
+
/>,
|
|
153
|
+
);
|
|
154
|
+
const detachedClass = screen.getByTestId('fs').getAttribute('class');
|
|
155
|
+
|
|
156
|
+
expect(attachedClass).not.toEqual(detachedClass);
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
describe('prop forwarding', () => {
|
|
161
|
+
it('forwards a ref to the root element', () => {
|
|
162
|
+
const ref = vi.fn();
|
|
163
|
+
render(<FieldStatus ref={ref} type="error" message="msg" />);
|
|
164
|
+
expect(ref).toHaveBeenCalledWith(expect.any(HTMLDivElement));
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('applies the id attribute', () => {
|
|
168
|
+
render(
|
|
169
|
+
<FieldStatus
|
|
170
|
+
type="error"
|
|
171
|
+
message="msg"
|
|
172
|
+
id="email-error"
|
|
173
|
+
data-testid="fs"
|
|
174
|
+
/>,
|
|
175
|
+
);
|
|
176
|
+
expect(screen.getByTestId('fs')).toHaveAttribute('id', 'email-error');
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it('passes through arbitrary DOM props', () => {
|
|
180
|
+
render(
|
|
181
|
+
<FieldStatus
|
|
182
|
+
type="error"
|
|
183
|
+
message="msg"
|
|
184
|
+
data-testid="fs"
|
|
185
|
+
data-custom="xyz"
|
|
186
|
+
/>,
|
|
187
|
+
);
|
|
188
|
+
expect(screen.getByTestId('fs')).toHaveAttribute('data-custom', 'xyz');
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
it('merges a consumer className with the stable class', () => {
|
|
192
|
+
render(
|
|
193
|
+
<FieldStatus
|
|
194
|
+
type="error"
|
|
195
|
+
message="msg"
|
|
196
|
+
className="my-status"
|
|
197
|
+
data-testid="fs"
|
|
198
|
+
/>,
|
|
199
|
+
);
|
|
200
|
+
const el = screen.getByTestId('fs');
|
|
201
|
+
expect(el).toHaveClass('my-status');
|
|
202
|
+
expect(el).toHaveClass('astryx-field-status');
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it('merges a consumer inline style', () => {
|
|
206
|
+
render(
|
|
207
|
+
<FieldStatus
|
|
208
|
+
type="error"
|
|
209
|
+
message="msg"
|
|
210
|
+
style={{marginTop: '10px'}}
|
|
211
|
+
data-testid="fs"
|
|
212
|
+
/>,
|
|
213
|
+
);
|
|
214
|
+
expect(screen.getByTestId('fs')).toHaveStyle({marginTop: '10px'});
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it('applies an xstyle as an extra class', () => {
|
|
218
|
+
const {rerender} = render(
|
|
219
|
+
<FieldStatus type="error" message="msg" data-testid="fs" />,
|
|
220
|
+
);
|
|
221
|
+
const withoutXstyle = screen.getByTestId('fs').getAttribute('class');
|
|
222
|
+
|
|
223
|
+
// xstyle values are compiled StyleX styles; passing one adds classes.
|
|
224
|
+
rerender(
|
|
225
|
+
<FieldStatus
|
|
226
|
+
type="error"
|
|
227
|
+
message="msg"
|
|
228
|
+
data-testid="fs"
|
|
229
|
+
xstyle={testStyles.custom}
|
|
230
|
+
/>,
|
|
231
|
+
);
|
|
232
|
+
const withXstyle = screen.getByTestId('fs').getAttribute('class');
|
|
233
|
+
expect(withXstyle).not.toEqual(withoutXstyle);
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
describe('dynamic updates', () => {
|
|
238
|
+
it('updates the rendered message on rerender', () => {
|
|
239
|
+
const {rerender} = render(
|
|
240
|
+
<FieldStatus type="error" message="First" data-testid="fs" />,
|
|
241
|
+
);
|
|
242
|
+
expect(screen.getByTestId('fs')).toHaveTextContent('First');
|
|
243
|
+
|
|
244
|
+
rerender(<FieldStatus type="error" message="Second" data-testid="fs" />);
|
|
245
|
+
expect(screen.getByTestId('fs')).toHaveTextContent('Second');
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
// Switching from error to a non-error type must relax both the role and
|
|
249
|
+
// the live-region politeness in lockstep.
|
|
250
|
+
it('relaxes role and aria-live when type changes from error', () => {
|
|
251
|
+
const {rerender} = render(
|
|
252
|
+
<FieldStatus type="error" message="msg" data-testid="fs" />,
|
|
253
|
+
);
|
|
254
|
+
let el = screen.getByTestId('fs');
|
|
255
|
+
expect(el).toHaveAttribute('role', 'alert');
|
|
256
|
+
expect(el).toHaveAttribute('aria-live', 'assertive');
|
|
257
|
+
|
|
258
|
+
rerender(<FieldStatus type="success" message="msg" data-testid="fs" />);
|
|
259
|
+
el = screen.getByTestId('fs');
|
|
260
|
+
expect(el).toHaveAttribute('role', 'status');
|
|
261
|
+
expect(el).toHaveAttribute('aria-live', 'polite');
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
describe('edge cases', () => {
|
|
266
|
+
it('renders an empty message without crashing', () => {
|
|
267
|
+
render(<FieldStatus type="error" message="" data-testid="fs" />);
|
|
268
|
+
const el = screen.getByTestId('fs');
|
|
269
|
+
expect(el).toBeInTheDocument();
|
|
270
|
+
expect(el).toHaveTextContent('');
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
it('renders message content verbatim, including whitespace-only strings', () => {
|
|
274
|
+
render(<FieldStatus type="warning" message=" " data-testid="fs" />);
|
|
275
|
+
expect(screen.getByTestId('fs').textContent).toBe(' ');
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
it('exposes a displayName for devtools', () => {
|
|
280
|
+
expect(FieldStatus.displayName).toBe('FieldStatus');
|
|
281
|
+
});
|
|
282
|
+
});
|
|
@@ -92,7 +92,7 @@ export const docs = {
|
|
|
92
92
|
name: 'disabledMessage',
|
|
93
93
|
type: 'string',
|
|
94
94
|
description:
|
|
95
|
-
'Explains why the input is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the trigger focusable via aria-disabled (opening the file picker stays blocked). Use this instead of wrapping a disabled FileInput in Tooltip
|
|
95
|
+
'Explains why the input is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the trigger focusable via aria-disabled (opening the file picker stays blocked). Use this instead of wrapping a disabled FileInput in Tooltip; disabled controls swallow the hover events an external Tooltip needs.',
|
|
96
96
|
},
|
|
97
97
|
{
|
|
98
98
|
name: 'isLoading',
|
|
@@ -4,7 +4,6 @@ exports[`FormLayout > matches snapshot for horizontal direction 1`] = `
|
|
|
4
4
|
<div
|
|
5
5
|
class="astryx-form-layout horizontal FormLayout__styles.base xdt5ytf x18g69wz FormLayout__styles.horizontal xrvj5dj x1mt1orb xu6a5m6"
|
|
6
6
|
data-direction="horizontal"
|
|
7
|
-
data-style-src="@astryxdesign/core:src/FormLayout/FormLayout.tsx:40; @astryxdesign/core:src/FormLayout/FormLayout.tsx:45"
|
|
8
7
|
data-testid="layout"
|
|
9
8
|
>
|
|
10
9
|
<input
|
|
@@ -20,7 +19,6 @@ exports[`FormLayout > matches snapshot for horizontal-labels direction 1`] = `
|
|
|
20
19
|
<div
|
|
21
20
|
class="astryx-form-layout horizontal-labels FormLayout__styles.base xdt5ytf FormLayout__styles.horizontalLabels xrvj5dj x1pmbctz xlaq8a2 x7a106z xedohl4 x1rpgqan x1a1jff"
|
|
22
21
|
data-direction="horizontal-labels"
|
|
23
|
-
data-style-src="@astryxdesign/core:src/FormLayout/FormLayout.tsx:40; @astryxdesign/core:src/FormLayout/FormLayout.tsx:50"
|
|
24
22
|
data-testid="layout"
|
|
25
23
|
>
|
|
26
24
|
<label>
|
|
@@ -36,7 +34,6 @@ exports[`FormLayout > matches snapshot for vertical direction 1`] = `
|
|
|
36
34
|
<div
|
|
37
35
|
class="astryx-form-layout vertical FormLayout__styles.base x78zum5 xdt5ytf x18g69wz"
|
|
38
36
|
data-direction="vertical"
|
|
39
|
-
data-style-src="@astryxdesign/core:src/FormLayout/FormLayout.tsx:40"
|
|
40
37
|
data-testid="layout"
|
|
41
38
|
>
|
|
42
39
|
<input
|
package/src/Grid/Grid.doc.mjs
CHANGED
|
@@ -17,7 +17,7 @@ export const docs = {
|
|
|
17
17
|
{ guidance: true, description: 'Use `repeat: \'fill\'` (the default) for consistent item widths. Use `\'fit\'` when items should stretch to fill leftover space.' },
|
|
18
18
|
{ guidance: false, description: 'Write manual CSS grid; Grid handles spacing and responsive behavior for you.' },
|
|
19
19
|
{ guidance: false, description: 'Use `HStack` with wrapping for grids; use Grid instead.' },
|
|
20
|
-
{ guidance: true, description: 'Track templates use CSS-variable indirection (not raw inline styles), so `xstyle` overrides of `gridTemplateColumns`
|
|
20
|
+
{ guidance: true, description: 'Track templates use CSS-variable indirection (not raw inline styles), so `xstyle` overrides of `gridTemplateColumns` (including inside `@media` queries) take effect.' },
|
|
21
21
|
],
|
|
22
22
|
},
|
|
23
23
|
theming: {
|
|
@@ -112,7 +112,7 @@ export const docsZh = {
|
|
|
112
112
|
{ guidance: true, description: 'Use `repeat: \'fill\'` (the default) for consistent item widths. Use `\'fit\'` when items should stretch to fill leftover space.' },
|
|
113
113
|
{ guidance: false, description: 'Write manual CSS grid; Grid handles spacing and responsive behavior for you.' },
|
|
114
114
|
{ guidance: false, description: 'Use `HStack` with wrapping for grids; use Grid instead.' },
|
|
115
|
-
{ guidance: true, description: 'Track templates use CSS-variable indirection (not raw inline styles), so `xstyle` overrides of `gridTemplateColumns`
|
|
115
|
+
{ guidance: true, description: 'Track templates use CSS-variable indirection (not raw inline styles), so `xstyle` overrides of `gridTemplateColumns` (including inside `@media` queries) take effect.' },
|
|
116
116
|
],
|
|
117
117
|
},
|
|
118
118
|
};
|
|
@@ -128,7 +128,7 @@ export const docsDense = {
|
|
|
128
128
|
{ guidance: true, description: 'Use repeat: \'fill\' (the default) for consistent item widths. Use \'fit\' when items should stretch to fill leftover space.' },
|
|
129
129
|
{ guidance: false, description: 'Write manual CSS grid; Grid handles spacing and responsive behavior for you.' },
|
|
130
130
|
{ guidance: false, description: 'Use HStack with wrapping for grids; use Grid instead.' },
|
|
131
|
-
{ guidance: true, description: 'track templates use CSS-var indirection, not inline styles
|
|
131
|
+
{ guidance: true, description: 'track templates use CSS-var indirection, not inline styles, so xstyle/@media overrides of gridTemplateColumns work.' },
|
|
132
132
|
],
|
|
133
133
|
},
|
|
134
134
|
};
|
package/src/Grid/Grid.test.tsx
CHANGED
|
@@ -65,7 +65,7 @@ describe('Grid', () => {
|
|
|
65
65
|
expect(templateColumns(grid)).toBe('repeat(auto-fill, minmax(250px, 1fr))');
|
|
66
66
|
});
|
|
67
67
|
|
|
68
|
-
it('renders with columns object max (capped
|
|
68
|
+
it('renders with columns object max (count capped, tracks still fill)', () => {
|
|
69
69
|
render(
|
|
70
70
|
<Grid columns={{minWidth: 250, max: 3}} gap={4} data-testid="grid">
|
|
71
71
|
<div>Item 1</div>
|
|
@@ -74,13 +74,37 @@ describe('Grid', () => {
|
|
|
74
74
|
</Grid>,
|
|
75
75
|
);
|
|
76
76
|
const grid = screen.getByTestId('grid');
|
|
77
|
-
//
|
|
77
|
+
// Cap lives on the track MIN (min(100%, max(minWidth, perColumn))); the
|
|
78
|
+
// track MAX stays 1fr so present columns fill the row (a lone column on
|
|
79
|
+
// mobile stretches to 100% instead of leaving dead space).
|
|
78
80
|
expect(templateColumns(grid)).toBe(
|
|
79
|
-
'repeat(auto-fill, minmax(250px, calc((100% - 2 * var(--spacing-4)) / 3)))',
|
|
81
|
+
'repeat(auto-fill, minmax(min(100%, max(250px, calc((100% - 2 * var(--spacing-4)) / 3))), 1fr))',
|
|
80
82
|
);
|
|
81
83
|
expect(grid.style.maxWidth).toBe('');
|
|
82
84
|
});
|
|
83
85
|
|
|
86
|
+
it('keeps track max at 1fr with a max cap so a lone column can fill (#3391)', () => {
|
|
87
|
+
// Regression: previously the cap was applied to the track MAX
|
|
88
|
+
// (minmax(minWidth, 100%/max)), so when fewer than `max` columns fit —
|
|
89
|
+
// e.g. a single column on mobile — the lone column was pinned to ~100%/max
|
|
90
|
+
// and left dead space on the right. The cap now lives on the track MIN and
|
|
91
|
+
// the track MAX stays 1fr, so present columns always stretch to fill.
|
|
92
|
+
render(
|
|
93
|
+
<Grid columns={{minWidth: 360, max: 2}} gap={4} data-testid="grid">
|
|
94
|
+
<div>Left</div>
|
|
95
|
+
<div>Right</div>
|
|
96
|
+
</Grid>,
|
|
97
|
+
);
|
|
98
|
+
const grid = screen.getByTestId('grid');
|
|
99
|
+
const template = templateColumns(grid);
|
|
100
|
+
// Track max must be 1fr (fills), not a fraction-of-container cap.
|
|
101
|
+
expect(template).toMatch(/, 1fr\)\)$/);
|
|
102
|
+
expect(template).not.toMatch(/, calc\([^)]*\/ 2\)\)\)$/);
|
|
103
|
+
expect(template).toBe(
|
|
104
|
+
'repeat(auto-fill, minmax(min(100%, max(360px, calc((100% - 1 * var(--spacing-4)) / 2))), 1fr))',
|
|
105
|
+
);
|
|
106
|
+
});
|
|
107
|
+
|
|
84
108
|
it('renders with columns object max using columnGap', () => {
|
|
85
109
|
render(
|
|
86
110
|
<Grid columns={{minWidth: 200, max: 4}} columnGap={6} data-testid="grid">
|
|
@@ -89,9 +113,9 @@ describe('Grid', () => {
|
|
|
89
113
|
</Grid>,
|
|
90
114
|
);
|
|
91
115
|
const grid = screen.getByTestId('grid');
|
|
92
|
-
// columnGap takes precedence
|
|
116
|
+
// columnGap takes precedence in the perColumn floor calculation
|
|
93
117
|
expect(templateColumns(grid)).toBe(
|
|
94
|
-
'repeat(auto-fill, minmax(200px, calc((100% - 3 * var(--spacing-6)) / 4)))',
|
|
118
|
+
'repeat(auto-fill, minmax(min(100%, max(200px, calc((100% - 3 * var(--spacing-6)) / 4))), 1fr))',
|
|
95
119
|
);
|
|
96
120
|
expect(grid.style.maxWidth).toBe('');
|
|
97
121
|
});
|
|
@@ -165,7 +189,7 @@ describe('Grid', () => {
|
|
|
165
189
|
expect(templateColumns(grid)).toBe('1fr');
|
|
166
190
|
});
|
|
167
191
|
|
|
168
|
-
it('uses auto-fill
|
|
192
|
+
it('uses auto-fill with a plain 1fr track when no max specified', () => {
|
|
169
193
|
render(
|
|
170
194
|
<Grid columns={{minWidth: 200}} data-testid="grid">
|
|
171
195
|
<div>Item</div>
|
|
@@ -220,7 +244,7 @@ describe('Grid', () => {
|
|
|
220
244
|
|
|
221
245
|
// --- P2: columns object + columnGap interaction (hardening #719) ---
|
|
222
246
|
|
|
223
|
-
it('uses columnGap var in
|
|
247
|
+
it('uses columnGap var in the count-cap floor when both columnGap and gap are set', () => {
|
|
224
248
|
render(
|
|
225
249
|
<Grid
|
|
226
250
|
columns={{minWidth: 200, max: 3}}
|
|
@@ -231,14 +255,14 @@ describe('Grid', () => {
|
|
|
231
255
|
</Grid>,
|
|
232
256
|
);
|
|
233
257
|
const grid = screen.getByTestId('grid');
|
|
234
|
-
// columnGap takes precedence over gap in
|
|
258
|
+
// columnGap takes precedence over gap in the perColumn floor
|
|
235
259
|
expect(templateColumns(grid)).toBe(
|
|
236
|
-
'repeat(auto-fill, minmax(200px, calc((100% - 2 * var(--spacing-6)) / 3)))',
|
|
260
|
+
'repeat(auto-fill, minmax(min(100%, max(200px, calc((100% - 2 * var(--spacing-6)) / 3))), 1fr))',
|
|
237
261
|
);
|
|
238
262
|
expect(grid.style.maxWidth).toBe('');
|
|
239
263
|
});
|
|
240
264
|
|
|
241
|
-
it('uses gap var in
|
|
265
|
+
it('uses gap var in the count-cap floor when columnGap is not set', () => {
|
|
242
266
|
render(
|
|
243
267
|
<Grid columns={{minWidth: 150, max: 2}} gap={3} data-testid="grid">
|
|
244
268
|
<div>Item</div>
|
|
@@ -246,12 +270,12 @@ describe('Grid', () => {
|
|
|
246
270
|
);
|
|
247
271
|
const grid = screen.getByTestId('grid');
|
|
248
272
|
expect(templateColumns(grid)).toBe(
|
|
249
|
-
'repeat(auto-fill, minmax(150px, calc((100% - 1 * var(--spacing-3)) / 2)))',
|
|
273
|
+
'repeat(auto-fill, minmax(min(100%, max(150px, calc((100% - 1 * var(--spacing-3)) / 2))), 1fr))',
|
|
250
274
|
);
|
|
251
275
|
expect(grid.style.maxWidth).toBe('');
|
|
252
276
|
});
|
|
253
277
|
|
|
254
|
-
it('uses simple fraction in
|
|
278
|
+
it('uses simple fraction in the count-cap floor when no gap is set', () => {
|
|
255
279
|
render(
|
|
256
280
|
<Grid columns={{minWidth: 100, max: 3}} data-testid="grid">
|
|
257
281
|
<div>Item</div>
|
|
@@ -259,7 +283,7 @@ describe('Grid', () => {
|
|
|
259
283
|
);
|
|
260
284
|
const grid = screen.getByTestId('grid');
|
|
261
285
|
expect(templateColumns(grid)).toBe(
|
|
262
|
-
'repeat(auto-fill, minmax(100px, calc(100% / 3)))',
|
|
286
|
+
'repeat(auto-fill, minmax(min(100%, max(100px, calc(100% / 3))), 1fr))',
|
|
263
287
|
);
|
|
264
288
|
expect(grid.style.maxWidth).toBe('');
|
|
265
289
|
});
|
|
@@ -332,7 +356,7 @@ describe('Grid', () => {
|
|
|
332
356
|
expect(templateColumns(grid)).toBe('repeat(auto-fill, minmax(280px, 1fr))');
|
|
333
357
|
});
|
|
334
358
|
|
|
335
|
-
it('renders with columns={{minWidth, max}} capping
|
|
359
|
+
it('renders with columns={{minWidth, max}} capping the count while filling', () => {
|
|
336
360
|
render(
|
|
337
361
|
<Grid columns={{minWidth: 280, max: 3}} gap={4} data-testid="grid">
|
|
338
362
|
<div>Item 1</div>
|
|
@@ -340,14 +364,15 @@ describe('Grid', () => {
|
|
|
340
364
|
</Grid>,
|
|
341
365
|
);
|
|
342
366
|
const grid = screen.getByTestId('grid');
|
|
343
|
-
//
|
|
367
|
+
// Count is capped via the track MIN; track MAX stays 1fr so present
|
|
368
|
+
// columns fill the row (grid stays full width).
|
|
344
369
|
expect(templateColumns(grid)).toBe(
|
|
345
|
-
'repeat(auto-fill, minmax(280px, calc((100% - 2 * var(--spacing-4)) / 3)))',
|
|
370
|
+
'repeat(auto-fill, minmax(min(100%, max(280px, calc((100% - 2 * var(--spacing-4)) / 3))), 1fr))',
|
|
346
371
|
);
|
|
347
372
|
expect(grid.style.maxWidth).toBe('');
|
|
348
373
|
});
|
|
349
374
|
|
|
350
|
-
it('renders with columns={{minWidth, max, repeat: "fit"}} using auto-fit +
|
|
375
|
+
it('renders with columns={{minWidth, max, repeat: "fit"}} using auto-fit + count cap', () => {
|
|
351
376
|
render(
|
|
352
377
|
<Grid
|
|
353
378
|
columns={{minWidth: 280, max: 3, repeat: 'fit'}}
|
|
@@ -359,7 +384,7 @@ describe('Grid', () => {
|
|
|
359
384
|
);
|
|
360
385
|
const grid = screen.getByTestId('grid');
|
|
361
386
|
expect(templateColumns(grid)).toBe(
|
|
362
|
-
'repeat(auto-fit, minmax(280px, calc((100% - 2 * var(--spacing-4)) / 3)))',
|
|
387
|
+
'repeat(auto-fit, minmax(min(100%, max(280px, calc((100% - 2 * var(--spacing-4)) / 3))), 1fr))',
|
|
363
388
|
);
|
|
364
389
|
expect(grid.style.maxWidth).toBe('');
|
|
365
390
|
});
|
package/src/Grid/Grid.tsx
CHANGED
|
@@ -38,9 +38,10 @@ export type GridAlignment = 'start' | 'center' | 'end' | 'stretch';
|
|
|
38
38
|
* - `minWidth` — minimum width (px) for each column track
|
|
39
39
|
* - `repeat` — `'fill'` (default) preserves empty tracks for consistent widths;
|
|
40
40
|
* `'fit'` collapses empty tracks so items stretch to fill
|
|
41
|
-
* - `max` — caps the maximum number of columns
|
|
42
|
-
*
|
|
43
|
-
*
|
|
41
|
+
* - `max` — caps the maximum number of columns. The grid stretches to 100%
|
|
42
|
+
* of its parent and the columns that are present always fill the row, so a
|
|
43
|
+
* layout collapsing to a single column on mobile stretches to full width
|
|
44
|
+
* (no dead space on the right).
|
|
44
45
|
*/
|
|
45
46
|
export type GridColumns =
|
|
46
47
|
| number
|
|
@@ -321,9 +322,20 @@ const spacingVarNames: Record<SpacingStep, string> = {
|
|
|
321
322
|
};
|
|
322
323
|
|
|
323
324
|
/**
|
|
324
|
-
* Build a grid-template-columns value that caps
|
|
325
|
-
*
|
|
326
|
-
*
|
|
325
|
+
* Build a grid-template-columns value that caps the column *count* at `max`
|
|
326
|
+
* while still letting the columns that are actually present stretch to fill
|
|
327
|
+
* the row.
|
|
328
|
+
*
|
|
329
|
+
* The cap lives on the track's **min** size, not its max: each track is at
|
|
330
|
+
* least `perColumn = (100% - (max-1) * gap) / max`, so more than `max` columns
|
|
331
|
+
* can never fit. The track **max** stays `1fr`, so whenever fewer than `max`
|
|
332
|
+
* columns fit (most importantly a lone column on mobile) they still grow to
|
|
333
|
+
* fill the whole row — no dead space on the right.
|
|
334
|
+
*
|
|
335
|
+
* The track min is `max(minWidth, perColumn)` so an explicit `minWidth` is
|
|
336
|
+
* still honored, wrapped in `min(100%, …)` so a single column on a viewport
|
|
337
|
+
* narrower than `minWidth`/`perColumn` shrinks to the container instead of
|
|
338
|
+
* overflowing it.
|
|
327
339
|
*/
|
|
328
340
|
function buildCappedTemplate(
|
|
329
341
|
minWidth: number,
|
|
@@ -339,12 +351,17 @@ function buildCappedTemplate(
|
|
|
339
351
|
? spacingVarNames[gap]
|
|
340
352
|
: null;
|
|
341
353
|
|
|
342
|
-
//
|
|
343
|
-
|
|
354
|
+
// perColumn = (100% - (maxCols - 1) * gap) / maxCols — the width a track
|
|
355
|
+
// would have if exactly `maxCols` columns were present. Used as a floor so
|
|
356
|
+
// the grid never fits more than `maxCols` columns.
|
|
357
|
+
const perColumn = gapVar
|
|
344
358
|
? `calc((100% - ${maxCols - 1} * var(${gapVar})) / ${maxCols})`
|
|
345
359
|
: `calc(100% / ${maxCols})`;
|
|
346
360
|
|
|
347
|
-
|
|
361
|
+
// Track min caps the count; track max stays 1fr so present columns fill.
|
|
362
|
+
const trackMin = `min(100%, max(${minWidth}px, ${perColumn}))`;
|
|
363
|
+
|
|
364
|
+
return `repeat(${repeatMode}, minmax(${trackMin}, 1fr))`;
|
|
348
365
|
}
|
|
349
366
|
|
|
350
367
|
/**
|