@astryxdesign/core 0.7.1-canary.ff40b78 → 0.7.1
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 +116 -0
- package/dist/Button/Button.d.ts +1 -1
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +5 -2
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +191 -32
- package/dist/Chat/ChatComposerInput.d.ts +9 -0
- package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
- package/dist/Chat/ChatComposerInput.js +5 -0
- package/dist/Chat/ChatMessage.d.ts +11 -0
- package/dist/Chat/ChatMessage.d.ts.map +1 -1
- package/dist/Chat/ChatMessage.js +18 -9
- package/dist/Chat/useTriggerMenu.d.ts +9 -2
- package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
- package/dist/Chat/useTriggerMenu.js +222 -50
- package/dist/CodeBlock/CodeBlock.d.ts +10 -1
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +158 -38
- package/dist/CodeBlock/tokenizer.d.ts +39 -0
- package/dist/CodeBlock/tokenizer.d.ts.map +1 -1
- package/dist/CodeBlock/tokenizer.js +108 -0
- package/dist/CommandPalette/CommandPalette.d.ts +9 -5
- package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPalette.js +38 -20
- package/dist/CommandPalette/CommandPaletteEmpty.d.ts +4 -3
- package/dist/CommandPalette/CommandPaletteEmpty.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteEmpty.js +4 -3
- package/dist/CommandPalette/CommandPaletteInput.d.ts +5 -4
- package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteInput.js +35 -18
- package/dist/CommandPalette/CommandPaletteItem.d.ts +11 -6
- package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteItem.js +8 -9
- package/dist/CommandPalette/CommandPaletteList.d.ts +4 -2
- package/dist/CommandPalette/CommandPaletteList.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteList.js +10 -5
- package/dist/ComplexSelector/ComplexSelector.d.ts +8 -5
- package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
- package/dist/ComplexSelector/ComplexSelector.js +12 -3
- package/dist/ContextMenu/ContextMenu.d.ts +3 -3
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +62 -48
- package/dist/DateInput/DateInput.js +1 -1
- package/dist/DateInput/MonthScroller.d.ts.map +1 -1
- package/dist/DateInput/MonthScroller.js +12 -4
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +12 -2
- package/dist/Dialog/Dialog.d.ts +1 -1
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +16 -5
- package/dist/Dialog/DialogHeader.d.ts +1 -1
- package/dist/Dialog/DialogHeader.d.ts.map +1 -1
- package/dist/Dialog/DialogHeader.js +7 -7
- package/dist/Divider/Divider.d.ts +1 -0
- package/dist/Divider/Divider.d.ts.map +1 -1
- package/dist/Divider/Divider.js +5 -4
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +161 -65
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +7 -5
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +12 -5
- package/dist/Field/InputClearButton.d.ts +8 -4
- package/dist/Field/InputClearButton.d.ts.map +1 -1
- package/dist/Field/InputClearButton.js +23 -7
- package/dist/FormLayout/FormLayout.d.ts.map +1 -1
- package/dist/FormLayout/FormLayout.js +1 -0
- package/dist/Grid/Grid.d.ts +13 -4
- package/dist/Grid/Grid.d.ts.map +1 -1
- package/dist/Grid/Grid.js +7 -1
- package/dist/HoverCard/useHoverCard.d.ts +1 -1
- package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
- package/dist/HoverCard/useHoverCard.js +67 -49
- package/dist/InputGroup/InputGroup.d.ts +2 -4
- package/dist/InputGroup/InputGroup.d.ts.map +1 -1
- package/dist/InputGroup/InputGroup.js +2 -4
- package/dist/InputGroup/groupStyles.d.ts +10 -2
- package/dist/InputGroup/groupStyles.d.ts.map +1 -1
- package/dist/InputGroup/groupStyles.js +19 -2
- package/dist/Layer/useLayerDismissal.d.ts +9 -9
- package/dist/Layer/useLayerDismissal.js +9 -9
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.js +25 -4
- package/dist/MobileNav/MobileNav.d.ts +7 -0
- package/dist/MobileNav/MobileNav.d.ts.map +1 -1
- package/dist/MobileNav/MobileNav.js +45 -2
- package/dist/MultiSelector/MultiSelector.d.ts +7 -4
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +24 -3
- package/dist/NumberInput/NumberInput.js +1 -1
- package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchEditPopover.js +6 -0
- package/dist/Resizable/ResizeHandle.d.ts +1 -1
- package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
- package/dist/Resizable/ResizeHandle.js +83 -15
- package/dist/Resizable/useResizable.d.ts +23 -0
- package/dist/Resizable/useResizable.d.ts.map +1 -1
- package/dist/Resizable/useResizable.js +78 -0
- package/dist/Selector/Selector.d.ts +6 -3
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +28 -6
- package/dist/SideNav/SideNav.d.ts.map +1 -1
- package/dist/SideNav/SideNav.js +10 -2
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +18 -7
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +16 -4
- package/dist/Toolbar/Toolbar.d.ts +2 -1
- package/dist/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/Toolbar/Toolbar.js +3 -1
- package/dist/TreeList/TreeList.d.ts.map +1 -1
- package/dist/TreeList/TreeList.js +6 -3
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +7 -1
- package/dist/astryx.css +22 -0
- package/dist/hooks/useScrollOverflow.d.ts.map +1 -1
- package/dist/hooks/useScrollOverflow.js +55 -12
- package/dist/hooks/useTreeFocus.d.ts +21 -0
- package/dist/hooks/useTreeFocus.d.ts.map +1 -1
- package/dist/hooks/useTreeFocus.js +40 -2
- package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/en.generated.js +3 -0
- package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/pseudo.generated.js +3 -0
- package/dist/reset.a11y.chromium.spec.js +6 -1
- package/dist/reset.until-found.a11y.browser.spec.d.ts +2 -0
- package/dist/reset.until-found.a11y.browser.spec.d.ts.map +1 -0
- package/dist/reset.until-found.a11y.browser.spec.js +71 -0
- package/dist/theme/syntax/SyntaxTheme.d.ts.map +1 -1
- package/dist/theme/syntax/SyntaxTheme.js +43 -2
- package/dist/theme/syntax/defineSyntaxTheme.d.ts +18 -5
- package/dist/theme/syntax/defineSyntaxTheme.d.ts.map +1 -1
- package/dist/theme/syntax/defineSyntaxTheme.js +38 -9
- package/dist/theme/syntax/index.d.ts +1 -1
- package/dist/theme/syntax/index.d.ts.map +1 -1
- package/dist/theme/syntax/tokens.d.ts +12 -2
- package/dist/theme/syntax/tokens.d.ts.map +1 -1
- package/dist/theme/syntax/tokens.js +25 -4
- package/dist/utils/plainDate.d.ts +12 -0
- package/dist/utils/plainDate.d.ts.map +1 -1
- package/dist/utils/plainDate.js +63 -10
- package/locales/en.json +13 -1
- package/locales/pseudo.json +9 -0
- package/package.json +4 -4
- package/src/AlertDialog/AlertDialog.doc.mjs +6 -0
- package/src/AlertDialog/AlertDialog.spec.md +205 -0
- package/src/AlertDialog/AlertDialog.test.tsx +3 -14
- package/src/AlertDialog/__tests__/AlertDialog.a11y.chromium.spec.ts +115 -0
- package/src/AlertDialog/__tests__/AlertDialog.a11y.renders.tsx +52 -0
- package/src/AlertDialog/__tests__/AlertDialog.a11y.states.ts +68 -0
- package/src/AlertDialog/__tests__/AlertDialog.a11y.test.tsx +144 -0
- package/src/Button/Button.test.tsx +37 -0
- package/src/Button/Button.tsx +5 -1
- package/src/Calendar/Calendar.doc.mjs +234 -60
- package/src/Calendar/Calendar.spec.md +209 -0
- package/src/Calendar/Calendar.test.tsx +559 -20
- package/src/Calendar/Calendar.tsx +258 -41
- package/src/Calendar/__tests__/Calendar.a11y.chromium.spec.ts +126 -0
- package/src/Calendar/__tests__/Calendar.a11y.known-failures.ts +12 -0
- package/src/Calendar/__tests__/Calendar.a11y.renders.tsx +57 -0
- package/src/Calendar/__tests__/Calendar.a11y.states.ts +139 -0
- package/src/Calendar/__tests__/Calendar.a11y.test.tsx +137 -0
- package/src/Carousel/Carousel.test.tsx +54 -71
- package/src/Carousel/__tests__/Carousel.a11y.chromium.spec.ts +192 -0
- package/src/Carousel/__tests__/Carousel.a11y.known-failures.ts +27 -0
- package/src/Carousel/__tests__/Carousel.a11y.renders.tsx +39 -0
- package/src/Carousel/__tests__/Carousel.a11y.states.ts +139 -0
- package/src/Carousel/__tests__/Carousel.a11y.test.tsx +127 -0
- package/src/Chat/ChatComposerInput.doc.mjs +1 -1
- package/src/Chat/ChatComposerInput.spec.md +94 -55
- package/src/Chat/ChatComposerInput.test.tsx +202 -1
- package/src/Chat/ChatComposerInput.tsx +13 -0
- package/src/Chat/ChatMessage.doc.mjs +31 -16
- package/src/Chat/ChatMessage.spec.md +265 -0
- package/src/Chat/ChatMessage.test.tsx +246 -0
- package/src/Chat/ChatMessage.tsx +30 -7
- package/src/Chat/ChatSystemMessage.spec.md +36 -37
- package/src/Chat/ChatSystemMessage.test.tsx +4 -4
- package/src/Chat/useTriggerMenu.test.tsx +994 -0
- package/src/Chat/useTriggerMenu.tsx +278 -46
- package/src/CodeBlock/CodeBlock.doc.mjs +7 -0
- package/src/CodeBlock/CodeBlock.spec.md +40 -41
- package/src/CodeBlock/CodeBlock.test.tsx +89 -9
- package/src/CodeBlock/CodeBlock.tsx +205 -25
- package/src/CodeBlock/__tests__/CodeBlockOverflowStop.a11y.chromium.spec.ts +125 -0
- package/src/CodeBlock/__tests__/DiffRowPaint.a11y.chromium.spec.ts +93 -0
- package/src/CodeBlock/tokenizer.test.ts +112 -0
- package/src/CodeBlock/tokenizer.ts +106 -0
- package/src/Collapsible/CollapsibleGroup.spec.md +17 -8
- package/src/Collapsible/__tests__/CollapsibleGroup.a11y.renders.tsx +45 -0
- package/src/Collapsible/__tests__/CollapsibleGroup.a11y.states.ts +139 -0
- package/src/Collapsible/__tests__/CollapsibleGroup.a11y.test.tsx +135 -0
- package/src/Collapsible/__tests__/CollapsibleGroupAccordion.a11y.chromium.spec.ts +128 -0
- package/src/CommandPalette/CommandPalette.doc.mjs +126 -23
- package/src/CommandPalette/CommandPalette.spec.md +100 -49
- package/src/CommandPalette/CommandPalette.test.tsx +241 -2
- package/src/CommandPalette/CommandPalette.tsx +47 -21
- package/src/CommandPalette/CommandPaletteEmpty.tsx +4 -3
- package/src/CommandPalette/CommandPaletteInput.doc.mjs +61 -4
- package/src/CommandPalette/CommandPaletteInput.spec.md +215 -0
- package/src/CommandPalette/CommandPaletteInput.test.tsx +375 -51
- package/src/CommandPalette/CommandPaletteInput.tsx +74 -21
- package/src/CommandPalette/CommandPaletteItem.doc.mjs +73 -22
- package/src/CommandPalette/CommandPaletteItem.spec.md +223 -0
- package/src/CommandPalette/CommandPaletteItem.test.tsx +200 -5
- package/src/CommandPalette/CommandPaletteItem.tsx +16 -11
- package/src/CommandPalette/CommandPaletteList.doc.mjs +3 -3
- package/src/CommandPalette/CommandPaletteList.spec.md +41 -36
- package/src/CommandPalette/CommandPaletteList.test.tsx +80 -0
- package/src/CommandPalette/CommandPaletteList.tsx +10 -5
- package/src/CommandPalette/__tests__/CommandPalette.a11y.chromium.spec.ts +599 -0
- package/src/ComplexSelector/ComplexSelector.doc.mjs +10 -8
- package/src/ComplexSelector/ComplexSelector.spec.md +14 -9
- package/src/ComplexSelector/ComplexSelector.test.tsx +64 -16
- package/src/ComplexSelector/ComplexSelector.tsx +37 -8
- package/src/ContextMenu/ContextMenu.doc.mjs +6 -0
- package/src/ContextMenu/ContextMenu.spec.md +51 -53
- package/src/ContextMenu/ContextMenu.test.tsx +132 -1
- package/src/ContextMenu/ContextMenu.tsx +78 -48
- package/src/DateInput/DateInput.doc.mjs +52 -0
- package/src/DateInput/DateInput.spec.md +27 -15
- package/src/DateInput/DateInput.test.tsx +38 -0
- package/src/DateInput/DateInput.tsx +1 -1
- package/src/DateInput/DateInputTouch.test.tsx +22 -0
- package/src/DateInput/MonthScroller.tsx +12 -4
- package/src/DateRangeInput/DateRangeInput.test.tsx +49 -0
- package/src/DateRangeInput/DateRangeInput.tsx +20 -2
- package/src/Dialog/Dialog.test.tsx +27 -1
- package/src/Dialog/Dialog.tsx +16 -5
- package/src/Dialog/DialogHeader.test.tsx +27 -2
- package/src/Dialog/DialogHeader.tsx +7 -8
- package/src/Dialog/__tests__/Dialog.a11y.chromium.spec.ts +21 -14
- package/src/Divider/Divider.doc.mjs +5 -3
- package/src/Divider/Divider.spec.md +140 -54
- package/src/Divider/Divider.test.tsx +15 -0
- package/src/Divider/Divider.tsx +6 -4
- package/src/DropdownMenu/DropdownMenu.doc.mjs +2 -2
- package/src/DropdownMenu/DropdownMenu.spec.md +121 -45
- package/src/DropdownMenu/DropdownMenu.test.tsx +288 -23
- package/src/DropdownMenu/DropdownMenu.tsx +212 -81
- package/src/DropdownMenu/DropdownMenuCheckboxItem.doc.mjs +38 -2
- package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +32 -18
- package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +146 -1
- package/src/DropdownMenu/__tests__/MenuButton.a11y.chromium.spec.ts +136 -0
- package/src/DropdownMenu/__tests__/MenuButton.a11y.known-failures.ts +12 -0
- package/src/DropdownMenu/__tests__/MenuButton.a11y.renders.tsx +67 -0
- package/src/DropdownMenu/__tests__/MenuButton.a11y.states.ts +141 -0
- package/src/DropdownMenu/__tests__/MenuButton.a11y.test.tsx +138 -0
- package/src/DropdownMenu/__tests__/MenuHeaderFooter.a11y.chromium.spec.ts +40 -5
- package/src/Field/InputClearButton.test.tsx +29 -4
- package/src/Field/InputClearButton.tsx +26 -8
- package/src/FieldStatus/__tests__/StatusMessage.a11y.chromium.spec.ts +21 -14
- package/src/FormLayout/FormLayout.tsx +1 -0
- package/src/FormLayout/__snapshots__/FormLayout.test.tsx.snap +1 -1
- package/src/Grid/Grid.doc.mjs +14 -11
- package/src/Grid/Grid.spec.md +50 -32
- package/src/Grid/Grid.tsx +13 -4
- package/src/HoverCard/HoverCard.test.tsx +46 -1
- package/src/HoverCard/useHoverCard.tsx +68 -48
- package/src/InputGroup/InputGroup.doc.mjs +11 -1
- package/src/InputGroup/InputGroup.tsx +2 -4
- package/src/InputGroup/groupStyles.ts +40 -2
- package/src/Layer/useLayerDismissal.ts +9 -9
- package/src/Link/__tests__/Link.a11y.chromium.spec.ts +142 -0
- package/src/Link/__tests__/Link.a11y.renders.tsx +97 -0
- package/src/Link/__tests__/Link.a11y.states.ts +104 -0
- package/src/Link/__tests__/Link.a11y.test.tsx +127 -0
- package/src/Markdown/Markdown.doc.mjs +1 -1
- package/src/Markdown/Markdown.fr23.perf.test.ts +161 -40
- package/src/Markdown/Markdown.spec.md +45 -23
- package/src/Markdown/Markdown.test.tsx +38 -0
- package/src/Markdown/Markdown.tsx +24 -2
- package/src/Markdown/plugins/semanticFence.test.tsx +3 -2
- package/src/MobileNav/MobileNav.tsx +50 -2
- package/src/MobileNav/MobileNavFocus.test.tsx +553 -0
- package/src/MoreMenu/MoreMenu.spec.md +18 -7
- package/src/MoreMenu/MoreMenu.test.tsx +38 -0
- package/src/MultiSelector/MultiSelector.doc.mjs +8 -8
- package/src/MultiSelector/MultiSelector.spec.md +1 -1
- package/src/MultiSelector/MultiSelector.test.tsx +188 -21
- package/src/MultiSelector/MultiSelector.tsx +50 -11
- package/src/NumberInput/NumberInput.test.tsx +24 -0
- package/src/NumberInput/NumberInput.tsx +1 -1
- package/src/NumberInput/__tests__/NumberInput.a11y.chromium.spec.ts +22 -15
- package/src/PowerSearch/PowerSearchEditPopover.test.tsx +78 -0
- package/src/PowerSearch/PowerSearchEditPopover.tsx +6 -0
- package/src/Resizable/Resizable.spec.md +41 -9
- package/src/Resizable/ResizeHandle.test.tsx +565 -2
- package/src/Resizable/ResizeHandle.tsx +126 -21
- package/src/Resizable/__tests__/ResizeHandle.a11y.chromium.spec.ts +119 -0
- package/src/Resizable/__tests__/ResizeHandle.a11y.known-failures.ts +39 -0
- package/src/Resizable/__tests__/ResizeHandle.a11y.renders.tsx +80 -0
- package/src/Resizable/__tests__/ResizeHandle.a11y.states.ts +197 -0
- package/src/Resizable/__tests__/ResizeHandle.a11y.test.tsx +123 -0
- package/src/Resizable/useResizable.ts +95 -0
- package/src/Selector/Selector.doc.mjs +7 -6
- package/src/Selector/Selector.spec.md +37 -24
- package/src/Selector/Selector.test.tsx +176 -10
- package/src/Selector/Selector.tsx +59 -14
- package/src/Selector/__tests__/Combobox.a11y.known-failures.ts +27 -0
- package/src/Selector/__tests__/Combobox.a11y.states.ts +145 -0
- package/src/Selector/__tests__/Selector.combobox.a11y.chromium.spec.ts +108 -0
- package/src/Selector/__tests__/Selector.combobox.a11y.test.tsx +126 -0
- package/src/SideNav/SideNav.test.tsx +35 -0
- package/src/SideNav/SideNav.tsx +16 -2
- package/src/Slider/Slider.spec.md +43 -17
- package/src/Slider/Slider.test.tsx +134 -0
- package/src/Slider/Slider.tsx +29 -6
- package/src/Slider/__tests__/Slider.a11y.chromium.spec.ts +112 -0
- package/src/Slider/__tests__/Slider.a11y.known-failures.ts +12 -0
- package/src/Slider/__tests__/Slider.a11y.renders.tsx +42 -0
- package/src/Slider/__tests__/Slider.a11y.states.ts +106 -0
- package/src/Slider/__tests__/Slider.a11y.test.tsx +105 -0
- package/src/Switch/__tests__/Switch.a11y.chromium.spec.ts +25 -18
- package/src/TabList/__tests__/Tabs.a11y.chromium.spec.ts +19 -12
- package/src/TextInput/__tests__/TextInput.a11y.chromium.spec.ts +21 -14
- package/src/ToggleButton/__tests__/ToggleButton.a11y.chromium.spec.ts +18 -11
- package/src/Tokenizer/Tokenizer.test.tsx +87 -0
- package/src/Tokenizer/Tokenizer.tsx +31 -3
- package/src/Toolbar/Toolbar.test.tsx +131 -4
- package/src/Toolbar/Toolbar.tsx +3 -1
- package/src/TreeList/TreeList.spec.md +33 -8
- package/src/TreeList/TreeList.test.tsx +72 -0
- package/src/TreeList/TreeList.tsx +10 -6
- package/src/TreeList/TreeListItem.tsx +5 -0
- package/src/TreeList/__tests__/TreeList.a11y.chromium.spec.ts +125 -0
- package/src/TreeList/__tests__/TreeList.a11y.renders.tsx +44 -0
- package/src/TreeList/__tests__/TreeList.a11y.states.ts +164 -0
- package/src/TreeList/__tests__/TreeList.a11y.test.tsx +138 -0
- package/src/TreeList/__tests__/TreeListRowNames.a11y.chromium.spec.ts +82 -0
- package/src/hooks/useScrollOverflow.test.tsx +222 -0
- package/src/hooks/useScrollOverflow.ts +55 -13
- package/src/hooks/useTreeFocus.test.tsx +37 -0
- package/src/hooks/useTreeFocus.ts +55 -2
- package/src/i18n/generated-locales/en.generated.ts +3 -0
- package/src/i18n/generated-locales/pseudo.generated.ts +3 -0
- package/src/reset.a11y.chromium.spec.ts +9 -1
- package/src/reset.css +8 -3
- package/src/reset.until-found.a11y.browser.spec.ts +75 -0
- package/src/reset.until-found.test.ts +32 -0
- package/src/stylexValidation.source-build.test.mjs +42 -0
- package/src/theme/syntax/SyntaxTheme.tsx +46 -5
- package/src/theme/syntax/defineSyntaxTheme.diff.test.ts +91 -0
- package/src/theme/syntax/defineSyntaxTheme.ts +75 -15
- package/src/theme/syntax/index.ts +5 -1
- package/src/theme/syntax/tokens.ts +32 -2
- package/src/theme/syntax/useSyntaxTheme.diff.test.tsx +40 -0
- package/src/utils/plainDate.test.ts +147 -0
- package/src/utils/plainDate.ts +75 -10
|
@@ -7,47 +7,93 @@ export const docs = {
|
|
|
7
7
|
subComponentOf: 'CommandPalette',
|
|
8
8
|
displayName: 'Command Palette Item',
|
|
9
9
|
isHiddenFromOverview: true,
|
|
10
|
-
description:
|
|
10
|
+
description:
|
|
11
|
+
'One option in a command palette result list. CommandPalette context supplies selection, highlight, identity, and close behavior.',
|
|
12
|
+
usage: {
|
|
13
|
+
description:
|
|
14
|
+
'Use CommandPaletteItem for one non-interactive result row inside CommandPaletteList or CommandPaletteGroup. CommandPalette owns the composite keyboard model; standalone items expose only their explicit visual state and pointer activation.',
|
|
15
|
+
bestPractices: [
|
|
16
|
+
{
|
|
17
|
+
guidance: true,
|
|
18
|
+
description:
|
|
19
|
+
'Keep each value unique within the result list so highlight, active-descendant identity, and selection resolve to the same item.',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
guidance: true,
|
|
23
|
+
description:
|
|
24
|
+
'Use non-interactive child content such as icons, descriptions, and shortcut hints; activate the option itself instead of nesting buttons or links.',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
guidance: false,
|
|
28
|
+
description:
|
|
29
|
+
'Treat isHighlighted as selection. Highlight is the active keyboard result; isSelected represents the chosen value.',
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
anatomy: [
|
|
33
|
+
{
|
|
34
|
+
name: 'Item',
|
|
35
|
+
required: true,
|
|
36
|
+
description:
|
|
37
|
+
'The option root that carries selection, disabled, item identity, interaction, and theme state.',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'Content',
|
|
41
|
+
required: true,
|
|
42
|
+
description:
|
|
43
|
+
'Caller-provided non-interactive label and supporting presentation.',
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
theming: {
|
|
48
|
+
targets: [{className: 'astryx-command-palette-item'}],
|
|
49
|
+
},
|
|
11
50
|
props: [
|
|
12
51
|
{
|
|
13
52
|
name: 'value',
|
|
14
53
|
type: 'string',
|
|
15
|
-
description:
|
|
54
|
+
description:
|
|
55
|
+
'Unique value used for item identity, highlight lookup, and selection.',
|
|
16
56
|
required: true,
|
|
17
57
|
},
|
|
18
58
|
{
|
|
19
59
|
name: 'children',
|
|
20
60
|
type: 'ReactNode',
|
|
21
|
-
description:
|
|
61
|
+
description:
|
|
62
|
+
'Non-interactive item content such as a label, icon, description, or keyboard shortcut.',
|
|
22
63
|
required: true,
|
|
23
64
|
},
|
|
24
65
|
{
|
|
25
66
|
name: 'onSelect',
|
|
26
67
|
type: '(value: string) => void',
|
|
27
|
-
description:
|
|
68
|
+
description:
|
|
69
|
+
'Called after this item is activated by pointer. Keyboard selection in CommandPalette reports through CommandPalette onValueChange.',
|
|
28
70
|
},
|
|
29
71
|
{
|
|
30
72
|
name: 'isHighlighted',
|
|
31
73
|
type: 'boolean',
|
|
32
|
-
description:
|
|
74
|
+
description:
|
|
75
|
+
'Whether this item is the active keyboard result. Derived from context when omitted inside CommandPalette.',
|
|
33
76
|
default: 'false',
|
|
34
77
|
},
|
|
35
78
|
{
|
|
36
79
|
name: 'isSelected',
|
|
37
80
|
type: 'boolean',
|
|
38
|
-
description:
|
|
81
|
+
description:
|
|
82
|
+
'Whether this item represents the selected value in picker mode.',
|
|
39
83
|
default: 'false',
|
|
40
84
|
},
|
|
41
85
|
{
|
|
42
86
|
name: 'isDisabled',
|
|
43
87
|
type: 'boolean',
|
|
44
|
-
description:
|
|
88
|
+
description:
|
|
89
|
+
'Whether the item is unavailable and suppresses pointer activation.',
|
|
45
90
|
default: 'false',
|
|
46
91
|
},
|
|
47
92
|
{
|
|
48
93
|
name: 'xstyle',
|
|
49
94
|
type: 'StyleXStyles',
|
|
50
|
-
description:
|
|
95
|
+
description:
|
|
96
|
+
'StyleX styles for layout customization. Must be a stylex.create() value.',
|
|
51
97
|
},
|
|
52
98
|
],
|
|
53
99
|
playground: {
|
|
@@ -62,14 +108,17 @@ export const docsZh = {
|
|
|
62
108
|
name: 'CommandPaletteItem',
|
|
63
109
|
isHiddenFromOverview: true,
|
|
64
110
|
displayName: 'Command Palette Item',
|
|
65
|
-
description:
|
|
111
|
+
description:
|
|
112
|
+
'命令面板结果列表中的一个选项。CommandPalette 上下文提供选择、高亮、标识和关闭行为。',
|
|
66
113
|
propDescriptions: {
|
|
67
|
-
value: '
|
|
68
|
-
children: '
|
|
69
|
-
onSelect:
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
114
|
+
value: '用于条目标识、高亮查找和选择的唯一值。',
|
|
115
|
+
children: '非交互式条目内容,例如标签、图标、描述或键盘快捷键。',
|
|
116
|
+
onSelect:
|
|
117
|
+
'通过指针激活此条目后调用。CommandPalette 中的键盘选择通过根组件的 onValueChange 报告。',
|
|
118
|
+
isHighlighted:
|
|
119
|
+
'此条目是否为当前键盘结果。在 CommandPalette 内省略时从上下文派生。',
|
|
120
|
+
isSelected: '此条目是否代表选择器模式中的已选值。',
|
|
121
|
+
isDisabled: '条目是否不可用并禁止指针激活。',
|
|
73
122
|
xstyle: 'StyleX 布局自定义样式。必须是 stylex.create() 的值。',
|
|
74
123
|
},
|
|
75
124
|
};
|
|
@@ -78,14 +127,16 @@ export const docsDense = {
|
|
|
78
127
|
name: 'CommandPaletteItem',
|
|
79
128
|
isHiddenFromOverview: true,
|
|
80
129
|
displayName: 'Command Palette Item',
|
|
81
|
-
description:
|
|
130
|
+
description:
|
|
131
|
+
'one result option; context owns selection, highlight, identity, and close',
|
|
82
132
|
propDescriptions: {
|
|
83
|
-
value: 'unique
|
|
84
|
-
children: '
|
|
85
|
-
onSelect:
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
133
|
+
value: 'unique value for identity, highlight lookup, and selection',
|
|
134
|
+
children: 'non-interactive label and supporting content',
|
|
135
|
+
onSelect:
|
|
136
|
+
'called after pointer activation; palette keyboard selection uses root onValueChange',
|
|
137
|
+
isHighlighted: 'active keyboard result; derived from context when omitted',
|
|
138
|
+
isSelected: 'selected value in picker mode',
|
|
139
|
+
isDisabled: 'unavailable; suppresses pointer activation',
|
|
89
140
|
xstyle: 'StyleX layout styles; must be stylex.create() value',
|
|
90
141
|
},
|
|
91
142
|
};
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 3
|
|
3
|
+
template_version: 7
|
|
4
|
+
kind: component
|
|
5
|
+
id: component:CommandPaletteItem
|
|
6
|
+
authority: draft
|
|
7
|
+
archive_reason: null
|
|
8
|
+
superseded_by: null
|
|
9
|
+
approved_by: null
|
|
10
|
+
approved_at: null
|
|
11
|
+
owners: [cixzhang]
|
|
12
|
+
review_triggers: [behavior, accessibility, public-api, compatibility, theming]
|
|
13
|
+
verified_by:
|
|
14
|
+
[
|
|
15
|
+
packages/core/src/CommandPalette/CommandPaletteItem.test.tsx,
|
|
16
|
+
packages/core/src/CommandPalette/CommandPalette.test.tsx,
|
|
17
|
+
packages/core/src/theme/themingTargets.test.ts,
|
|
18
|
+
apps/storybook/stories/CommandPaletteItem.stories.tsx,
|
|
19
|
+
apps/storybook/rtl-audit/targets.json,
|
|
20
|
+
scripts/check-knowledge.mjs,
|
|
21
|
+
]
|
|
22
|
+
modules: []
|
|
23
|
+
families: []
|
|
24
|
+
design_specs: []
|
|
25
|
+
architecture:
|
|
26
|
+
[
|
|
27
|
+
architecture:component-test-sufficiency,
|
|
28
|
+
architecture:component-theming-surface,
|
|
29
|
+
architecture:interaction-modality,
|
|
30
|
+
architecture:public-component-api,
|
|
31
|
+
]
|
|
32
|
+
contributing: []
|
|
33
|
+
system_specs: [spec:AST-017, spec:AST-020]
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
# CommandPaletteItem component contract
|
|
37
|
+
|
|
38
|
+
## Contract at a glance
|
|
39
|
+
|
|
40
|
+
| Area | Contract |
|
|
41
|
+
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
42
|
+
| Public contract | One result option with context-backed identity, highlight, selection, and close behavior; explicit standalone visual state and pointer activation remain available. |
|
|
43
|
+
| Behavior | Consumer click runs first; cancellation stops selection; successful activation reports locally, updates context, and closes; disabled items run no click callbacks. |
|
|
44
|
+
| End-user impact | Disabled commands cannot activate, and keyboard focus, selected value, and option identity remain distinct and consistently exposed. |
|
|
45
|
+
| Builder impact | Values stay unique; children stay non-interactive; CommandPalette owns composite keyboard navigation and reports keyboard selection through root `onValueChange`. |
|
|
46
|
+
| Compatibility/readiness | Victim-free `[fix]` restores promised disabled and native-passthrough behavior; the standalone keyboard contract remains unsettled. |
|
|
47
|
+
| Review checks | Reject disabled activation, dropped standalone DOM identity, highlight-as-selection ARIA, nested interactive children, or a second context scroll owner. |
|
|
48
|
+
| Governing rules | `architecture:public-component-api/INV5,INV7`; `architecture:interaction-modality`; `spec:AST-017/FR1,FR3,FR5`; `spec:AST-020/FR1,FR2`; WAI-ARIA 1.2 `option`. |
|
|
49
|
+
|
|
50
|
+
This table is a review projection; the body below is authoritative.
|
|
51
|
+
|
|
52
|
+
## Intent
|
|
53
|
+
|
|
54
|
+
CommandPaletteItem presents one command result as an option. CommandPalette
|
|
55
|
+
context supplies composite state and keyboard ownership; the item owns its option
|
|
56
|
+
semantics, visual states, pointer activation, native passthrough boundary, and
|
|
57
|
+
standalone scroll behavior.
|
|
58
|
+
|
|
59
|
+
## Compatibility and migration
|
|
60
|
+
|
|
61
|
+
- Released default preserved: `yes`
|
|
62
|
+
- Compatibility class: victim-free contract restoration under
|
|
63
|
+
`spec:AST-017/FR1,FR3,FR5`; `isDisabled` already promises a non-interactive
|
|
64
|
+
item and the native `BaseProps` seam already promises standalone DOM props
|
|
65
|
+
- Controlled/uncontrolled behavior: explicit item state still precedes context
|
|
66
|
+
state, then the existing false default
|
|
67
|
+
- Migration decision: none for these corrections; OQ1 holds any change to the
|
|
68
|
+
standalone keyboard contract
|
|
69
|
+
- Documentation compatibility: item `onSelect` reports pointer activation only.
|
|
70
|
+
No public runtime path delivers Enter to it — CommandPalette mints rows without
|
|
71
|
+
item callbacks and standalone items have no keyboard owner — so describing
|
|
72
|
+
keyboard selection through root `onValueChange` leaves no released consumer
|
|
73
|
+
behind (`spec:AST-017/FR1,FR5`). OQ1 owns any standalone keyboard path.
|
|
74
|
+
|
|
75
|
+
Consumer migration instructions belong in consumer docs and release notes.
|
|
76
|
+
|
|
77
|
+
## Ownership boundary
|
|
78
|
+
|
|
79
|
+
**Owns**
|
|
80
|
+
|
|
81
|
+
- The option root, item value marker, selected and disabled ARIA state, and
|
|
82
|
+
`command-palette-item` theme target.
|
|
83
|
+
- Explicit → CommandPalette context → false precedence for highlighted and
|
|
84
|
+
selected visual state.
|
|
85
|
+
- Pointer activation order, disabled suppression, and context selection/close.
|
|
86
|
+
- Standalone highlighted-item scroll behavior and the inline-preview initial
|
|
87
|
+
scroll suppression.
|
|
88
|
+
|
|
89
|
+
**Does not own / non-goals**
|
|
90
|
+
|
|
91
|
+
- CommandPalette's listbox, query-field active descendant, arrow-key navigation,
|
|
92
|
+
Enter handling, search results, or root `onValueChange` callback.
|
|
93
|
+
- Grouping, list layout, or caller-provided non-interactive item content.
|
|
94
|
+
- A standalone composite listbox keyboard model; its direction remains OQ1.
|
|
95
|
+
- Interactive descendants. Buttons and links are sibling actions or separate
|
|
96
|
+
commands, not content inside an option.
|
|
97
|
+
|
|
98
|
+
## Public concepts
|
|
99
|
+
|
|
100
|
+
| Concept | Closed values or states | Meaning | Availability | Default | Owner | Stability | Invalid-value behavior |
|
|
101
|
+
| ------------- | --------------------------------------------------- | ------------------------------------------------- | ------------------------ | ------- | ------------------------------ | --------- | --------------------------------------------------------- |
|
|
102
|
+
| Highlight | explicit; context index; false | Active keyboard result, painted but not selected. | All uses | false | `component:CommandPaletteItem` | Stable | Unknown context value leaves every item unhighlighted. |
|
|
103
|
+
| Selection | explicit; context value; false | Chosen value exposed through `aria-selected`. | All uses | false | `component:CommandPaletteItem` | Stable | Duplicate values resolve ambiguously; values stay unique. |
|
|
104
|
+
| Availability | enabled; disabled | Whether pointer activation is available. | All uses | enabled | `component:CommandPaletteItem` | Stable | Disabled suppresses consumer and component callbacks. |
|
|
105
|
+
| Item identity | context-generated id; standalone caller-provided id | DOM identity used by active-descendant or caller. | Contextual or standalone | absent | component or caller | Stable | Context identity wins only for a registered item. |
|
|
106
|
+
|
|
107
|
+
## Behavioral and layout contract
|
|
108
|
+
|
|
109
|
+
| ID | Candidate invariant | Basis | Draft review state |
|
|
110
|
+
| --- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------------------- |
|
|
111
|
+
| FR1 | Native props and `ref` reach the option root. CommandPalette context owns registered-item id, role, selected state, disabled state, and value marker; standalone caller id persists. | Released source and `architecture:public-component-api/INV5` | Verified by focused DOM tests |
|
|
112
|
+
| FR2 | Pointer activation runs consumer `onClick`, then stops when prevented; otherwise it calls item `onSelect`, then context selection and close. Disabled items run none of those paths. | Released callbacks and disabled promise | Verified; mutation-resistant |
|
|
113
|
+
| FR3 | Explicit `isHighlighted` and `isSelected` precede context-derived values, then false. Highlight paints active state only; selection alone drives `aria-selected`. | Released source, docs, and listbox semantics | State semantics tested; precedence tested; combined paint gap remains OQ2 |
|
|
114
|
+
| FR4 | Context owns highlighted-item scrolling. Outside context, a highlighted item scrolls nearest, except an initially highlighted item inside an inline Dialog does not scroll. | Released source and regression history | Verified by focused Effect tests |
|
|
115
|
+
| FR5 | Children provide the option's label and supporting presentation, without nested interactive descendants. | Option semantics and `spec:AST-020/FR1,FR2` | Documented; exact-head a11y remains a gate |
|
|
116
|
+
|
|
117
|
+
### Allowed variation
|
|
118
|
+
|
|
119
|
+
- **AV1 — Content.** Labels, icons, descriptions, and shortcut hints may vary
|
|
120
|
+
while remaining non-interactive.
|
|
121
|
+
- **AV2 — Visual state.** Highlight, selection, and disabled state may occur
|
|
122
|
+
independently or together. The current selected paint masks highlighted paint
|
|
123
|
+
when both are true; OQ2 holds the visible-state remedy.
|
|
124
|
+
- **AV3 — Layout.** Consumer `xstyle`, class, and style may adjust the single
|
|
125
|
+
root without replacing its option semantics.
|
|
126
|
+
|
|
127
|
+
### Representative states
|
|
128
|
+
|
|
129
|
+
| State | Required invariant | Allowed variation |
|
|
130
|
+
| -------------------- | ------------------------------------------------------------------------- | --------------------------------- |
|
|
131
|
+
| Enabled standalone | Caller id and native props persist; pointer activation reports locally. | Content and visual state. |
|
|
132
|
+
| Disabled standalone | `aria-disabled` is true and no click callback fires. | Content. |
|
|
133
|
+
| Context highlighted | Context item id matches active descendant and highlight is not selection. | Item index and content. |
|
|
134
|
+
| Context selected | Matching value exposes `aria-selected=true`. | Highlight may be same or another. |
|
|
135
|
+
| Consumer-cancelled | Consumer click runs; local and context selection/close do not. | Consumer side effect. |
|
|
136
|
+
| Inline initial state | Initial standalone highlight does not scroll the surrounding preview. | Selected value and content. |
|
|
137
|
+
|
|
138
|
+
### Transformation and precedence order
|
|
139
|
+
|
|
140
|
+
- **ORD1 — Visual state.** Explicit item prop → CommandPalette context → false.
|
|
141
|
+
- **ORD2 — Pointer activation.** Disabled guard → consumer click → prevented
|
|
142
|
+
check → item `onSelect` → context select → context close.
|
|
143
|
+
- **ORD3 — Identity.** Registered context id → standalone caller id → absent.
|
|
144
|
+
|
|
145
|
+
### Performance and resources
|
|
146
|
+
|
|
147
|
+
- **PR1 — Lookup.** Context matching remains bounded by the current flat result
|
|
148
|
+
list and performs no listener, observer, or per-item registry work.
|
|
149
|
+
- **PR2 — Scroll ownership.** One owner scrolls a highlighted contextual item;
|
|
150
|
+
standalone items schedule no work when not highlighted.
|
|
151
|
+
|
|
152
|
+
## Accessibility contract
|
|
153
|
+
|
|
154
|
+
- **AR1 — Option semantics.** The root exposes `role=option`; its content or
|
|
155
|
+
caller label provides the accessible name, and `aria-selected` reports chosen
|
|
156
|
+
value rather than visual highlight.
|
|
157
|
+
- **AR2 — Composite ownership.** Inside CommandPalette, the query field retains
|
|
158
|
+
focus and points to the context-generated item id; CommandPalette owns arrow
|
|
159
|
+
navigation and Enter selection under its adopted listbox/combobox model.
|
|
160
|
+
- **AR3 — Disabled state.** Disabled items expose `aria-disabled=true` and
|
|
161
|
+
suppress every pointer activation callback. Source inspection confirms the
|
|
162
|
+
interaction overlay is omitted; exact-head browser evidence remains the paint
|
|
163
|
+
gate.
|
|
164
|
+
- **AR4 — Content.** Item children contain no nested button, link, or other
|
|
165
|
+
interactive descendant whose semantics would be lost when the `option`
|
|
166
|
+
role makes its descendants presentational, following WAI-ARIA 1.2 and
|
|
167
|
+
`spec:AST-020/FR1,FR2`.
|
|
168
|
+
- **AR5 — Standalone gap.** A standalone option has no owning composite keyboard
|
|
169
|
+
model. OQ1 must settle that public contract before runtime semantics change.
|
|
170
|
+
|
|
171
|
+
## Design relationships
|
|
172
|
+
|
|
173
|
+
| Anatomy | Design requirement | Representation authority | Hierarchy role | Component contract |
|
|
174
|
+
| ------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | -------------- | ------------------ |
|
|
175
|
+
| Item | Paints enabled, highlighted, selected, disabled, and press states on one root. Selected currently masks highlight when both apply (OQ2). | Current source and public docs | Prominent | FR1–FR4, AR1–AR3 |
|
|
176
|
+
| Content | Supplies the option name and non-interactive supporting presentation. | Product callsite | Supporting | FR5, AR1, AR4 |
|
|
177
|
+
|
|
178
|
+
## Family and system relationships
|
|
179
|
+
|
|
180
|
+
- `component:CommandPalette` owns composite search, listbox, active-descendant,
|
|
181
|
+
keyboard, and close orchestration; this component binds one option to it.
|
|
182
|
+
- `architecture:interaction-modality` owns shared pointer and keyboard behavior.
|
|
183
|
+
- `architecture:public-component-api` owns native passthrough and released API
|
|
184
|
+
compatibility.
|
|
185
|
+
- `architecture:component-theming-surface` owns the aggregate Item anatomy map
|
|
186
|
+
and stable `command-palette-item` target.
|
|
187
|
+
- `spec:AST-017` classifies the victim-free corrections and holds OQ1 against
|
|
188
|
+
silent released-contract changes.
|
|
189
|
+
- `spec:AST-020` supplies accessibility evidence and adopted-pattern boundaries.
|
|
190
|
+
- WAI-ARIA 1.2 option semantics make descendants presentational, so interactive
|
|
191
|
+
controls do not belong inside this option root.
|
|
192
|
+
|
|
193
|
+
## Verification map
|
|
194
|
+
|
|
195
|
+
| Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
|
|
196
|
+
| ----------------- | -------------------------------------------------------------------------------------- | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ----------------------------------- |
|
|
197
|
+
| FR1, FR3, AR1–AR2 | `CommandPaletteItem.test.tsx`, `CommandPalette.test.tsx` | standalone; context highlighted/selected | Dropped id/ref/native prop, clobberable role/state, or highlight-as-selection fails focused DOM assertions. | `audit:CommandPaletteItem/a11y` |
|
|
198
|
+
| FR2, AR3 | `CommandPaletteItem.test.tsx` | enabled; disabled; consumer-cancelled; contextual | Disabled consumer activation, ignored cancellation, missing local report, selection, or close fails tests. | `audit:CommandPaletteItem/behavior` |
|
|
199
|
+
| FR4 | `CommandPaletteItem.test.tsx`, `CommandPalette.test.tsx` | standalone; inline initial; changed highlight | Lost nearest scrolling, duplicate contextual scrolling, or initial inline scroll fails Effect assertions. | `audit:CommandPaletteItem/behavior` |
|
|
200
|
+
| FR5, AR4 | public docs, dedicated Storybook states, exact-head a11y/browser evidence | label; shortcut; disabled | Interactive descendant guidance regresses or supported composition fails exact-head accessibility evidence. | `audit:CommandPaletteItem/a11y` |
|
|
201
|
+
| Theme/RTL | focused class assertion, `themingTargets.test.ts`, Storybook fixture, RTL verified N/A | all visual states | Target loss fails inventory/DOM tests; any new directional behavior requires a non-empty RTL dimension. | `audit:CommandPaletteItem/theming` |
|
|
202
|
+
|
|
203
|
+
## Decision log
|
|
204
|
+
|
|
205
|
+
No component-local API, keyboard, or visual decision is settled in this draft.
|
|
206
|
+
Objective corrections preserve the current public shape.
|
|
207
|
+
|
|
208
|
+
## Open questions
|
|
209
|
+
|
|
210
|
+
- **OQ1 — What standalone keyboard contract should CommandPaletteItem expose?**
|
|
211
|
+
(`human-api`) Current standalone use exposes an option and pointer activation
|
|
212
|
+
but no owning listbox keyboard model. Decide whether a public composite owner
|
|
213
|
+
must supply that model, the item should gain a different standalone role and
|
|
214
|
+
interaction contract, or standalone activation should enter a migration path.
|
|
215
|
+
- **OQ2 — How should keyboard highlight remain visible when the item is also
|
|
216
|
+
selected?** (`human-design`) Current selected background paint follows and
|
|
217
|
+
masks the highlighted background. Real-browser pixels must confirm the gap;
|
|
218
|
+
any appearance remedy requires owner direction and a separate visual change.
|
|
219
|
+
|
|
220
|
+
## Content boundary
|
|
221
|
+
|
|
222
|
+
This file does not duplicate consumer examples, audit scores, implementation
|
|
223
|
+
steps, aggregate CommandPalette search/list behavior, or shared system rules.
|
|
@@ -6,9 +6,12 @@
|
|
|
6
6
|
* @output Unit tests for CommandPaletteItem
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import {createRef, type ReactElement} from 'react';
|
|
9
10
|
import {afterEach, describe, it, expect, vi} from 'vitest';
|
|
10
11
|
import {render, screen, fireEvent, waitFor} from '@testing-library/react';
|
|
11
12
|
import {Dialog} from '../Dialog/Dialog';
|
|
13
|
+
import {CommandPaletteContext} from './CommandPaletteContext';
|
|
14
|
+
import type {CommandPaletteContextValue} from './CommandPaletteContext';
|
|
12
15
|
import {CommandPaletteItem} from './CommandPaletteItem';
|
|
13
16
|
|
|
14
17
|
const scrollIntoViewDescriptor = Object.getOwnPropertyDescriptor(
|
|
@@ -38,11 +41,45 @@ afterEach(() => {
|
|
|
38
41
|
}
|
|
39
42
|
});
|
|
40
43
|
|
|
44
|
+
function makeContext(
|
|
45
|
+
overrides: Partial<CommandPaletteContextValue> = {},
|
|
46
|
+
): CommandPaletteContextValue {
|
|
47
|
+
return {
|
|
48
|
+
search: '',
|
|
49
|
+
setSearch: vi.fn(),
|
|
50
|
+
value: '',
|
|
51
|
+
setValue: vi.fn(),
|
|
52
|
+
listId: 'command-list',
|
|
53
|
+
highlightedIndex: -1,
|
|
54
|
+
setHighlightedIndex: vi.fn(),
|
|
55
|
+
getItemId: index => `command-item-${index}`,
|
|
56
|
+
selectableItems: [{value: 'test', label: 'Item'}],
|
|
57
|
+
searchResults: [],
|
|
58
|
+
selectItem: vi.fn(),
|
|
59
|
+
onKeyDown: vi.fn(),
|
|
60
|
+
onClose: vi.fn(),
|
|
61
|
+
isOpen: true,
|
|
62
|
+
isBusy: false,
|
|
63
|
+
...overrides,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function renderWithContext(
|
|
68
|
+
item: ReactElement,
|
|
69
|
+
overrides: Partial<CommandPaletteContextValue> = {},
|
|
70
|
+
) {
|
|
71
|
+
const context = makeContext(overrides);
|
|
72
|
+
return {
|
|
73
|
+
context,
|
|
74
|
+
...render(
|
|
75
|
+
<CommandPaletteContext value={context}>{item}</CommandPaletteContext>,
|
|
76
|
+
),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
41
80
|
describe('CommandPaletteItem', () => {
|
|
42
81
|
it('renders children', () => {
|
|
43
|
-
render(
|
|
44
|
-
<CommandPaletteItem value="test">Test Item</CommandPaletteItem>,
|
|
45
|
-
);
|
|
82
|
+
render(<CommandPaletteItem value="test">Test Item</CommandPaletteItem>);
|
|
46
83
|
expect(screen.getByText('Test Item')).toBeInTheDocument();
|
|
47
84
|
});
|
|
48
85
|
|
|
@@ -51,6 +88,13 @@ describe('CommandPaletteItem', () => {
|
|
|
51
88
|
expect(screen.getByRole('option')).toBeInTheDocument();
|
|
52
89
|
});
|
|
53
90
|
|
|
91
|
+
it('carries the stable item theme target', () => {
|
|
92
|
+
render(<CommandPaletteItem value="test">Item</CommandPaletteItem>);
|
|
93
|
+
expect(screen.getByRole('option')).toHaveClass(
|
|
94
|
+
'astryx-command-palette-item',
|
|
95
|
+
);
|
|
96
|
+
});
|
|
97
|
+
|
|
54
98
|
it('calls onSelect when clicked', () => {
|
|
55
99
|
const handleSelect = vi.fn();
|
|
56
100
|
render(
|
|
@@ -62,6 +106,36 @@ describe('CommandPaletteItem', () => {
|
|
|
62
106
|
expect(handleSelect).toHaveBeenCalledWith('test');
|
|
63
107
|
});
|
|
64
108
|
|
|
109
|
+
it('coordinates selection and close through CommandPalette context', () => {
|
|
110
|
+
const handleSelect = vi.fn();
|
|
111
|
+
const {context} = renderWithContext(
|
|
112
|
+
<CommandPaletteItem value="test" onSelect={handleSelect}>
|
|
113
|
+
Item
|
|
114
|
+
</CommandPaletteItem>,
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
fireEvent.click(screen.getByRole('option'));
|
|
118
|
+
|
|
119
|
+
expect(handleSelect).toHaveBeenCalledWith('test');
|
|
120
|
+
expect(context.selectItem).toHaveBeenCalledWith('test');
|
|
121
|
+
expect(context.onClose).toHaveBeenCalledTimes(1);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('lets consumer click cancellation stop contextual selection and close', () => {
|
|
125
|
+
const {context} = renderWithContext(
|
|
126
|
+
<CommandPaletteItem
|
|
127
|
+
value="test"
|
|
128
|
+
onClick={event => event.preventDefault()}>
|
|
129
|
+
Item
|
|
130
|
+
</CommandPaletteItem>,
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
fireEvent.click(screen.getByRole('option'));
|
|
134
|
+
|
|
135
|
+
expect(context.selectItem).not.toHaveBeenCalled();
|
|
136
|
+
expect(context.onClose).not.toHaveBeenCalled();
|
|
137
|
+
});
|
|
138
|
+
|
|
65
139
|
it('does not call onSelect when disabled', () => {
|
|
66
140
|
const handleSelect = vi.fn();
|
|
67
141
|
render(
|
|
@@ -73,6 +147,94 @@ describe('CommandPaletteItem', () => {
|
|
|
73
147
|
expect(handleSelect).not.toHaveBeenCalled();
|
|
74
148
|
});
|
|
75
149
|
|
|
150
|
+
it('does not call consumer click or selection handlers when disabled', () => {
|
|
151
|
+
const handleClick = vi.fn();
|
|
152
|
+
const handleSelect = vi.fn();
|
|
153
|
+
render(
|
|
154
|
+
<CommandPaletteItem
|
|
155
|
+
value="test"
|
|
156
|
+
isDisabled
|
|
157
|
+
onClick={handleClick}
|
|
158
|
+
onSelect={handleSelect}>
|
|
159
|
+
Item
|
|
160
|
+
</CommandPaletteItem>,
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
fireEvent.click(screen.getByRole('option'));
|
|
164
|
+
|
|
165
|
+
expect(handleClick).not.toHaveBeenCalled();
|
|
166
|
+
expect(handleSelect).not.toHaveBeenCalled();
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it('lets a consumer cancel selection from onClick', () => {
|
|
170
|
+
const handleSelect = vi.fn();
|
|
171
|
+
render(
|
|
172
|
+
<CommandPaletteItem
|
|
173
|
+
value="test"
|
|
174
|
+
onClick={event => event.preventDefault()}
|
|
175
|
+
onSelect={handleSelect}>
|
|
176
|
+
Item
|
|
177
|
+
</CommandPaletteItem>,
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
fireEvent.click(screen.getByRole('option'));
|
|
181
|
+
|
|
182
|
+
expect(handleSelect).not.toHaveBeenCalled();
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
it('derives selected state and item identity from context', () => {
|
|
186
|
+
renderWithContext(
|
|
187
|
+
<CommandPaletteItem value="test" id="consumer-id">
|
|
188
|
+
Item
|
|
189
|
+
</CommandPaletteItem>,
|
|
190
|
+
{value: 'test'},
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
const item = screen.getByRole('option');
|
|
194
|
+
expect(item).toHaveAttribute('id', 'command-item-0');
|
|
195
|
+
expect(item).toHaveAttribute('aria-selected', 'true');
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it('paints context-derived highlight when the item is not selected', () => {
|
|
199
|
+
renderWithContext(
|
|
200
|
+
<CommandPaletteItem value="test">Item</CommandPaletteItem>,
|
|
201
|
+
{highlightedIndex: 0},
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
expect(getComputedStyle(screen.getByRole('option')).backgroundColor).toBe(
|
|
205
|
+
'var(--color-overlay-hover)',
|
|
206
|
+
);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it('lets explicit visual state override context-derived state', () => {
|
|
210
|
+
renderWithContext(
|
|
211
|
+
<CommandPaletteItem value="test" isHighlighted={false} isSelected={false}>
|
|
212
|
+
Item
|
|
213
|
+
</CommandPaletteItem>,
|
|
214
|
+
{value: 'test', highlightedIndex: 0},
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
const item = screen.getByRole('option');
|
|
218
|
+
expect(item).toHaveAttribute('aria-selected', 'false');
|
|
219
|
+
expect(getComputedStyle(item).backgroundColor).toBe('rgba(0, 0, 0, 0)');
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
it('protects owned option semantics from native passthrough props', () => {
|
|
223
|
+
render(
|
|
224
|
+
<CommandPaletteItem
|
|
225
|
+
value="test"
|
|
226
|
+
role="button"
|
|
227
|
+
aria-selected={true}
|
|
228
|
+
aria-disabled={true}>
|
|
229
|
+
Item
|
|
230
|
+
</CommandPaletteItem>,
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
const item = screen.getByRole('option');
|
|
234
|
+
expect(item).toHaveAttribute('aria-selected', 'false');
|
|
235
|
+
expect(item).not.toHaveAttribute('aria-disabled');
|
|
236
|
+
});
|
|
237
|
+
|
|
76
238
|
it('sets aria-disabled when disabled', () => {
|
|
77
239
|
render(
|
|
78
240
|
<CommandPaletteItem value="test" isDisabled>
|
|
@@ -157,10 +319,43 @@ describe('CommandPaletteItem', () => {
|
|
|
157
319
|
});
|
|
158
320
|
});
|
|
159
321
|
|
|
160
|
-
it('
|
|
322
|
+
it('forwards ref and standalone DOM attributes to the option', () => {
|
|
323
|
+
const ref = createRef<HTMLDivElement>();
|
|
324
|
+
render(
|
|
325
|
+
<CommandPaletteItem
|
|
326
|
+
ref={ref}
|
|
327
|
+
value="test"
|
|
328
|
+
id="standalone-item"
|
|
329
|
+
aria-label="Open settings"
|
|
330
|
+
data-kind="command">
|
|
331
|
+
Item
|
|
332
|
+
</CommandPaletteItem>,
|
|
333
|
+
);
|
|
334
|
+
|
|
335
|
+
const item = screen.getByRole('option', {name: 'Open settings'});
|
|
336
|
+
expect(ref.current).toBe(item);
|
|
337
|
+
expect(item).toHaveAttribute('id', 'standalone-item');
|
|
338
|
+
expect(item).toHaveAttribute('data-kind', 'command');
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
it('carries the stable theme target and consumer styling on its root', () => {
|
|
161
342
|
render(
|
|
162
|
-
<CommandPaletteItem
|
|
343
|
+
<CommandPaletteItem
|
|
344
|
+
value="test"
|
|
345
|
+
className="consumer-item"
|
|
346
|
+
style={{marginBlockStart: '8px'}}>
|
|
347
|
+
Item
|
|
348
|
+
</CommandPaletteItem>,
|
|
163
349
|
);
|
|
350
|
+
|
|
351
|
+
const item = screen.getByRole('option');
|
|
352
|
+
expect(item).toHaveClass('astryx-command-palette-item');
|
|
353
|
+
expect(item).toHaveClass('consumer-item');
|
|
354
|
+
expect(item).toHaveStyle({marginBlockStart: '8px'});
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
it('sets data-value attribute', () => {
|
|
358
|
+
render(<CommandPaletteItem value="my-value">Item</CommandPaletteItem>);
|
|
164
359
|
expect(screen.getByRole('option')).toHaveAttribute(
|
|
165
360
|
'data-value',
|
|
166
361
|
'my-value',
|