@astryxdesign/core 0.1.9-canary.d2d84f8 → 0.1.9-canary.e00a241
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/dist/Avatar/Avatar.d.ts +6 -1
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +46 -12
- package/dist/Avatar/AvatarStatusDot.d.ts +6 -4
- package/dist/Avatar/AvatarStatusDot.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.js +11 -4
- package/dist/Breadcrumbs/index.d.ts +1 -0
- package/dist/Breadcrumbs/index.d.ts.map +1 -1
- package/dist/Breadcrumbs/index.js +2 -1
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +50 -9
- package/dist/Calendar/dayCellUtils.d.ts +4 -4
- package/dist/Calendar/dayCellUtils.js +2 -2
- package/dist/Calendar/styles.d.ts +30 -31
- package/dist/Calendar/styles.d.ts.map +1 -1
- package/dist/Calendar/styles.js +30 -31
- package/dist/Card/Card.js +1 -1
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +22 -12
- package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
- package/dist/Chat/ChatDictationButton.js +3 -1
- package/dist/Chat/ChatMessageBubble.d.ts.map +1 -1
- package/dist/Chat/ChatMessageBubble.js +8 -8
- package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
- package/dist/Chat/ChatToolCalls.js +10 -3
- package/dist/CheckboxInput/CheckboxInput.js +4 -4
- package/dist/Citation/Citation.d.ts +22 -1
- package/dist/Citation/Citation.d.ts.map +1 -1
- package/dist/Citation/Citation.js +20 -6
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +13 -7
- package/dist/Collapsible/Collapsible.d.ts.map +1 -1
- package/dist/Collapsible/Collapsible.js +3 -1
- package/dist/CommandPalette/CommandPalette.d.ts +1 -1
- package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPalette.js +42 -3
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +14 -5
- package/dist/ContextMenu/index.d.ts +1 -0
- package/dist/ContextMenu/index.d.ts.map +1 -1
- package/dist/ContextMenu/index.js +3 -1
- package/dist/DateInput/DateInput.d.ts +1 -0
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +31 -19
- package/dist/DateRangeInput/DateRangeInput.d.ts +1 -0
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +20 -19
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +23 -18
- package/dist/Divider/Divider.d.ts +2 -2
- package/dist/Divider/Divider.d.ts.map +1 -1
- package/dist/Divider/Divider.js +13 -0
- package/dist/DropdownMenu/DropdownMenu.d.ts +6 -0
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +22 -5
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +4 -1
- package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuItem.js +4 -1
- package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuRadioItem.js +4 -1
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts +104 -0
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -0
- package/dist/DropdownMenu/DropdownMenuSubMenu.js +427 -0
- package/dist/DropdownMenu/index.d.ts +10 -0
- package/dist/DropdownMenu/index.d.ts.map +1 -1
- package/dist/DropdownMenu/index.js +13 -0
- package/dist/DropdownMenu/menuItemHover.d.ts +23 -0
- package/dist/DropdownMenu/menuItemHover.d.ts.map +1 -0
- package/dist/DropdownMenu/menuItemHover.js +33 -0
- package/dist/DropdownMenu/menuItemRoles.d.ts +8 -0
- package/dist/DropdownMenu/menuItemRoles.d.ts.map +1 -1
- package/dist/DropdownMenu/menuItemRoles.js +10 -1
- package/dist/DropdownMenu/renderDropdownItems.d.ts.map +1 -1
- package/dist/DropdownMenu/renderDropdownItems.js +21 -6
- package/dist/Field/Field.d.ts +3 -1
- package/dist/Field/Field.d.ts.map +1 -1
- package/dist/Field/Field.js +4 -1
- package/dist/Field/inputStyles.stylex.d.ts +1 -0
- package/dist/Field/inputStyles.stylex.d.ts.map +1 -1
- package/dist/Field/inputStyles.stylex.js +1 -0
- package/dist/FieldStatus/FieldStatus.d.ts +4 -1
- package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
- package/dist/FieldStatus/FieldStatus.js +4 -2
- package/dist/FileInput/FileInput.d.ts +1 -0
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +91 -65
- package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
- package/dist/HoverCard/useHoverCard.js +10 -4
- package/dist/Icon/Icon.d.ts +15 -1
- package/dist/Icon/Icon.d.ts.map +1 -1
- package/dist/Icon/Icon.js +19 -3
- package/dist/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/Lightbox/Lightbox.js +15 -9
- package/dist/List/List.d.ts.map +1 -1
- package/dist/List/List.js +6 -3
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.js +7 -0
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +65 -40
- package/dist/NumberInput/NumberInput.d.ts +1 -0
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +20 -17
- package/dist/Outline/Outline.js +2 -2
- package/dist/RadioList/RadioList.d.ts +2 -2
- package/dist/RadioList/RadioListItem.js +4 -4
- package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
- package/dist/Resizable/ResizeHandle.js +49 -19
- package/dist/SegmentedControl/SegmentedControlItem.d.ts +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.js +2 -1
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +58 -16
- package/dist/SideNav/SideNav.d.ts.map +1 -1
- package/dist/SideNav/SideNav.js +5 -5
- package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
- package/dist/SideNav/SideNavCollapseButton.js +13 -10
- package/dist/SideNav/SideNavItem.d.ts +1 -1
- package/dist/SideNav/SideNavItem.d.ts.map +1 -1
- package/dist/SideNav/SideNavItem.js +12 -10
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +87 -34
- package/dist/Spinner/Spinner.d.ts +3 -2
- package/dist/Spinner/Spinner.d.ts.map +1 -1
- package/dist/Spinner/Spinner.js +11 -2
- package/dist/Switch/Switch.d.ts +8 -1
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +160 -91
- package/dist/TabList/TabList.d.ts +2 -11
- package/dist/TabList/TabList.d.ts.map +1 -1
- package/dist/TabList/TabList.js +5 -9
- package/dist/TabList/TabListContext.d.ts +0 -5
- package/dist/TabList/TabListContext.d.ts.map +1 -1
- package/dist/TabList/TabListContext.js +0 -5
- package/dist/Table/BaseTable.d.ts.map +1 -1
- package/dist/Table/BaseTable.js +30 -4
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +15 -11
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +36 -26
- package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
- package/dist/Table/plugins/selection/useTableSelection.js +3 -0
- package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
- package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +14 -6
- package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -1
- package/dist/Table/plugins/tree/useTableTreeData.js +29 -23
- package/dist/Table/types.d.ts +32 -0
- package/dist/Table/types.d.ts.map +1 -1
- package/dist/TextArea/TextArea.d.ts +1 -0
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +16 -19
- package/dist/TextInput/TextInput.d.ts +1 -0
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +18 -17
- package/dist/TimeInput/TimeInput.d.ts +1 -0
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +15 -17
- package/dist/Timestamp/Timestamp.d.ts +31 -3
- package/dist/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +47 -76
- package/dist/Timestamp/formatInstant.d.ts +41 -0
- package/dist/Timestamp/formatInstant.d.ts.map +1 -0
- package/dist/Timestamp/formatInstant.js +177 -0
- package/dist/Timestamp/index.d.ts +1 -0
- package/dist/Timestamp/index.d.ts.map +1 -1
- package/dist/Timestamp/tooltipEntries.d.ts +56 -0
- package/dist/Timestamp/tooltipEntries.d.ts.map +1 -0
- package/dist/Timestamp/tooltipEntries.js +163 -0
- package/dist/Token/Token.d.ts +30 -3
- package/dist/Token/Token.d.ts.map +1 -1
- package/dist/Token/Token.js +17 -2
- package/dist/Token/index.d.ts +1 -1
- package/dist/Token/index.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +2 -2
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +17 -1
- package/dist/TopNav/TopNavItem.d.ts +3 -1
- package/dist/TopNav/TopNavItem.d.ts.map +1 -1
- package/dist/TopNav/TopNavItem.js +30 -3
- package/dist/TreeList/TreeList.d.ts.map +1 -1
- package/dist/TreeList/TreeList.js +1 -0
- package/dist/TreeList/TreeListBranches.d.ts.map +1 -1
- package/dist/TreeList/TreeListBranches.js +8 -6
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +32 -14
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +19 -10
- package/dist/Typeahead/Typeahead.js +1 -1
- package/dist/Typeahead/TypeaheadItem.d.ts +1 -1
- package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
- package/dist/Typeahead/TypeaheadItem.js +20 -10
- package/dist/astryx.css +38 -14
- package/dist/astryx.umd.js +52 -52
- package/dist/astryx.umd.js.map +4 -4
- 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/isRtlElement.d.ts +18 -0
- package/dist/hooks/isRtlElement.d.ts.map +1 -0
- package/dist/hooks/isRtlElement.js +27 -0
- package/dist/hooks/useAnnounce.d.ts +3 -0
- package/dist/hooks/useAnnounce.d.ts.map +1 -1
- package/dist/hooks/useAnnounce.js +39 -1
- package/dist/hooks/useFocusTrap.d.ts.map +1 -1
- package/dist/hooks/useFocusTrap.js +52 -11
- package/dist/hooks/useGridFocus.d.ts +6 -1
- package/dist/hooks/useGridFocus.d.ts.map +1 -1
- package/dist/hooks/useGridFocus.js +12 -9
- package/dist/hooks/useHotkeys.d.ts +9 -0
- package/dist/hooks/useHotkeys.d.ts.map +1 -1
- package/dist/hooks/useHotkeys.js +9 -0
- package/dist/hooks/useInputStatusIcon.d.ts +38 -0
- package/dist/hooks/useInputStatusIcon.d.ts.map +1 -0
- package/dist/hooks/useInputStatusIcon.js +158 -0
- package/dist/hooks/useListFocus.d.ts +39 -1
- package/dist/hooks/useListFocus.d.ts.map +1 -1
- package/dist/hooks/useListFocus.js +54 -9
- package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
- package/dist/theme/derivedVarRegistry.js +13 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +2 -1
- package/dist/utils/plainDate.d.ts +17 -0
- package/dist/utils/plainDate.d.ts.map +1 -1
- package/dist/utils/plainDate.js +23 -4
- package/dist/utils/rtlStyles.d.ts +24 -0
- package/dist/utils/rtlStyles.d.ts.map +1 -0
- package/dist/utils/rtlStyles.js +27 -0
- package/locales/en.json +76 -0
- package/locales/pseudo.json +57 -0
- package/package.json +6 -1
- package/src/Avatar/Avatar.doc.mjs +18 -4
- package/src/Avatar/Avatar.test.tsx +106 -0
- package/src/Avatar/Avatar.tsx +62 -10
- package/src/Avatar/AvatarStatusDot.doc.mjs +4 -4
- package/src/Avatar/AvatarStatusDot.tsx +6 -4
- package/src/AvatarGroup/AvatarGroup.test.tsx +16 -1
- package/src/Breadcrumbs/BreadcrumbItem.tsx +10 -10
- package/src/Breadcrumbs/Breadcrumbs.test.tsx +51 -0
- package/src/Breadcrumbs/index.ts +4 -0
- package/src/Button/Button.doc.mjs +0 -4
- package/src/Calendar/Calendar.test.tsx +170 -20
- package/src/Calendar/Calendar.tsx +73 -16
- package/src/Calendar/dayCellUtils.test.ts +18 -18
- package/src/Calendar/dayCellUtils.ts +2 -2
- package/src/Calendar/styles.ts +33 -39
- package/src/Card/Card.tsx +1 -1
- package/src/Carousel/Carousel.tsx +25 -6
- package/src/Chat/ChatComposer.doc.mjs +2 -2
- package/src/Chat/ChatComposerInput.doc.mjs +1 -1
- package/src/Chat/ChatDictationButton.tsx +7 -1
- package/src/Chat/ChatMessageBubble.tsx +15 -10
- package/src/Chat/ChatSystemMessage.test.tsx +5 -0
- package/src/Chat/ChatToolCalls.tsx +9 -2
- package/src/CheckboxInput/CheckboxInput.doc.mjs +6 -0
- package/src/CheckboxInput/CheckboxInput.tsx +4 -4
- package/src/CheckboxList/CheckboxList.doc.mjs +6 -0
- package/src/Citation/Citation.doc.mjs +4 -3
- package/src/Citation/Citation.test.tsx +97 -0
- package/src/Citation/Citation.tsx +43 -11
- package/src/CodeBlock/CodeBlock.tsx +35 -8
- package/src/Collapsible/Collapsible.doc.mjs +1 -0
- package/src/Collapsible/Collapsible.test.tsx +7 -0
- package/src/Collapsible/Collapsible.tsx +16 -6
- package/src/CommandPalette/CommandPalette.test.tsx +95 -1
- package/src/CommandPalette/CommandPalette.tsx +41 -2
- package/src/ContextMenu/ContextMenu.test.tsx +42 -0
- package/src/ContextMenu/ContextMenu.tsx +13 -11
- package/src/ContextMenu/index.ts +5 -0
- package/src/DateInput/DateInput.doc.mjs +15 -5
- package/src/DateInput/DateInput.test.tsx +210 -3
- package/src/DateInput/DateInput.tsx +41 -29
- package/src/DateRangeInput/DateRangeInput.doc.mjs +11 -3
- package/src/DateRangeInput/DateRangeInput.test.tsx +120 -3
- package/src/DateRangeInput/DateRangeInput.tsx +29 -27
- package/src/DateTimeInput/DateTimeInput.doc.mjs +22 -1
- package/src/DateTimeInput/DateTimeInput.test.tsx +112 -0
- package/src/DateTimeInput/DateTimeInput.tsx +44 -39
- package/src/Divider/Divider.test.tsx +32 -8
- package/src/Divider/Divider.tsx +14 -1
- package/src/DropdownMenu/DropdownMenu.test.tsx +60 -0
- package/src/DropdownMenu/DropdownMenu.tsx +31 -12
- package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +8 -2
- package/src/DropdownMenu/DropdownMenuItem.tsx +8 -2
- package/src/DropdownMenu/DropdownMenuRadioItem.tsx +8 -2
- package/src/DropdownMenu/DropdownMenuSubMenu.doc.mjs +88 -0
- package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +635 -0
- package/src/DropdownMenu/DropdownMenuSubMenu.tsx +553 -0
- package/src/DropdownMenu/index.ts +16 -0
- package/src/DropdownMenu/menuItemHover.ts +39 -0
- package/src/DropdownMenu/menuItemRoles.ts +9 -0
- package/src/DropdownMenu/renderDropdownItems.tsx +29 -15
- package/src/Field/Field.tsx +14 -9
- package/src/Field/inputStyles.stylex.ts +2 -0
- package/src/FieldStatus/FieldStatus.tsx +10 -4
- package/src/FileInput/FileInput.doc.mjs +13 -7
- package/src/FileInput/FileInput.test.tsx +84 -16
- package/src/FileInput/FileInput.tsx +96 -79
- package/src/HoverCard/useHoverCard.tsx +15 -3
- package/src/Icon/Icon.doc.mjs +13 -0
- package/src/Icon/Icon.test.tsx +89 -0
- package/src/Icon/Icon.tsx +51 -3
- package/src/Lightbox/Lightbox.tsx +11 -3
- package/src/List/List.test.tsx +17 -29
- package/src/List/List.tsx +6 -1
- package/src/Markdown/Markdown.test.tsx +21 -0
- package/src/Markdown/Markdown.tsx +4 -0
- package/src/MultiSelector/MultiSelector.doc.mjs +11 -0
- package/src/MultiSelector/MultiSelector.test.tsx +306 -3
- package/src/MultiSelector/MultiSelector.tsx +88 -57
- package/src/NumberInput/NumberInput.doc.mjs +11 -5
- package/src/NumberInput/NumberInput.test.tsx +48 -0
- package/src/NumberInput/NumberInput.tsx +25 -26
- package/src/Outline/Outline.test.tsx +12 -12
- package/src/Outline/Outline.tsx +2 -2
- package/src/RadioList/RadioList.doc.mjs +6 -0
- package/src/RadioList/RadioList.tsx +2 -2
- package/src/RadioList/RadioListItem.tsx +4 -4
- package/src/Resizable/ResizeHandle.test.tsx +94 -0
- package/src/Resizable/ResizeHandle.tsx +70 -20
- package/src/SegmentedControl/SegmentedControlItem.tsx +2 -0
- package/src/Selector/Selector.doc.mjs +8 -0
- package/src/Selector/Selector.test.tsx +328 -3
- package/src/Selector/Selector.tsx +70 -19
- package/src/SideNav/SideNav.tsx +1 -8
- package/src/SideNav/SideNavCollapseButton.tsx +9 -7
- package/src/SideNav/SideNavItem.tsx +5 -3
- package/src/Slider/Slider.doc.mjs +6 -0
- package/src/Slider/Slider.test.tsx +240 -12
- package/src/Slider/Slider.tsx +96 -23
- package/src/Spinner/Spinner.test.tsx +10 -8
- package/src/Spinner/Spinner.tsx +15 -5
- package/src/Switch/Switch.doc.mjs +142 -42
- package/src/Switch/Switch.test.tsx +22 -0
- package/src/Switch/Switch.tsx +90 -33
- package/src/TabList/TabList.doc.mjs +0 -6
- package/src/TabList/TabList.test.tsx +3 -15
- package/src/TabList/TabList.tsx +6 -17
- package/src/TabList/TabListContext.ts +0 -6
- package/src/Table/BaseTable.tsx +34 -2
- package/src/Table/Table.doc.mjs +11 -0
- package/src/Table/Table.test.tsx +85 -0
- package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +9 -6
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +24 -17
- package/src/Table/plugins/selection/useTableSelection.test.tsx +61 -3
- package/src/Table/plugins/selection/useTableSelection.tsx +3 -0
- package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +37 -8
- package/src/Table/plugins/tree/useTableTreeData.tsx +17 -13
- package/src/Table/types.ts +33 -0
- package/src/Table/useTableRowStatus.doc.mjs +1 -1
- package/src/TextArea/TextArea.doc.mjs +11 -5
- package/src/TextArea/TextArea.tsx +17 -26
- package/src/TextInput/TextInput.doc.mjs +11 -5
- package/src/TextInput/TextInput.test.tsx +130 -3
- package/src/TextInput/TextInput.tsx +18 -25
- package/src/Thumbnail/Thumbnail.doc.mjs +1 -1
- package/src/TimeInput/TimeInput.doc.mjs +11 -5
- package/src/TimeInput/TimeInput.tsx +14 -25
- package/src/Timestamp/Timestamp.doc.mjs +32 -6
- package/src/Timestamp/Timestamp.test.tsx +371 -0
- package/src/Timestamp/Timestamp.tsx +96 -93
- package/src/Timestamp/formatInstant.ts +218 -0
- package/src/Timestamp/index.ts +4 -0
- package/src/Timestamp/tooltipEntries.test.ts +552 -0
- package/src/Timestamp/tooltipEntries.ts +210 -0
- package/src/Token/Token.test.tsx +21 -15
- package/src/Token/Token.tsx +31 -14
- package/src/Token/index.ts +1 -1
- package/src/Tokenizer/Tokenizer.doc.mjs +8 -1
- package/src/Tokenizer/Tokenizer.tsx +4 -2
- package/src/Tooltip/Tooltip.test.tsx +46 -0
- package/src/Tooltip/useTooltip.tsx +20 -0
- package/src/TopNav/TopNav.test.tsx +93 -2
- package/src/TopNav/TopNavItem.doc.mjs +3 -3
- package/src/TopNav/TopNavItem.tsx +35 -6
- package/src/TopNav/TopNavMegaMenuFeaturedCard.doc.mjs +1 -1
- package/src/TreeList/TreeList.doc.mjs +6 -0
- package/src/TreeList/TreeList.test.tsx +50 -10
- package/src/TreeList/TreeList.tsx +5 -0
- package/src/TreeList/TreeListBranches.tsx +8 -6
- package/src/TreeList/TreeListItem.tsx +33 -11
- package/src/Typeahead/BaseTypeahead.tsx +29 -14
- package/src/Typeahead/Typeahead.doc.mjs +6 -0
- package/src/Typeahead/Typeahead.test.tsx +27 -0
- package/src/Typeahead/Typeahead.tsx +1 -1
- package/src/Typeahead/TypeaheadItem.tsx +2 -1
- package/src/__tests__/inputWidthContract.test.tsx +62 -0
- package/src/doc-mjs.d.ts +19 -0
- package/src/hooks/index.ts +6 -0
- package/src/hooks/isRtlElement.ts +27 -0
- package/src/hooks/useAnnounce.test.tsx +75 -2
- package/src/hooks/useAnnounce.ts +47 -1
- package/src/hooks/useFocusTrap.test.tsx +104 -0
- package/src/hooks/useFocusTrap.ts +61 -12
- package/src/hooks/useGridFocus.doc.mjs +3 -3
- package/src/hooks/useGridFocus.test.tsx +41 -0
- package/src/hooks/useGridFocus.ts +21 -10
- package/src/hooks/useHotkeys.ts +9 -0
- package/src/hooks/useInputStatusIcon.test.tsx +162 -0
- package/src/hooks/useInputStatusIcon.tsx +224 -0
- package/src/hooks/useListFocus.doc.mjs +25 -3
- package/src/hooks/useListFocus.test.tsx +153 -1
- package/src/hooks/useListFocus.ts +102 -9
- package/src/reset.css +0 -26
- package/src/reset.test.ts +60 -0
- package/src/theme/derivedVarRegistry.test.ts +1 -0
- package/src/theme/derivedVarRegistry.ts +6 -0
- package/src/theme/generateThemeRules.test.ts +42 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/plainDate.test.ts +24 -6
- package/src/utils/plainDate.ts +18 -4
- package/src/utils/rtlStyles.ts +27 -0
package/src/List/List.test.tsx
CHANGED
|
@@ -136,35 +136,23 @@ describe('List', () => {
|
|
|
136
136
|
expect(container.querySelector('ul')).toBeInTheDocument();
|
|
137
137
|
});
|
|
138
138
|
|
|
139
|
-
it('
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
expect(ul).not.toHaveAttribute('role');
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
it('does not add role="list" when listStyle is decimal', () => {
|
|
160
|
-
const {container} = render(
|
|
161
|
-
<List listStyle="decimal">
|
|
162
|
-
<ListItem label="Item" />
|
|
163
|
-
</List>,
|
|
164
|
-
);
|
|
165
|
-
const ol = container.querySelector('ol');
|
|
166
|
-
expect(ol).not.toHaveAttribute('role');
|
|
167
|
-
});
|
|
139
|
+
it.each(['none', 'disc', 'circle', 'decimal'] as const)(
|
|
140
|
+
'adds an explicit role="list" when listStyle is %s (Safari fix)',
|
|
141
|
+
listStyle => {
|
|
142
|
+
// The base list style always sets list-style-type: none (markers are
|
|
143
|
+
// custom-rendered by ListItem), so Safari/VoiceOver drops the implicit
|
|
144
|
+
// list role for EVERY variant — the explicit role must always be there.
|
|
145
|
+
render(
|
|
146
|
+
<List listStyle={listStyle}>
|
|
147
|
+
<ListItem label="Item 1" />
|
|
148
|
+
<ListItem label="Item 2" />
|
|
149
|
+
</List>,
|
|
150
|
+
);
|
|
151
|
+
const list = screen.getByRole('list');
|
|
152
|
+
expect(list).toHaveAttribute('role', 'list');
|
|
153
|
+
expect(screen.getAllByRole('listitem')).toHaveLength(2);
|
|
154
|
+
},
|
|
155
|
+
);
|
|
168
156
|
|
|
169
157
|
it('renders items as <li> elements', () => {
|
|
170
158
|
const {container} = render(
|
package/src/List/List.tsx
CHANGED
|
@@ -168,7 +168,12 @@ export function List({
|
|
|
168
168
|
data-testid={testId}
|
|
169
169
|
aria-labelledby={header != null ? headerId : undefined}
|
|
170
170
|
{...(isOrdered && start != null && start !== 1 ? {start} : {})}
|
|
171
|
-
|
|
171
|
+
// The base list style always sets list-style-type: none (markers are
|
|
172
|
+
// custom-rendered by ListItem), and Safari/VoiceOver drops implicit
|
|
173
|
+
// list semantics for lists styled with list-style: none. The explicit
|
|
174
|
+
// role restores "list, N items" announcements for every listStyle
|
|
175
|
+
// variant.
|
|
176
|
+
role="list"
|
|
172
177
|
{...mergeProps(
|
|
173
178
|
themeProps('list', {density, listStyle}),
|
|
174
179
|
stylex.props(
|
|
@@ -236,6 +236,27 @@ describe('Markdown', () => {
|
|
|
236
236
|
expect(img!.getAttribute('src')).toBe('image.png');
|
|
237
237
|
});
|
|
238
238
|
|
|
239
|
+
it('uses the components.image override for a standalone (block) image', () => {
|
|
240
|
+
// A standalone image line parses as a block image; its render path must
|
|
241
|
+
// honor components.image just like the inline image path does.
|
|
242
|
+
render(
|
|
243
|
+
<Markdown
|
|
244
|
+
components={{
|
|
245
|
+
image: ({src, alt}) => (
|
|
246
|
+
<span data-testid="custom-image" data-src={src}>
|
|
247
|
+
{alt}
|
|
248
|
+
</span>
|
|
249
|
+
),
|
|
250
|
+
}}>
|
|
251
|
+
{''}
|
|
252
|
+
</Markdown>,
|
|
253
|
+
);
|
|
254
|
+
expect(document.querySelector('img')).not.toBeInTheDocument();
|
|
255
|
+
const custom = screen.getByTestId('custom-image');
|
|
256
|
+
expect(custom).toHaveTextContent('alt text');
|
|
257
|
+
expect(custom.getAttribute('data-src')).toBe('image.png');
|
|
258
|
+
});
|
|
259
|
+
|
|
239
260
|
it('shifts heading levels with headingLevelStart', () => {
|
|
240
261
|
render(<Markdown headingLevelStart={3}>{'# Heading 1'}</Markdown>);
|
|
241
262
|
expect(screen.getByText('Heading 1').tagName).toBe('H3');
|
|
@@ -21,6 +21,11 @@ export const docs = {
|
|
|
21
21
|
theming: {
|
|
22
22
|
targets: [
|
|
23
23
|
{className: 'astryx-multi-selector', visualProps: ['size', 'status']},
|
|
24
|
+
{className: 'astryx-multi-selector-clear-icon'},
|
|
25
|
+
{
|
|
26
|
+
className: 'astryx-multi-selector-indicator-icon',
|
|
27
|
+
states: ['state'],
|
|
28
|
+
},
|
|
24
29
|
],
|
|
25
30
|
},
|
|
26
31
|
components: [
|
|
@@ -168,6 +173,12 @@ export const docs = {
|
|
|
168
173
|
description:
|
|
169
174
|
'Custom render function for each selectable option in the dropdown. Not called for dividers, sections, or the select-all row.',
|
|
170
175
|
},
|
|
176
|
+
{
|
|
177
|
+
name: 'width',
|
|
178
|
+
type: 'SizeValue',
|
|
179
|
+
description:
|
|
180
|
+
'Width of the field (number = pixels, string used as-is, e.g. "100%"). Sizes the whole field (label, control, and status) so they stay aligned.',
|
|
181
|
+
},
|
|
171
182
|
{
|
|
172
183
|
name: 'xstyle',
|
|
173
184
|
type: 'StyleXStyles',
|
|
@@ -19,7 +19,10 @@ import {
|
|
|
19
19
|
} from '@testing-library/react';
|
|
20
20
|
import userEvent from '@testing-library/user-event';
|
|
21
21
|
import {MultiSelector} from './MultiSelector';
|
|
22
|
+
import {Icon} from '../Icon';
|
|
22
23
|
import {__resetLiveRegionsForTest} from '../hooks/useAnnounce';
|
|
24
|
+
import {defineTheme} from '../theme/defineTheme';
|
|
25
|
+
import {generateThemeCSSFlat} from '../theme/generateThemeRules';
|
|
23
26
|
|
|
24
27
|
// Module-level constants to satisfy @eslint-react/no-unstable-default-props.
|
|
25
28
|
const ANNOUNCE_OPTIONS = ['Apple', 'Banana', 'Orange'] as const;
|
|
@@ -565,6 +568,72 @@ describe('MultiSelector', () => {
|
|
|
565
568
|
expect(options).toHaveLength(1);
|
|
566
569
|
});
|
|
567
570
|
|
|
571
|
+
describe('grouped search', () => {
|
|
572
|
+
const GROUPED = [
|
|
573
|
+
{
|
|
574
|
+
type: 'section' as const,
|
|
575
|
+
title: 'Citrus',
|
|
576
|
+
options: [
|
|
577
|
+
{value: 'orange', label: 'Orange'},
|
|
578
|
+
{value: 'lemon', label: 'Lemon'},
|
|
579
|
+
],
|
|
580
|
+
},
|
|
581
|
+
{
|
|
582
|
+
type: 'section' as const,
|
|
583
|
+
title: 'Berries',
|
|
584
|
+
options: [
|
|
585
|
+
{value: 'strawberry', label: 'Strawberry'},
|
|
586
|
+
{value: 'blueberry', label: 'Blueberry'},
|
|
587
|
+
],
|
|
588
|
+
},
|
|
589
|
+
];
|
|
590
|
+
|
|
591
|
+
it('keeps the group header above matching items while searching', async () => {
|
|
592
|
+
const user = userEvent.setup();
|
|
593
|
+
render(
|
|
594
|
+
<MultiSelector
|
|
595
|
+
label="Fruit"
|
|
596
|
+
options={GROUPED}
|
|
597
|
+
value={[]}
|
|
598
|
+
onChange={() => {}}
|
|
599
|
+
hasSearch
|
|
600
|
+
/>,
|
|
601
|
+
);
|
|
602
|
+
await user.click(screen.getByRole('button', {name: 'Fruit'}));
|
|
603
|
+
await user.type(screen.getByRole('combobox', h), 'orange');
|
|
604
|
+
|
|
605
|
+
expect(
|
|
606
|
+
screen.getByRole('group', {name: 'Citrus', ...h}),
|
|
607
|
+
).toBeInTheDocument();
|
|
608
|
+
const options = screen.getAllByRole('option', h);
|
|
609
|
+
expect(options).toHaveLength(1);
|
|
610
|
+
expect(options[0]).toHaveTextContent('Orange');
|
|
611
|
+
});
|
|
612
|
+
|
|
613
|
+
it('hides a group whose items have no match', async () => {
|
|
614
|
+
const user = userEvent.setup();
|
|
615
|
+
render(
|
|
616
|
+
<MultiSelector
|
|
617
|
+
label="Fruit"
|
|
618
|
+
options={GROUPED}
|
|
619
|
+
value={[]}
|
|
620
|
+
onChange={() => {}}
|
|
621
|
+
hasSearch
|
|
622
|
+
/>,
|
|
623
|
+
);
|
|
624
|
+
await user.click(screen.getByRole('button', {name: 'Fruit'}));
|
|
625
|
+
await user.type(screen.getByRole('combobox', h), 'berry');
|
|
626
|
+
|
|
627
|
+
expect(
|
|
628
|
+
screen.getByRole('group', {name: 'Berries', ...h}),
|
|
629
|
+
).toBeInTheDocument();
|
|
630
|
+
expect(
|
|
631
|
+
screen.queryByRole('group', {name: 'Citrus', ...h}),
|
|
632
|
+
).not.toBeInTheDocument();
|
|
633
|
+
expect(screen.getAllByRole('option', h)).toHaveLength(2);
|
|
634
|
+
});
|
|
635
|
+
});
|
|
636
|
+
|
|
568
637
|
it('PageDown/PageUp jump the highlight to the last/first filtered option', async () => {
|
|
569
638
|
const user = userEvent.setup();
|
|
570
639
|
render(
|
|
@@ -1246,11 +1315,16 @@ describe('MultiSelector', () => {
|
|
|
1246
1315
|
});
|
|
1247
1316
|
});
|
|
1248
1317
|
|
|
1249
|
-
|
|
1250
1318
|
describe('MultiSelector statusVariant forwarding', () => {
|
|
1251
1319
|
it('defaults to attached (status renders with data-variant="attached")', () => {
|
|
1252
1320
|
const {container} = render(
|
|
1253
|
-
<MultiSelector
|
|
1321
|
+
<MultiSelector
|
|
1322
|
+
label="Fruit"
|
|
1323
|
+
options={['Apple', 'Banana']}
|
|
1324
|
+
value={[]}
|
|
1325
|
+
onChange={() => {}}
|
|
1326
|
+
status={{type: 'error', message: 'Required'}}
|
|
1327
|
+
/>,
|
|
1254
1328
|
);
|
|
1255
1329
|
expect(container.querySelector('.astryx-field-status')).toHaveAttribute(
|
|
1256
1330
|
'data-variant',
|
|
@@ -1260,7 +1334,14 @@ describe('MultiSelector statusVariant forwarding', () => {
|
|
|
1260
1334
|
|
|
1261
1335
|
it('forwards statusVariant="detached" to the underlying Field status', () => {
|
|
1262
1336
|
const {container} = render(
|
|
1263
|
-
<MultiSelector
|
|
1337
|
+
<MultiSelector
|
|
1338
|
+
label="Fruit"
|
|
1339
|
+
options={['Apple', 'Banana']}
|
|
1340
|
+
value={[]}
|
|
1341
|
+
onChange={() => {}}
|
|
1342
|
+
status={{type: 'error', message: 'Required'}}
|
|
1343
|
+
statusVariant="detached"
|
|
1344
|
+
/>,
|
|
1264
1345
|
);
|
|
1265
1346
|
expect(container.querySelector('.astryx-field-status')).toHaveAttribute(
|
|
1266
1347
|
'data-variant',
|
|
@@ -1268,3 +1349,225 @@ describe('MultiSelector statusVariant forwarding', () => {
|
|
|
1268
1349
|
);
|
|
1269
1350
|
});
|
|
1270
1351
|
});
|
|
1352
|
+
|
|
1353
|
+
describe('MultiSelector clear icon theme target', () => {
|
|
1354
|
+
const ICON_OPTIONS = ['Apple', 'Banana', 'Orange'];
|
|
1355
|
+
|
|
1356
|
+
// Resolve the clear glyph span (the astryx-icon element inside the clear
|
|
1357
|
+
// button), independent of the theme target class.
|
|
1358
|
+
const getClearIcon = (): HTMLElement => {
|
|
1359
|
+
const button = screen.getByRole('button', {name: 'Clear all Fruit'});
|
|
1360
|
+
const icon = button.querySelector('.astryx-icon');
|
|
1361
|
+
if (icon == null) {
|
|
1362
|
+
throw new Error('clear icon not found');
|
|
1363
|
+
}
|
|
1364
|
+
return icon as HTMLElement;
|
|
1365
|
+
};
|
|
1366
|
+
|
|
1367
|
+
it('renders the astryx-multi-selector-clear-icon target on the clear glyph', () => {
|
|
1368
|
+
render(
|
|
1369
|
+
<MultiSelector
|
|
1370
|
+
label="Fruit"
|
|
1371
|
+
options={ICON_OPTIONS}
|
|
1372
|
+
value={['Banana']}
|
|
1373
|
+
onChange={() => {}}
|
|
1374
|
+
hasClear
|
|
1375
|
+
/>,
|
|
1376
|
+
);
|
|
1377
|
+
// The stable theme target lands on the icon element itself (not the
|
|
1378
|
+
// button), so a theme can restyle just this glyph (color, size, hover)
|
|
1379
|
+
// via `defineTheme` — a button-level target could not reach the icon's
|
|
1380
|
+
// own color/size.
|
|
1381
|
+
const icon = getClearIcon();
|
|
1382
|
+
expect(icon).toHaveClass('astryx-multi-selector-clear-icon');
|
|
1383
|
+
expect(icon).toHaveClass('astryx-icon');
|
|
1384
|
+
});
|
|
1385
|
+
|
|
1386
|
+
it('keeps the clear button functional alongside the target', () => {
|
|
1387
|
+
const onChange = vi.fn();
|
|
1388
|
+
render(
|
|
1389
|
+
<MultiSelector
|
|
1390
|
+
label="Fruit"
|
|
1391
|
+
options={ICON_OPTIONS}
|
|
1392
|
+
value={['Banana']}
|
|
1393
|
+
onChange={onChange}
|
|
1394
|
+
hasClear
|
|
1395
|
+
/>,
|
|
1396
|
+
);
|
|
1397
|
+
const clear = screen.getByRole('button', {name: 'Clear all Fruit'});
|
|
1398
|
+
expect(clear.tagName).toBe('BUTTON');
|
|
1399
|
+
fireEvent.click(clear);
|
|
1400
|
+
expect(onChange).toHaveBeenCalledWith([]);
|
|
1401
|
+
});
|
|
1402
|
+
|
|
1403
|
+
it('renders the default icon (secondary color, sm size) byte-identically', () => {
|
|
1404
|
+
// Pixel-identical default guard: the clear glyph must carry the exact same
|
|
1405
|
+
// StyleX color/size classes as a standalone secondary/sm icon. The added
|
|
1406
|
+
// target class is purely additive — it changes nothing until a theme
|
|
1407
|
+
// targets it.
|
|
1408
|
+
render(
|
|
1409
|
+
<MultiSelector
|
|
1410
|
+
label="Fruit"
|
|
1411
|
+
options={ICON_OPTIONS}
|
|
1412
|
+
value={['Banana']}
|
|
1413
|
+
onChange={() => {}}
|
|
1414
|
+
hasClear
|
|
1415
|
+
/>,
|
|
1416
|
+
);
|
|
1417
|
+
const icon = getClearIcon();
|
|
1418
|
+
|
|
1419
|
+
const {container: refContainer} = render(
|
|
1420
|
+
<Icon icon="close" size="sm" color="secondary" />,
|
|
1421
|
+
);
|
|
1422
|
+
const refIcon = refContainer.querySelector('.astryx-icon') as HTMLElement;
|
|
1423
|
+
|
|
1424
|
+
const styleClasses = (el: HTMLElement) =>
|
|
1425
|
+
el.className
|
|
1426
|
+
.split(' ')
|
|
1427
|
+
.filter(c => c !== 'astryx-multi-selector-clear-icon')
|
|
1428
|
+
.sort();
|
|
1429
|
+
|
|
1430
|
+
expect(styleClasses(icon)).toEqual(styleClasses(refIcon));
|
|
1431
|
+
});
|
|
1432
|
+
|
|
1433
|
+
it('exposes multi-selector-clear-icon so a theme reaches the icon color, size, and hover', () => {
|
|
1434
|
+
// jsdom cannot resolve the @layer cascade, so the DOM-class assertion above
|
|
1435
|
+
// (target lands on the icon element) plus this generation assertion (the
|
|
1436
|
+
// theme emits same-element icon rules in @layer astryx-theme) together
|
|
1437
|
+
// prove the seam: a same-element theme rule wins over the icon's own
|
|
1438
|
+
// base-layer color/size.
|
|
1439
|
+
const theme = defineTheme({
|
|
1440
|
+
name: 'multi-selector-clear-icon-test',
|
|
1441
|
+
components: {
|
|
1442
|
+
'multi-selector-clear-icon': {
|
|
1443
|
+
base: {
|
|
1444
|
+
width: '12px',
|
|
1445
|
+
height: '12px',
|
|
1446
|
+
fontSize: '12px',
|
|
1447
|
+
color: 'var(--color-icon-secondary)',
|
|
1448
|
+
':hover': {color: 'var(--color-icon-primary)'},
|
|
1449
|
+
},
|
|
1450
|
+
},
|
|
1451
|
+
},
|
|
1452
|
+
});
|
|
1453
|
+
const css = generateThemeCSSFlat(theme);
|
|
1454
|
+
expect(css).toContain('.astryx-multi-selector-clear-icon {');
|
|
1455
|
+
expect(css).toContain('width: 12px');
|
|
1456
|
+
expect(css).toContain('height: 12px');
|
|
1457
|
+
expect(css).toContain('.astryx-multi-selector-clear-icon:hover {');
|
|
1458
|
+
expect(css).toContain('color: var(--color-icon-primary)');
|
|
1459
|
+
});
|
|
1460
|
+
});
|
|
1461
|
+
|
|
1462
|
+
describe('MultiSelector indicator (chevron) icon theme target', () => {
|
|
1463
|
+
const ICON_OPTIONS = ['Apple', 'Banana', 'Orange'];
|
|
1464
|
+
|
|
1465
|
+
const getIndicatorIcon = (container: HTMLElement): HTMLElement => {
|
|
1466
|
+
// The chevron is the only glyph carrying the indicator target class.
|
|
1467
|
+
const icon = container.querySelector(
|
|
1468
|
+
'.astryx-multi-selector-indicator-icon',
|
|
1469
|
+
);
|
|
1470
|
+
if (icon == null) {
|
|
1471
|
+
throw new Error('indicator icon not found');
|
|
1472
|
+
}
|
|
1473
|
+
return icon as HTMLElement;
|
|
1474
|
+
};
|
|
1475
|
+
|
|
1476
|
+
it('renders the astryx-multi-selector-indicator-icon target on the chevron glyph', () => {
|
|
1477
|
+
const {container} = render(
|
|
1478
|
+
<MultiSelector
|
|
1479
|
+
label="Fruit"
|
|
1480
|
+
options={ICON_OPTIONS}
|
|
1481
|
+
value={[]}
|
|
1482
|
+
onChange={() => {}}
|
|
1483
|
+
/>,
|
|
1484
|
+
);
|
|
1485
|
+
// The stable theme target lands on the icon element itself (not the trigger
|
|
1486
|
+
// button), so a theme can restyle just this glyph (color, size, hover) —
|
|
1487
|
+
// and each open/closed state — via `defineTheme`. A button-level target
|
|
1488
|
+
// could not reach the icon's own color/size.
|
|
1489
|
+
const icon = getIndicatorIcon(container);
|
|
1490
|
+
expect(icon).toHaveClass('astryx-multi-selector-indicator-icon');
|
|
1491
|
+
expect(icon).toHaveClass('astryx-icon');
|
|
1492
|
+
// Open/closed state is reflected so a theme can target each state alone.
|
|
1493
|
+
expect(icon).toHaveAttribute('data-state', 'collapsed');
|
|
1494
|
+
});
|
|
1495
|
+
|
|
1496
|
+
it('reflects the expanded state on the chevron when the popover is open', async () => {
|
|
1497
|
+
const user = userEvent.setup();
|
|
1498
|
+
const {container} = render(
|
|
1499
|
+
<MultiSelector
|
|
1500
|
+
label="Fruit"
|
|
1501
|
+
options={ICON_OPTIONS}
|
|
1502
|
+
value={[]}
|
|
1503
|
+
onChange={() => {}}
|
|
1504
|
+
/>,
|
|
1505
|
+
);
|
|
1506
|
+
await user.click(screen.getByRole('combobox'));
|
|
1507
|
+
await waitFor(() => {
|
|
1508
|
+
expect(getIndicatorIcon(container)).toHaveAttribute(
|
|
1509
|
+
'data-state',
|
|
1510
|
+
'expanded',
|
|
1511
|
+
);
|
|
1512
|
+
});
|
|
1513
|
+
});
|
|
1514
|
+
|
|
1515
|
+
it('renders the default icon (inherit color, sm size) byte-identically', () => {
|
|
1516
|
+
// Pixel-identical default guard: the chevron glyph must carry the exact
|
|
1517
|
+
// same StyleX color/size classes as a standalone inherit/sm icon. The added
|
|
1518
|
+
// target class + data-state are purely additive — they change nothing until
|
|
1519
|
+
// a theme targets them.
|
|
1520
|
+
const {container} = render(
|
|
1521
|
+
<MultiSelector
|
|
1522
|
+
label="Fruit"
|
|
1523
|
+
options={ICON_OPTIONS}
|
|
1524
|
+
value={[]}
|
|
1525
|
+
onChange={() => {}}
|
|
1526
|
+
/>,
|
|
1527
|
+
);
|
|
1528
|
+
const icon = getIndicatorIcon(container);
|
|
1529
|
+
|
|
1530
|
+
const {container: refContainer} = render(
|
|
1531
|
+
<Icon icon="chevronDown" size="sm" color="inherit" />,
|
|
1532
|
+
);
|
|
1533
|
+
const refIcon = refContainer.querySelector('.astryx-icon') as HTMLElement;
|
|
1534
|
+
|
|
1535
|
+
// Exclude the additive theme-target classes (the stable target + its
|
|
1536
|
+
// reflected state class) so only the StyleX color/size classes remain.
|
|
1537
|
+
const themeTargetClasses = new Set([
|
|
1538
|
+
'astryx-multi-selector-indicator-icon',
|
|
1539
|
+
'collapsed',
|
|
1540
|
+
'expanded',
|
|
1541
|
+
]);
|
|
1542
|
+
const styleClasses = (el: HTMLElement) =>
|
|
1543
|
+
el.className
|
|
1544
|
+
.split(' ')
|
|
1545
|
+
.filter(c => !themeTargetClasses.has(c))
|
|
1546
|
+
.sort();
|
|
1547
|
+
|
|
1548
|
+
expect(styleClasses(icon)).toEqual(styleClasses(refIcon));
|
|
1549
|
+
});
|
|
1550
|
+
|
|
1551
|
+
it('exposes multi-selector-indicator-icon so a theme reaches the icon size and per-state color', () => {
|
|
1552
|
+
// jsdom cannot resolve the @layer cascade, so the DOM-class assertions
|
|
1553
|
+
// above (target lands on the icon element) plus this generation assertion
|
|
1554
|
+
// (the theme emits same-element icon rules in @layer astryx-theme) together
|
|
1555
|
+
// prove the seam: a same-element theme rule wins over the icon's own
|
|
1556
|
+
// base-layer color/size.
|
|
1557
|
+
const theme = defineTheme({
|
|
1558
|
+
name: 'multi-selector-indicator-icon-test',
|
|
1559
|
+
components: {
|
|
1560
|
+
'multi-selector-indicator-icon': {
|
|
1561
|
+
base: {width: '14px', height: '14px', fontSize: '14px'},
|
|
1562
|
+
'state:expanded': {color: 'var(--color-icon-primary)'},
|
|
1563
|
+
},
|
|
1564
|
+
},
|
|
1565
|
+
});
|
|
1566
|
+
const css = generateThemeCSSFlat(theme);
|
|
1567
|
+
expect(css).toContain('.astryx-multi-selector-indicator-icon {');
|
|
1568
|
+
expect(css).toContain('width: 14px');
|
|
1569
|
+
expect(css).toContain('height: 14px');
|
|
1570
|
+
expect(css).toContain('.astryx-multi-selector-indicator-icon.expanded');
|
|
1571
|
+
expect(css).toContain('color: var(--color-icon-primary)');
|
|
1572
|
+
});
|
|
1573
|
+
});
|