@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
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
'use client';
|
|
4
4
|
/**
|
|
5
5
|
* @file CommandPalette.tsx
|
|
6
|
-
* @input Uses React, Dialog, Layout, CommandPaletteContext, SearchSource,
|
|
6
|
+
* @input Uses React, Dialog, Layout, CommandPaletteContext, SearchSource,
|
|
7
|
+
* useCombobox, useAnnounce, useAnnounceRenderedText
|
|
7
8
|
* @output Exports CommandPalette root component and props
|
|
8
9
|
* @position Core root component; dialog shell with searchSource-driven items
|
|
9
10
|
*
|
|
@@ -37,6 +38,7 @@ import {CommandPaletteFooter} from './CommandPaletteFooter';
|
|
|
37
38
|
import {CommandPaletteEmpty} from './CommandPaletteEmpty';
|
|
38
39
|
import type {BaseProps} from '../BaseProps';
|
|
39
40
|
import {useAnnounce} from '../hooks/useAnnounce';
|
|
41
|
+
import {useAnnounceRenderedText} from '../hooks/useAnnounceRenderedText';
|
|
40
42
|
import {useTranslator} from '../i18n';
|
|
41
43
|
|
|
42
44
|
export interface CommandPaletteProps<
|
|
@@ -78,7 +80,9 @@ export interface CommandPaletteProps<
|
|
|
78
80
|
|
|
79
81
|
/**
|
|
80
82
|
* Per-item render function. Receives the item and whether it is currently selected.
|
|
81
|
-
*
|
|
83
|
+
* Return non-interactive presentation content; buttons and links cannot be
|
|
84
|
+
* nested inside the rendered option. Auto-grouping by `auxiliaryData.group`
|
|
85
|
+
* is preserved.
|
|
82
86
|
* When omitted, renders each item's `label` text.
|
|
83
87
|
*/
|
|
84
88
|
renderItem?: (item: T, isSelected: boolean) => ReactNode;
|
|
@@ -253,9 +257,10 @@ function ItemRenderer<T extends SearchableItem>({
|
|
|
253
257
|
* Uses `searchSource` for all search logic — same interface as Typeahead.
|
|
254
258
|
* For static lists, use `createStaticSource` from `@astryxdesign/core/Typeahead`.
|
|
255
259
|
*
|
|
256
|
-
* Keyboard navigation is handled by `useCombobox` from Selector,
|
|
257
|
-
*
|
|
258
|
-
*
|
|
260
|
+
* Keyboard navigation is handled by `useCombobox` from Selector for arrows,
|
|
261
|
+
* PageUp/PageDown, and Enter. Home/End remain native caret keys. Modal Escape
|
|
262
|
+
* dismissal delegates to Dialog's shared layer stack so nested surfaces handle
|
|
263
|
+
* the first press.
|
|
259
264
|
*
|
|
260
265
|
* Input and footer are rendered by default — only pass them to replace the defaults.
|
|
261
266
|
*
|
|
@@ -311,6 +316,7 @@ export function CommandPalette<T extends SearchableItem = SearchableItem>({
|
|
|
311
316
|
useOptimistic(searchResults);
|
|
312
317
|
const isBusy = isPending;
|
|
313
318
|
const searchVersionRef = useRef(0);
|
|
319
|
+
const emptyStateRef = useRef<HTMLDivElement>(null);
|
|
314
320
|
|
|
315
321
|
// Announce search status to screen readers through the shared polite live
|
|
316
322
|
// region (comboboxes-7 announce path, mirroring Selector / BaseTypeahead).
|
|
@@ -393,6 +399,10 @@ export function CommandPalette<T extends SearchableItem = SearchableItem>({
|
|
|
393
399
|
(query: string) => {
|
|
394
400
|
searchSource.cancel?.();
|
|
395
401
|
const version = ++searchVersionRef.current;
|
|
402
|
+
// A highlight belongs to the query that created it. Clear it before any
|
|
403
|
+
// optimistic narrowing so aria-activedescendant never shifts to a
|
|
404
|
+
// different command at the same index while the next result set loads.
|
|
405
|
+
combobox.setHighlightedIndex(-1);
|
|
396
406
|
|
|
397
407
|
startTransition(async () => {
|
|
398
408
|
const isBootstrap = query === '';
|
|
@@ -429,16 +439,12 @@ export function CommandPalette<T extends SearchableItem = SearchableItem>({
|
|
|
429
439
|
|
|
430
440
|
// Announce the outcome from the search commit (not a reactive
|
|
431
441
|
// effect), matching Selector / BaseTypeahead: exactly one
|
|
432
|
-
// announcement per committed query
|
|
433
|
-
//
|
|
434
|
-
//
|
|
435
|
-
// palette announces nothing; clearing the query only clears any
|
|
436
|
-
// lingering status text.
|
|
442
|
+
// announcement per committed non-empty query. Empty results are
|
|
443
|
+
// announced from their rendered content below so a caller-supplied
|
|
444
|
+
// ReactNode reaches assistive technology as written.
|
|
437
445
|
if (isBootstrap) {
|
|
438
446
|
announce('');
|
|
439
|
-
} else if (items.length
|
|
440
|
-
announce(t('@astryx.commandPalette.noResultsFor', {query}));
|
|
441
|
-
} else {
|
|
447
|
+
} else if (items.length > 0) {
|
|
442
448
|
announce(
|
|
443
449
|
t('@astryx.commandPalette.resultCount', {count: items.length}),
|
|
444
450
|
);
|
|
@@ -494,14 +500,19 @@ export function CommandPalette<T extends SearchableItem = SearchableItem>({
|
|
|
494
500
|
}
|
|
495
501
|
}, [isOpen]);
|
|
496
502
|
|
|
497
|
-
// Wrap combobox's onKeyDown to
|
|
498
|
-
//
|
|
499
|
-
//
|
|
503
|
+
// Wrap combobox's onKeyDown to preserve inline-preview Escape handling and
|
|
504
|
+
// select + close on Enter. Modal Escape stays unclaimed here so Dialog's
|
|
505
|
+
// shared dismissal stack can route it to the topmost surface.
|
|
500
506
|
const handleKeyDown = useCallback(
|
|
501
507
|
(e: React.KeyboardEvent) => {
|
|
502
508
|
if (e.key === 'Escape') {
|
|
503
|
-
|
|
504
|
-
|
|
509
|
+
// Modal CommandPalette delegates Escape to Dialog's shared dismissal
|
|
510
|
+
// stack so a nested layer handles the first press. Inline previews do
|
|
511
|
+
// not join that stack, so preserve their local close behavior.
|
|
512
|
+
if (isInline) {
|
|
513
|
+
e.preventDefault();
|
|
514
|
+
handleClose();
|
|
515
|
+
}
|
|
505
516
|
return;
|
|
506
517
|
}
|
|
507
518
|
if (e.key === 'Enter') {
|
|
@@ -518,13 +529,18 @@ export function CommandPalette<T extends SearchableItem = SearchableItem>({
|
|
|
518
529
|
}
|
|
519
530
|
return;
|
|
520
531
|
}
|
|
532
|
+
// Home and End remain native caret-movement keys for this editable
|
|
533
|
+
// combobox. PageUp/PageDown provide first/last result navigation.
|
|
534
|
+
if (e.key === 'Home' || e.key === 'End') {
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
521
537
|
// Space should type in the input, not trigger selection
|
|
522
538
|
if (e.key === ' ') {
|
|
523
539
|
return;
|
|
524
540
|
}
|
|
525
541
|
combobox.onKeyDown(e);
|
|
526
542
|
},
|
|
527
|
-
[combobox, handleClose, selectableItems, selectItem],
|
|
543
|
+
[combobox, handleClose, isInline, selectableItems, selectItem],
|
|
528
544
|
);
|
|
529
545
|
|
|
530
546
|
// Hover highlight is owned here by a single delegated handler on the list
|
|
@@ -605,14 +621,24 @@ export function CommandPalette<T extends SearchableItem = SearchableItem>({
|
|
|
605
621
|
// the empty state is never unmounted and re-added mid-search (which flashed).
|
|
606
622
|
const showEmptyBootstrap = search === '' && optimisticResults.length === 0;
|
|
607
623
|
const showEmptySearch = search !== '' && optimisticResults.length === 0;
|
|
624
|
+
// Announce only once the search settles: while it is pending, optimistic
|
|
625
|
+
// narrowing can empty the list before the source answers, which would
|
|
626
|
+
// speak "No results" early or wrongly.
|
|
627
|
+
useAnnounceRenderedText(emptyStateRef, showEmptySearch && !isPending, search);
|
|
608
628
|
|
|
609
629
|
let listContent: ReactNode;
|
|
610
630
|
if (showEmptyBootstrap) {
|
|
611
631
|
listContent = (
|
|
612
|
-
<CommandPaletteEmpty
|
|
632
|
+
<CommandPaletteEmpty ref={emptyStateRef}>
|
|
633
|
+
{emptyBootstrapText}
|
|
634
|
+
</CommandPaletteEmpty>
|
|
613
635
|
);
|
|
614
636
|
} else if (showEmptySearch) {
|
|
615
|
-
listContent =
|
|
637
|
+
listContent = (
|
|
638
|
+
<CommandPaletteEmpty ref={emptyStateRef}>
|
|
639
|
+
{emptySearchText}
|
|
640
|
+
</CommandPaletteEmpty>
|
|
641
|
+
);
|
|
616
642
|
} else {
|
|
617
643
|
listContent = (
|
|
618
644
|
<ItemRenderer
|
|
@@ -52,13 +52,14 @@ export interface CommandPaletteEmptyProps extends BaseProps<HTMLDivElement> {
|
|
|
52
52
|
* - `emptyBootstrapText`: no search term and bootstrap() returns nothing
|
|
53
53
|
* - `emptySearchText`: a search query returned no results
|
|
54
54
|
*
|
|
55
|
-
* Can also be composed
|
|
55
|
+
* Can also be composed as a standalone empty result surface. Render actionable
|
|
56
|
+
* empty content outside listbox and option semantics.
|
|
56
57
|
*
|
|
57
58
|
* @example
|
|
58
59
|
* ```
|
|
59
60
|
* <CommandPalette
|
|
60
|
-
* emptyBootstrapText=
|
|
61
|
-
* emptySearchText=
|
|
61
|
+
* emptyBootstrapText="Start typing to search"
|
|
62
|
+
* emptySearchText="No results found"
|
|
62
63
|
* searchSource={source}
|
|
63
64
|
* />
|
|
64
65
|
* ```
|
|
@@ -9,18 +9,73 @@ export const docs = {
|
|
|
9
9
|
isHiddenFromOverview: true,
|
|
10
10
|
description:
|
|
11
11
|
'Search input slot. Auto-focuses on mount. Wires to command palette context when used inside CommandPalette.',
|
|
12
|
+
usage: {
|
|
13
|
+
description:
|
|
14
|
+
'Use CommandPaletteInput inside CommandPalette for a popup-backed command query, or as an independent search field when no result popup is present.',
|
|
15
|
+
bestPractices: [
|
|
16
|
+
{
|
|
17
|
+
guidance: true,
|
|
18
|
+
description:
|
|
19
|
+
'Pass a concise label that identifies what can be searched when "Search commands" does not describe it; the placeholder is never the field\'s name.',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
guidance: true,
|
|
23
|
+
description:
|
|
24
|
+
'Use endContent for short supporting controls or shortcut hints at the trailing edge.',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
guidance: false,
|
|
28
|
+
description:
|
|
29
|
+
'Override combobox role or popup state. CommandPaletteInput owns those semantics when connected to CommandPalette.',
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
anatomy: [
|
|
33
|
+
{
|
|
34
|
+
name: 'Input',
|
|
35
|
+
required: true,
|
|
36
|
+
description:
|
|
37
|
+
'The surrounding inline layout for the search glyph, query field, and trailing content.',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'Search glyph',
|
|
41
|
+
required: true,
|
|
42
|
+
description: 'A decorative search icon before the query field.',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: 'Query field',
|
|
46
|
+
required: true,
|
|
47
|
+
description:
|
|
48
|
+
'The native text field. It is a searchbox when standalone without popup attributes and a combobox when popup relationships are supplied or CommandPalette context is present.',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: 'Loading spinner',
|
|
52
|
+
required: false,
|
|
53
|
+
description:
|
|
54
|
+
'A delayed pending indicator shown before trailing content while search is busy.',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: 'Trailing content',
|
|
58
|
+
required: false,
|
|
59
|
+
description:
|
|
60
|
+
'Caller-provided supporting content such as a clear control or shortcut hint.',
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
theming: {
|
|
65
|
+
targets: [{className: 'astryx-command-palette-input'}],
|
|
66
|
+
},
|
|
12
67
|
props: [
|
|
13
68
|
{
|
|
14
69
|
name: 'placeholder',
|
|
15
70
|
type: 'string',
|
|
16
71
|
description: 'Placeholder text for the input.',
|
|
17
|
-
default: "'Search
|
|
72
|
+
default: "'Search…'",
|
|
18
73
|
},
|
|
19
74
|
{
|
|
20
75
|
name: 'label',
|
|
21
76
|
type: 'string',
|
|
22
77
|
description:
|
|
23
|
-
'Accessible label for the
|
|
78
|
+
'Accessible label for the query field, announced by screen readers. Defaults to the translated "Search commands"; the placeholder is never used as the name.',
|
|
24
79
|
},
|
|
25
80
|
{
|
|
26
81
|
name: 'hasAutoFocus',
|
|
@@ -85,7 +140,8 @@ export const docsZh = {
|
|
|
85
140
|
'搜索输入插槽。挂载时自动聚焦。在 CommandPalette 内使用时连接到上下文。',
|
|
86
141
|
propDescriptions: {
|
|
87
142
|
placeholder: '输入框的占位文本。',
|
|
88
|
-
label:
|
|
143
|
+
label:
|
|
144
|
+
'查询字段的无障碍标签,供屏幕阅读器朗读。默认为翻译后的 "Search commands";占位文本不会用作名称。',
|
|
89
145
|
hasAutoFocus: '挂载时自动聚焦输入框。内联命令面板中自动禁用。',
|
|
90
146
|
endContent: '渲染在输入框末尾的内容,位于加载指示器之后。',
|
|
91
147
|
value: '搜索值。在 CommandPalette 内省略时从上下文读取。',
|
|
@@ -102,7 +158,8 @@ export const docsDense = {
|
|
|
102
158
|
'search input; auto-focus on mount; wires to context inside CommandPalette',
|
|
103
159
|
propDescriptions: {
|
|
104
160
|
placeholder: 'input placeholder text',
|
|
105
|
-
label:
|
|
161
|
+
label:
|
|
162
|
+
'accessible label for the query field; default "Search commands", never the placeholder',
|
|
106
163
|
hasAutoFocus: 'auto-focus on mount; auto-disabled in inline mode',
|
|
107
164
|
endContent: 'trailing content after spinner',
|
|
108
165
|
value: 'search value; reads context when omitted inside palette',
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 3
|
|
3
|
+
template_version: 7
|
|
4
|
+
kind: component
|
|
5
|
+
id: component:CommandPaletteInput
|
|
6
|
+
authority: current
|
|
7
|
+
archive_reason: null
|
|
8
|
+
superseded_by: null
|
|
9
|
+
approved_by: cixzhang
|
|
10
|
+
approved_at: 2026-10-14
|
|
11
|
+
owners: [cixzhang]
|
|
12
|
+
review_triggers: [public-api, behavior, layout, theming, accessibility]
|
|
13
|
+
verified_by:
|
|
14
|
+
[
|
|
15
|
+
packages/core/src/CommandPalette/CommandPaletteInput.test.tsx,
|
|
16
|
+
apps/storybook/stories/CommandPaletteInput.stories.tsx,
|
|
17
|
+
apps/storybook/rtl-audit/targets.json,
|
|
18
|
+
packages/core/src/theme/themingTargets.test.ts,
|
|
19
|
+
scripts/check-knowledge.mjs,
|
|
20
|
+
]
|
|
21
|
+
modules: []
|
|
22
|
+
families: []
|
|
23
|
+
design_specs: []
|
|
24
|
+
architecture:
|
|
25
|
+
[
|
|
26
|
+
architecture:component-test-sufficiency,
|
|
27
|
+
architecture:component-theming-surface,
|
|
28
|
+
architecture:interaction-modality,
|
|
29
|
+
architecture:public-component-api,
|
|
30
|
+
]
|
|
31
|
+
contributing: []
|
|
32
|
+
system_specs: [spec:AST-017, spec:AST-020, spec:AST-056]
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
# CommandPaletteInput component contract
|
|
36
|
+
|
|
37
|
+
## Contract at a glance
|
|
38
|
+
|
|
39
|
+
| Area | Contract |
|
|
40
|
+
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
41
|
+
| Public contract | A query field with context-backed search state, optional trailing content, and a split wrapper/field attribute boundary. |
|
|
42
|
+
| Behavior | Standalone use without popup attributes is a searchbox; caller popup attributes or CommandPalette context supply combobox state and relationships. |
|
|
43
|
+
| End-user impact | Screen-reader users receive role and popup state that match whether a controlled result popup exists. |
|
|
44
|
+
| Builder impact | Context-owned popup semantics cannot be replaced through native passthrough props; standalone caller-owned popup semantics remain supported. |
|
|
45
|
+
| Compatibility/readiness | A `[fix]` restores no-popup semantics while preserving released caller-owned popup associations, and names the field "Search commands" by default instead of its placeholder; primary callback naming remains OQ1. |
|
|
46
|
+
| Review checks | Reject unassociated standalone combobox state, clobberable owned popup semantics, empty trailing chrome, or changed input ref routing. |
|
|
47
|
+
| Governing rules | `architecture:public-component-api/INV2,INV5`; `spec:AST-017/FR1,FR3,FR5,FR53`; `spec:AST-020/FR1,FR2`; `spec:AST-056/AR2`; WCAG 2.2 4.1.2. |
|
|
48
|
+
|
|
49
|
+
This table is a review projection; the body below is authoritative.
|
|
50
|
+
|
|
51
|
+
## Intent
|
|
52
|
+
|
|
53
|
+
CommandPaletteInput presents the text query for a command palette. It can bind
|
|
54
|
+
to CommandPalette search and navigation context or act as an independent search
|
|
55
|
+
field when no result-popup context is present.
|
|
56
|
+
|
|
57
|
+
## Compatibility and migration
|
|
58
|
+
|
|
59
|
+
- Released default preserved: `no` for no-popup standalone semantic output and
|
|
60
|
+
for the default accessible name; caller-owned popup associations and all other
|
|
61
|
+
CommandPalette output remain equivalent
|
|
62
|
+
- Compatibility class: contract restoration under `spec:AST-017/FR1,FR3,FR5` for
|
|
63
|
+
standalone semantics, since no-popup standalone use has no released popup
|
|
64
|
+
association to preserve; accessibility behavior fix under `spec:AST-017/FR53`
|
|
65
|
+
for the default name
|
|
66
|
+
- Controlled/uncontrolled behavior: unchanged
|
|
67
|
+
- Migration decision: `role="combobox"` keeps the earlier standalone semantics,
|
|
68
|
+
and `label` or `aria-label` keeps a specific name; the primary callback naming
|
|
69
|
+
question remains OQ1
|
|
70
|
+
|
|
71
|
+
Consumer migration instructions belong in consumer docs and release notes.
|
|
72
|
+
|
|
73
|
+
## Ownership boundary
|
|
74
|
+
|
|
75
|
+
**Owns**
|
|
76
|
+
|
|
77
|
+
- The arrangement inside Input: Search glyph, native Query field, Loading spinner
|
|
78
|
+
placement, and Trailing content.
|
|
79
|
+
- The query field's role and popup state when CommandPalette context is present.
|
|
80
|
+
- Context fallback for the search value, value updates, and keyboard navigation.
|
|
81
|
+
|
|
82
|
+
**Does not own / non-goals**
|
|
83
|
+
|
|
84
|
+
- The result popup, option collection, selection, or search orchestration — owned
|
|
85
|
+
by `component:CommandPalette` and its list/item parts.
|
|
86
|
+
- Spinner and search-glyph rendering — delegated to Spinner and Icon.
|
|
87
|
+
- Caller-provided trailing content behavior — owned by the product callsite.
|
|
88
|
+
|
|
89
|
+
## Public concepts
|
|
90
|
+
|
|
91
|
+
| Concept | Closed values or states | Meaning | Availability by variant/orientation/state | Default | Owner | Stability | Invalid-value behavior |
|
|
92
|
+
| ---------------- | ------------------------------------------------------------------------------------ | ------------------------------------------------ | ----------------------------------------- | -------------------- | ------------------------------- | --------- | ------------------------------------------------------------ |
|
|
93
|
+
| Query binding | explicit; CommandPalette context; native | Source and destination of query text changes. | All uses | context, then native | `component:CommandPaletteInput` | Released | Missing handlers leave native state |
|
|
94
|
+
| Popup semantics | standalone searchbox; standalone caller-owned popup; contextual CommandPalette popup | Whether the query field controls a result popup. | Context-dependent | standalone searchbox | `component:CommandPaletteInput` | Stable | Standalone overrides persist; CommandPalette context wins |
|
|
95
|
+
| Trailing content | busy indicator; `endContent`; both; absent | Supporting status or caller content after query. | All uses | absent | `component:CommandPaletteInput` | Released | Boolean, empty-string, null, and undefined values are absent |
|
|
96
|
+
|
|
97
|
+
## Behavioral and layout contract
|
|
98
|
+
|
|
99
|
+
| ID | Candidate invariant | Basis | Draft review state |
|
|
100
|
+
| --- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | ---------------------------------------------------------- |
|
|
101
|
+
| FR1 | Explicit `value` and `onValueChange` take precedence; otherwise CommandPalette context supplies search state; native uncontrolled state remains when neither exists. | Released source, docs, and tests | Verified current behavior |
|
|
102
|
+
| FR2 | Consumer `onKeyDown` runs before contextual navigation; preventing the event, or an active IME composition, prevents contextual delegation. | Released source and tests | Verified current behavior |
|
|
103
|
+
| FR3 | `ref` and native passthrough attributes reach the native query field; standalone caller-owned popup semantics persist, while CommandPalette context owns its popup role and relationships; `xstyle`, `className`, and `style` customize the surrounding Input. | Released source and docs; `architecture:public-component-api/INV5` | Verified current routing |
|
|
104
|
+
| FR4 | Pending state and renderable `endContent` share one trailing-content group; booleans, empty strings, null, and undefined do not create empty trailing chrome. | React rendering semantics and current utility contract | Verified current behavior |
|
|
105
|
+
| FR5 | Auto-focus is enabled by default and suppressed inside an inline Dialog; `hasAutoFocus={false}` suppresses both focus work and the autofocus marker. | Released source, docs, and tests | Verified current behavior; browser timing evidence remains |
|
|
106
|
+
|
|
107
|
+
### Allowed variation
|
|
108
|
+
|
|
109
|
+
- **AV1 — Query content.** Value, placeholder, label, and caller-provided trailing
|
|
110
|
+
content may vary without changing semantic ownership.
|
|
111
|
+
- **AV2 — Delegated visuals.** Icon and Spinner may change internal markup while
|
|
112
|
+
preserving their public contracts.
|
|
113
|
+
|
|
114
|
+
### Representative states
|
|
115
|
+
|
|
116
|
+
| State | Required invariant | Allowed variation |
|
|
117
|
+
| ------------------------ | ----------------------------------------------------------------- | ------------------------------------ |
|
|
118
|
+
| Standalone, no popup | Named searchbox with no popup-only ARIA state. | Explicit value and change handler. |
|
|
119
|
+
| Standalone, caller popup | Caller role, state, relationships, and active descendant persist. | Caller-owned popup model. |
|
|
120
|
+
| Contextual, closed | Named combobox references the list and reports collapsed state. | Query value and trailing content. |
|
|
121
|
+
| Contextual, no results | Named combobox reports collapsed state and references no list. | Empty or pending message. |
|
|
122
|
+
| Contextual, open | Named combobox references the list and reports expanded state. | Highlighted option and result count. |
|
|
123
|
+
| Contextual, highlighted | Active descendant names the context-owned highlighted option. | Highlighted index. |
|
|
124
|
+
| Pending or trailing | Supporting content remains at the logical trailing edge. | Spinner, caller content, or both. |
|
|
125
|
+
| Inline Dialog | Mount does not steal focus from the surrounding page. | Query and result content. |
|
|
126
|
+
|
|
127
|
+
### Transformation and precedence order
|
|
128
|
+
|
|
129
|
+
- **ORD1 — Search state.** Explicit props → CommandPalette context → native
|
|
130
|
+
uncontrolled state.
|
|
131
|
+
- **ORD2 — Keyboard handling.** Consumer handler → default-prevented or
|
|
132
|
+
IME-composition check → CommandPalette context handler.
|
|
133
|
+
- **ORD3 — Accessible name.** Native `aria-label` → `label` → the translated
|
|
134
|
+
default "Search commands" (DEC-1). Placeholder text is never the name.
|
|
135
|
+
|
|
136
|
+
### Performance and resources
|
|
137
|
+
|
|
138
|
+
- **PR1 — Focus scheduling.** At most one animation-frame focus request is
|
|
139
|
+
scheduled by a mounted eligible field; no listener or observer is retained.
|
|
140
|
+
|
|
141
|
+
## Accessibility contract
|
|
142
|
+
|
|
143
|
+
- **AR1 — Name.** The native query field always has an explicit accessible name
|
|
144
|
+
from ORD3 and never takes its name from placeholder text, satisfying
|
|
145
|
+
`spec:AST-056/AR2` and WCAG 2.2 4.1.2.
|
|
146
|
+
- **AR2 — Role and popup state.** Standalone use without popup attributes exposes
|
|
147
|
+
a `searchbox` without popup-only state. Standalone callers that provide their
|
|
148
|
+
own popup relationships retain those semantics. CommandPalette context exposes
|
|
149
|
+
a `combobox` with context-owned expanded state, list relationship, autocomplete
|
|
150
|
+
mode, and active descendant, following `spec:AST-020/FR1,FR2` and the WAI-ARIA
|
|
151
|
+
combobox pattern. While the palette holds no selectable result, the field
|
|
152
|
+
reports collapsed state and has no list relationship or active descendant, and
|
|
153
|
+
an active descendant always names an existing option.
|
|
154
|
+
- **AR3 — Semantic ownership.** With CommandPalette context, the field owns
|
|
155
|
+
`role`, `aria-expanded`, `aria-autocomplete`, `aria-controls`, and
|
|
156
|
+
`aria-activedescendant`, and these replace the same native passthrough props;
|
|
157
|
+
other ARIA props, including `aria-haspopup` and `aria-owns`, pass through.
|
|
158
|
+
Standalone caller-owned roles and relationships remain intact.
|
|
159
|
+
|
|
160
|
+
## Design relationships
|
|
161
|
+
|
|
162
|
+
| Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
|
|
163
|
+
| ---------------- | --------------------------------------------------------------------------------- | ----------------------------------------- | -------------- | ------------------ |
|
|
164
|
+
| Input | Arranges Search glyph, Query field, Loading spinner, and Trailing content inline. | Current source and public docs | Prominent | FR3, FR4 |
|
|
165
|
+
| Search glyph | Identifies the query affordance without adding a name. | Icon component | Supporting | AR1 |
|
|
166
|
+
| Query field | Receives text, focus, name, and popup semantics. | Current source and accessibility standard | Prominent | FR1–FR3, AR1–AR3 |
|
|
167
|
+
| Loading spinner | Indicates a pending contextual search before Trailing content. | Spinner component | Supporting | FR4 |
|
|
168
|
+
| Trailing content | Keeps caller content at logical inline-end. | Current source and public docs | Supporting | FR4 |
|
|
169
|
+
|
|
170
|
+
## Family and system relationships
|
|
171
|
+
|
|
172
|
+
- `component:CommandPalette` owns the result-popup context, aggregate composition,
|
|
173
|
+
and the open theming-reachability question; this component owns the default
|
|
174
|
+
Input's query-field semantics and binds them to that context.
|
|
175
|
+
- `spec:AST-017` owns compatibility classification for the released standalone
|
|
176
|
+
caller-popup and no-popup cases.
|
|
177
|
+
- `spec:AST-020` supplies the WCAG 2.2 and adopted-pattern evidence boundaries.
|
|
178
|
+
- `spec:AST-056/AR2` requires a query-field name distinct from placeholder text;
|
|
179
|
+
ORD3 and AR1 satisfy it.
|
|
180
|
+
|
|
181
|
+
## Verification map
|
|
182
|
+
|
|
183
|
+
| Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
|
|
184
|
+
| ----------- | --------------------------------------------------------- | ------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ |
|
|
185
|
+
| FR1–FR3 | `CommandPaletteInput.test.tsx` | explicit, context, prevented key, native, caller popup | Reversing state precedence, rerouting the ref, dropping standalone popup relationships, or allowing context semantics to be clobbered fails focused DOM tests. | `audit:CommandPaletteInput/testing` |
|
|
186
|
+
| FR4 | `CommandPaletteInput.test.tsx` | numeric, empty, busy, caller content | Truthiness routing creates empty chrome or moves numeric content away from the trailing edge. | `audit:CommandPaletteInput/behavior` |
|
|
187
|
+
| FR5 | focused unit tests plus exact-head browser evidence | enabled, disabled, inline | Eligible focus is lost, disabled focus is scheduled, or inline mode steals focus. | `audit:CommandPaletteInput/behavior` |
|
|
188
|
+
| AR1–AR3 | unit tests, exact-head axe/browser run, and source review | standalone, open, closed, highlighted | Wrong role/state, consumer clobbering of an owned attribute, or a placeholder-derived name fails semantics and name assertions. | `audit:CommandPaletteInput/a11y` |
|
|
189
|
+
| Theming/RTL | target inventory, Storybook fixture, and RTL D2 audit | standalone trailing content, contextual | Target loss or physical ordering fails the owned fixture. | `audit:CommandPaletteInput/theming` |
|
|
190
|
+
|
|
191
|
+
## Decision log
|
|
192
|
+
|
|
193
|
+
### DEC-1 — The query field's default name is "Search commands"
|
|
194
|
+
|
|
195
|
+
**Reference:** `component:CommandPaletteInput/DEC-1`
|
|
196
|
+
**Decider:** `cixzhang`, 2026-10-14
|
|
197
|
+
|
|
198
|
+
A screen-reader user reaching the field hears what it does, whatever the
|
|
199
|
+
placeholder says or whether one is set. The default is a fixed, localizable
|
|
200
|
+
"Search commands"; `label` and `aria-label` replace it, and placeholder text is
|
|
201
|
+
never the name.
|
|
202
|
+
|
|
203
|
+
Rejected: falling back to the placeholder, which a caller writes as a visual
|
|
204
|
+
hint and AST-056 AR2 does not accept as a name.
|
|
205
|
+
|
|
206
|
+
## Open questions
|
|
207
|
+
|
|
208
|
+
- **OQ1 — How should the released `onValueChange(value)` primary callback and
|
|
209
|
+
native-event `onChange(event)` exception migrate to the shared `onChange`
|
|
210
|
+
callback grammar without breaking existing consumers?** (`human-api`)
|
|
211
|
+
|
|
212
|
+
## Content boundary
|
|
213
|
+
|
|
214
|
+
This file does not duplicate consumer prop tables/examples, current audit
|
|
215
|
+
results, implementation steps, or family/system rules. It links to their owners.
|