@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
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
/** @vitest-environment jsdom */
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @file ResizeHandle.a11y.test.tsx
|
|
6
|
+
* @input WINDOW_SPLITTER_PATTERN bound to ResizeHandle's representative states
|
|
7
|
+
* @output jsdom-lane proof of the DOM expectations and an honest "unrun" report for the browser layers
|
|
8
|
+
* @position Binding test for component:Resizable AR1 (the Chromium spec covers the rest)
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import {cleanup, render, screen} from '@testing-library/react';
|
|
12
|
+
import {describe, expect, it} from 'vitest';
|
|
13
|
+
import {
|
|
14
|
+
WINDOW_SPLITTER_PATTERN,
|
|
15
|
+
checkAccessibilitySpec,
|
|
16
|
+
createJsdomHarness,
|
|
17
|
+
expectAccessibilitySpec,
|
|
18
|
+
summarize,
|
|
19
|
+
type BindingResult,
|
|
20
|
+
} from '@astryxdesign/a11y-spec';
|
|
21
|
+
import {RESIZE_HANDLE_KNOWN_FAILURES} from './ResizeHandle.a11y.known-failures';
|
|
22
|
+
import {
|
|
23
|
+
BARE_PANE_ID,
|
|
24
|
+
renderResizeHandleState,
|
|
25
|
+
} from './ResizeHandle.a11y.renders';
|
|
26
|
+
import {
|
|
27
|
+
RESIZE_HANDLE_BINDING_STATES,
|
|
28
|
+
RESIZE_HANDLE_EXCLUSIONS,
|
|
29
|
+
type ResizeHandleBindingState,
|
|
30
|
+
} from './ResizeHandle.a11y.states';
|
|
31
|
+
|
|
32
|
+
function separator(state: ResizeHandleBindingState): HTMLElement {
|
|
33
|
+
return screen.getByRole('separator', {name: state.label});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function pane(): HTMLElement {
|
|
37
|
+
const element = document.getElementById(BARE_PANE_ID);
|
|
38
|
+
if (element == null) {
|
|
39
|
+
throw new Error('the bare pane is not rendered');
|
|
40
|
+
}
|
|
41
|
+
return element;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function checkState(
|
|
45
|
+
state: ResizeHandleBindingState,
|
|
46
|
+
): Promise<BindingResult> {
|
|
47
|
+
return checkAccessibilitySpec({
|
|
48
|
+
spec: WINDOW_SPLITTER_PATTERN,
|
|
49
|
+
binding: 'ResizeHandle',
|
|
50
|
+
state: state.id,
|
|
51
|
+
facts: state.facts,
|
|
52
|
+
knownFailures: RESIZE_HANDLE_KNOWN_FAILURES,
|
|
53
|
+
mount: async () => {
|
|
54
|
+
render(renderResizeHandleState(state));
|
|
55
|
+
return createJsdomHarness({
|
|
56
|
+
subject: separator(state),
|
|
57
|
+
related: {pane: pane()},
|
|
58
|
+
});
|
|
59
|
+
},
|
|
60
|
+
unmount: cleanup,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
describe('ResizeHandle — window splitter pattern, jsdom lane', () => {
|
|
65
|
+
it.each(
|
|
66
|
+
RESIZE_HANDLE_BINDING_STATES.map(
|
|
67
|
+
state => [state.id, state.summary, state] as const,
|
|
68
|
+
),
|
|
69
|
+
)('%s — %s', async (_id, _summary, state) => {
|
|
70
|
+
await expectAccessibilitySpec({
|
|
71
|
+
spec: WINDOW_SPLITTER_PATTERN,
|
|
72
|
+
binding: 'ResizeHandle',
|
|
73
|
+
state: state.id,
|
|
74
|
+
facts: state.facts,
|
|
75
|
+
knownFailures: RESIZE_HANDLE_KNOWN_FAILURES,
|
|
76
|
+
render: () => {
|
|
77
|
+
render(renderResizeHandleState(state));
|
|
78
|
+
},
|
|
79
|
+
subject: () => separator(state),
|
|
80
|
+
related: () => ({pane: pane()}),
|
|
81
|
+
cleanup,
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('runs the DOM layer and reports the browser-owned outcomes as unrun', async () => {
|
|
86
|
+
const results: BindingResult[] = [];
|
|
87
|
+
for (const state of RESIZE_HANDLE_BINDING_STATES) {
|
|
88
|
+
results.push(await checkState(state));
|
|
89
|
+
}
|
|
90
|
+
const report = summarize(WINDOW_SPLITTER_PATTERN, results);
|
|
91
|
+
expect(report.counts.pass).toBeGreaterThan(0);
|
|
92
|
+
expect(report.unrunLayers).toEqual(['accessibility-tree', 'real-browser']);
|
|
93
|
+
expect(report.counts.unexpectedPass).toBe(0);
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
describe('ResizeHandle binding inventory', () => {
|
|
98
|
+
it('gives every representative state a distinct checked-in story', () => {
|
|
99
|
+
const stories = RESIZE_HANDLE_BINDING_STATES.map(state => state.storyId);
|
|
100
|
+
expect(new Set(stories).size).toBe(stories.length);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('keeps pointer and pane-cycling ownership explicit', () => {
|
|
104
|
+
expect(RESIZE_HANDLE_EXCLUSIONS.map(exclusion => exclusion.id)).toEqual([
|
|
105
|
+
'sidenav-binding',
|
|
106
|
+
'pointer-drag-model',
|
|
107
|
+
'pane-cycling',
|
|
108
|
+
]);
|
|
109
|
+
for (const exclusion of RESIZE_HANDLE_EXCLUSIONS) {
|
|
110
|
+
expect(exclusion.owner.length, exclusion.id).toBeGreaterThan(20);
|
|
111
|
+
expect(exclusion.reason.length, exclusion.id).toBeGreaterThan(80);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('renders exactly one named separator and its pane for every state', () => {
|
|
116
|
+
for (const state of RESIZE_HANDLE_BINDING_STATES) {
|
|
117
|
+
render(renderResizeHandleState(state));
|
|
118
|
+
expect(separator(state), state.id).toBeTruthy();
|
|
119
|
+
expect(pane(), state.id).toBeTruthy();
|
|
120
|
+
cleanup();
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
});
|
|
@@ -303,6 +303,9 @@ function persistState(key: string, state: PersistedResizableState): void {
|
|
|
303
303
|
|
|
304
304
|
/** The released compatibility basis when there is no window to measure. */
|
|
305
305
|
const SERVER_BASIS = 1200;
|
|
306
|
+
|
|
307
|
+
/** A store that never changes on its own; the snapshot is re-read on render. */
|
|
308
|
+
const noopSubscribe = () => () => {};
|
|
306
309
|
const DEFAULT_SIZE_FALLBACK = 250;
|
|
307
310
|
const RESIZABLE_SIZE_GUIDANCE =
|
|
308
311
|
'Use a non-negative number of pixels, an exact "Npx" string, an exact ' +
|
|
@@ -699,6 +702,23 @@ function useSingleResizable(config: UseResizableSingleConfig): ResizableRegion {
|
|
|
699
702
|
() => SERVER_BASIS,
|
|
700
703
|
);
|
|
701
704
|
|
|
705
|
+
// The window's extent along the hook's axis, for the REPORTED maximum of an
|
|
706
|
+
// unbounded region (never for clamping). Read through the same store shape
|
|
707
|
+
// so a server-rendered handle hydrates with no maximum and gains the real
|
|
708
|
+
// one on the first client render, instead of a hydration mismatch. It takes
|
|
709
|
+
// no resize subscription: an unbounded pixel region observes nothing
|
|
710
|
+
// (component:Resizable Performance and resources).
|
|
711
|
+
const windowExtent = useSyncExternalStore(
|
|
712
|
+
noopSubscribe,
|
|
713
|
+
() =>
|
|
714
|
+
typeof window === 'undefined'
|
|
715
|
+
? null
|
|
716
|
+
: direction === 'vertical'
|
|
717
|
+
? window.innerHeight
|
|
718
|
+
: window.innerWidth,
|
|
719
|
+
() => null,
|
|
720
|
+
);
|
|
721
|
+
|
|
702
722
|
// With a container, its content box is the basis; without one, the released
|
|
703
723
|
// viewport basis. Before a supplied container has been measured — the first
|
|
704
724
|
// render, the server, and any moment it is display:none or detached — the
|
|
@@ -1026,6 +1046,29 @@ function useSingleResizable(config: UseResizableSingleConfig): ResizableRegion {
|
|
|
1026
1046
|
// percentage bound stays pinned to the container size at grab time.
|
|
1027
1047
|
const onResizeCancel = releaseGestureBasis;
|
|
1028
1048
|
|
|
1049
|
+
// The maximum a handle REPORTS (End uses only a configured maximum). A
|
|
1050
|
+
// configured maximum wins. Otherwise a measured extent stands in — the
|
|
1051
|
+
// container's content box while a percentage bound already observes it, or
|
|
1052
|
+
// the window's extent along the axis — and never drops below the current size, so
|
|
1053
|
+
// `aria-valuenow` can never exceed `aria-valuemax` (a saved, default, or
|
|
1054
|
+
// pre-resize size may already be larger than the window). An unobserved
|
|
1055
|
+
// container reports nothing: measuring it would add an observer to an
|
|
1056
|
+
// atomic pixel path.
|
|
1057
|
+
const measuredBasisForMax = hasContainer
|
|
1058
|
+
? hasPositiveMeasurement && observeContainerBasis
|
|
1059
|
+
? containerBasis
|
|
1060
|
+
: null
|
|
1061
|
+
: windowExtent;
|
|
1062
|
+
// Never below the announced value either: a collapsed pane announces the
|
|
1063
|
+
// resolved minimum as its value, so the stand-in floors there as well, and
|
|
1064
|
+
// `aria-valuemax` can never fall under `aria-valuemin`.
|
|
1065
|
+
const effectiveMaxPx =
|
|
1066
|
+
resolvedMax !== Infinity
|
|
1067
|
+
? resolvedMax
|
|
1068
|
+
: measuredBasisForMax == null
|
|
1069
|
+
? undefined
|
|
1070
|
+
: Math.max(measuredBasisForMax, isCollapsed ? resolvedMin : size);
|
|
1071
|
+
|
|
1029
1072
|
const props: ResizableProps = {
|
|
1030
1073
|
_size: isCollapsed ? 0 : size,
|
|
1031
1074
|
_isCollapsed: isCollapsed,
|
|
@@ -1041,6 +1084,16 @@ function useSingleResizable(config: UseResizableSingleConfig): ResizableRegion {
|
|
|
1041
1084
|
_direction: direction,
|
|
1042
1085
|
_isResizableProps: true,
|
|
1043
1086
|
};
|
|
1087
|
+
collapseControls.set(props, {collapse, expand});
|
|
1088
|
+
// Without a configured maximum the basis stands in — only when it is a
|
|
1089
|
+
// real measurement (an observed container, or the window), never the
|
|
1090
|
+
// temporary 1200px placeholder (component:Resizable Performance: atomic
|
|
1091
|
+
// pixel paths add no observer, so an unobserved container stays unknown).
|
|
1092
|
+
// The released no-container basis is the window WIDTH on both axes; a
|
|
1093
|
+
// vertical region's reported maximum reads the window height instead.
|
|
1094
|
+
if (effectiveMaxPx != null) {
|
|
1095
|
+
effectiveMaxima.set(props, effectiveMaxPx);
|
|
1096
|
+
}
|
|
1044
1097
|
|
|
1045
1098
|
return {
|
|
1046
1099
|
size: isCollapsed ? 0 : size,
|
|
@@ -1097,6 +1150,48 @@ function useMultiResizable(
|
|
|
1097
1150
|
// Public API
|
|
1098
1151
|
// =============================================================================
|
|
1099
1152
|
|
|
1153
|
+
/**
|
|
1154
|
+
* Collapse/expand for a region, keyed by the `ResizableProps` object the hook
|
|
1155
|
+
* returns. A handle's Enter and double-click use them so the pane restores
|
|
1156
|
+
* its previous position (APG window splitter) rather than emulating the
|
|
1157
|
+
* toggle with a resize to the minimum.
|
|
1158
|
+
*
|
|
1159
|
+
* Kept off `ResizableProps` on purpose: that type is exported, so a new field
|
|
1160
|
+
* on it — optional or underscored — is a public delta. This module-private
|
|
1161
|
+
* map and {@link getCollapseControls} are the package's own channel between
|
|
1162
|
+
* the hook and the handle; neither is re-exported.
|
|
1163
|
+
*/
|
|
1164
|
+
type CollapseControls = {collapse: () => void; expand: () => void};
|
|
1165
|
+
const collapseControls = new WeakMap<ResizableProps, CollapseControls>();
|
|
1166
|
+
|
|
1167
|
+
/**
|
|
1168
|
+
* The maximum an unbounded region reports as `aria-valuemax`: a measured
|
|
1169
|
+
* extent that stands in for the missing configured maximum — the container's
|
|
1170
|
+
* content box on the active axis while a percentage bound already observes
|
|
1171
|
+
* it, or the window's extent along the axis — floored at the current size
|
|
1172
|
+
* and, while collapsed, at the resolved minimum. The region is never clamped
|
|
1173
|
+
* to it; it is what the separator announces. Kept off the exported
|
|
1174
|
+
* `ResizableProps` for the same reason as the collapse controls;
|
|
1175
|
+
* `getEffectiveMaxPx` is internal.
|
|
1176
|
+
*/
|
|
1177
|
+
const effectiveMaxima = new WeakMap<ResizableProps, number>();
|
|
1178
|
+
|
|
1179
|
+
/** The reported maximum for `props`, or `undefined` for a hand-built object. */
|
|
1180
|
+
export function getEffectiveMaxPx(props: ResizableProps): number | undefined {
|
|
1181
|
+
return effectiveMaxima.get(props);
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
/**
|
|
1185
|
+
* The collapse/expand pair the hook registered for `props`, or `undefined`
|
|
1186
|
+
* for a hand-built `ResizableProps` object (which the handle then toggles
|
|
1187
|
+
* with a resize gesture). Internal to the package.
|
|
1188
|
+
*/
|
|
1189
|
+
export function getCollapseControls(
|
|
1190
|
+
props: ResizableProps,
|
|
1191
|
+
): CollapseControls | undefined {
|
|
1192
|
+
return collapseControls.get(props);
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1100
1195
|
/** Removed keys must fail even when a variable bypasses excess-property checks. */
|
|
1101
1196
|
type RejectRemovedPixelBounds<Config> = Config extends unknown
|
|
1102
1197
|
? Config & {minSizePx?: never; maxSizePx?: never}
|
|
@@ -245,9 +245,9 @@ export const docs = {
|
|
|
245
245
|
},
|
|
246
246
|
{
|
|
247
247
|
name: 'variant',
|
|
248
|
-
type: "'input' | 'ghost'",
|
|
248
|
+
type: "'input' | 'secondary' | 'ghost'",
|
|
249
249
|
description:
|
|
250
|
-
'Visual trigger style. input is the bordered input treatment for forms; ghost is borderless and
|
|
250
|
+
'Visual trigger style. input is the bordered input treatment for forms; secondary matches the secondary buttons of the active theme (borderless and neutral-filled by default) for navs and toolbars; ghost is borderless and transparent, matching ghost buttons for toolbar usage.',
|
|
251
251
|
default: "'input'",
|
|
252
252
|
},
|
|
253
253
|
{
|
|
@@ -307,8 +307,9 @@ export const docs = {
|
|
|
307
307
|
name: 'statusVariant',
|
|
308
308
|
type: "'attached' | 'detached' | 'tooltip'",
|
|
309
309
|
description:
|
|
310
|
-
'How the status message is placed relative to the input. attached overlaps directly below the bordered input and is only valid for the input variant; ghost selectors detach attached status messages by default. Use tooltip for compact toolbar controls.',
|
|
311
|
-
default:
|
|
310
|
+
'How the status message is placed relative to the input. attached overlaps directly below the bordered input and is only valid for the input variant; secondary and ghost selectors detach attached status messages by default. Use tooltip for compact toolbar controls.',
|
|
311
|
+
default:
|
|
312
|
+
"'attached' for input selectors; 'detached' for secondary and ghost selectors",
|
|
312
313
|
},
|
|
313
314
|
{
|
|
314
315
|
name: 'renderOption',
|
|
@@ -439,7 +440,7 @@ export const docs = {
|
|
|
439
440
|
{
|
|
440
441
|
guidance: true,
|
|
441
442
|
description:
|
|
442
|
-
'Use variant="ghost" when a selector sits in a toolbar with ghost buttons. If validation status is needed there, prefer statusVariant="tooltip" so the toolbar height stays compact.',
|
|
443
|
+
'Use variant="secondary" when a selector sits in a nav or toolbar beside secondary buttons or a segmented control, so it shares their treatment instead of reading as a form field. Use variant="ghost" when a selector sits in a toolbar with ghost buttons. If validation status is needed there, prefer statusVariant="tooltip" so the toolbar height stays compact.',
|
|
443
444
|
},
|
|
444
445
|
{
|
|
445
446
|
guidance: true,
|
|
@@ -576,7 +577,7 @@ export const docsDense = {
|
|
|
576
577
|
{
|
|
577
578
|
guidance: true,
|
|
578
579
|
description:
|
|
579
|
-
'Use variant="ghost" in toolbars with ghost buttons; prefer statusVariant="tooltip" for compact validation status.',
|
|
580
|
+
'Use variant="secondary" in navs/toolbars beside secondary buttons; use variant="ghost" in toolbars with ghost buttons; prefer statusVariant="tooltip" for compact validation status.',
|
|
580
581
|
},
|
|
581
582
|
{
|
|
582
583
|
guidance: false,
|
|
@@ -16,6 +16,8 @@ verified_by:
|
|
|
16
16
|
packages/core/src/Selector/Selector.source-build.test.mjs,
|
|
17
17
|
packages/core/src/Selector/__tests__/Selector.listbox.a11y.test.tsx,
|
|
18
18
|
packages/core/src/Selector/__tests__/Listbox.a11y.chromium.spec.ts,
|
|
19
|
+
packages/core/src/Selector/__tests__/Selector.combobox.a11y.test.tsx,
|
|
20
|
+
packages/core/src/Selector/__tests__/Selector.combobox.a11y.chromium.spec.ts,
|
|
19
21
|
apps/storybook/stories/Selector.stories.tsx,
|
|
20
22
|
.github/scripts/story-play-guard.js,
|
|
21
23
|
]
|
|
@@ -60,6 +62,8 @@ connection between the closed trigger and its selection surface.
|
|
|
60
62
|
- `isReadOnly` is additive and defaults to `false`. It preserves the selected
|
|
61
63
|
value, focus, and form participation while removing selection-surface and
|
|
62
64
|
editing affordances. `isDisabled` takes precedence when both are set.
|
|
65
|
+
- `secondary` is an additive trigger variant. `input` remains the default;
|
|
66
|
+
existing `input` and `ghost` callers keep their released behavior.
|
|
63
67
|
- `spec:AST-004/DEC-1` governs the state-derived indicator-space behavior in FR3.
|
|
64
68
|
- 0.7.0 removes the `selector-clear-icon` alias; the shared clear glyph remains
|
|
65
69
|
available through `input-clear-icon`.
|
|
@@ -122,15 +126,15 @@ connection between the closed trigger and its selection surface.
|
|
|
122
126
|
This table names semantic concepts reviewers need. Prop syntax, complete defaults,
|
|
123
127
|
and examples remain in `Selector.doc.mjs`.
|
|
124
128
|
|
|
125
|
-
| Concept | Closed values or states | Meaning | Availability by variant/orientation/state | Default | Owner | Stability
|
|
126
|
-
| ---------------------- | -------------------------------------- | -------------------------------------------------------- | ----------------------------------------- | ---------- | -------- |
|
|
127
|
-
| trigger variant | `input`, `ghost`
|
|
128
|
-
| size | `sm`, `md`, `lg` | Trigger and option-row density | All presentations | `md` | Selector | released
|
|
129
|
-
| selected-mark position | `start`, `end` | Logical edge containing a rendered selection mark | Every option row | `end` | Selector | released
|
|
130
|
-
| presentation | `popover`, `bottom-sheet`, `adaptive` | Anchored pointer surface or modal compact-touch surface | All trigger variants | `adaptive` | Selector | released
|
|
131
|
-
| popup semantics | `listbox`; modal dialog containing one | Semantics follow the active presentation | Popover; bottom sheet | `listbox` | Selector | released
|
|
132
|
-
| option-row state | `selected`, `disabled` | Stable theming state on each option row | Every rendered option | neither | Selector | released
|
|
133
|
-
| read-only state | `false`, `true` | Preserves and submits value without selection affordance | Closed trigger | `false` | Caller | additive
|
|
129
|
+
| Concept | Closed values or states | Meaning | Availability by variant/orientation/state | Default | Owner | Stability | Invalid-value behavior |
|
|
130
|
+
| ---------------------- | -------------------------------------- | -------------------------------------------------------- | ----------------------------------------- | ---------- | -------- | ------------------------------ | ------------------------------- |
|
|
131
|
+
| trigger variant | `input`, `secondary`, `ghost` | Form-field or button-aligned toolbar presentation | All trigger states | `input` | Selector | released; `secondary` additive | TypeScript rejects other values |
|
|
132
|
+
| size | `sm`, `md`, `lg` | Trigger and option-row density | All presentations | `md` | Selector | released | TypeScript rejects other values |
|
|
133
|
+
| selected-mark position | `start`, `end` | Logical edge containing a rendered selection mark | Every option row | `end` | Selector | released | TypeScript rejects other values |
|
|
134
|
+
| presentation | `popover`, `bottom-sheet`, `adaptive` | Anchored pointer surface or modal compact-touch surface | All trigger variants | `adaptive` | Selector | released | TypeScript rejects other values |
|
|
135
|
+
| popup semantics | `listbox`; modal dialog containing one | Semantics follow the active presentation | Popover; bottom sheet | `listbox` | Selector | released | No separate role prop is public |
|
|
136
|
+
| option-row state | `selected`, `disabled` | Stable theming state on each option row | Every rendered option | neither | Selector | released | Unknown states are not emitted |
|
|
137
|
+
| read-only state | `false`, `true` | Preserves and submits value without selection affordance | Closed trigger | `false` | Caller | additive | Boolean normalization |
|
|
134
138
|
|
|
135
139
|
## Behavioral and layout contract
|
|
136
140
|
|
|
@@ -217,14 +221,22 @@ These requirements describe shipped behavior on current `main`.
|
|
|
217
221
|
|
|
218
222
|
No current design spec is linked.
|
|
219
223
|
|
|
220
|
-
| Anatomy or state | Current representation requirement
|
|
221
|
-
| -------------------------------- |
|
|
222
|
-
| selected mark and option spacing | Empty resolved marks collapse; visible marks retain space, so row label geometry may vary by state
|
|
223
|
-
| input
|
|
224
|
+
| Anatomy or state | Current representation requirement | Representation authority | Hierarchy role | Component contract |
|
|
225
|
+
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ------------------------ | --------------------------- | ------------------ |
|
|
226
|
+
| selected mark and option spacing | Empty resolved marks collapse; visible marks retain space, so row label geometry may vary by state | `spec:AST-004/DEC-1` | supporting | FR3 |
|
|
227
|
+
| trigger variants | `input` reads as a form field; `secondary` matches adjacent secondary `Button`s; `ghost` matches adjacent ghost `Button`s | `component:Selector/DD1` | form or peer action control | Public concepts |
|
|
224
228
|
|
|
225
229
|
The first row implements the state-derived spacing decision in
|
|
226
230
|
`spec:AST-004/DEC-1`.
|
|
227
231
|
|
|
232
|
+
### Design decisions
|
|
233
|
+
|
|
234
|
+
<!-- design-decisions:v1 -->
|
|
235
|
+
|
|
236
|
+
| ID | Decision | Intent or reason | Applies to | Allowed variation |
|
|
237
|
+
| --- | ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
|
|
238
|
+
| DD1 | A `secondary` Selector matches the visual role of adjacent secondary `Button`s. | A mixed toolbar or navigation area reads as one action hierarchy instead of making the Selector look like a form field or a ghost action. | The secondary trigger at rest and through its states | Themes may choose exact tokens while preserving parity with their secondary `Button` treatment. |
|
|
239
|
+
|
|
228
240
|
### Theming anatomy
|
|
229
241
|
|
|
230
242
|
<!-- anatomy-theming:v1 -->
|
|
@@ -319,17 +331,18 @@ new theming target.
|
|
|
319
331
|
|
|
320
332
|
## Verification map
|
|
321
333
|
|
|
322
|
-
| Contract
|
|
323
|
-
|
|
|
324
|
-
| FR1, AR2, AR3
|
|
325
|
-
| FR2
|
|
326
|
-
| FR3, AV1
|
|
327
|
-
| FR4, AR1, AR2
|
|
328
|
-
| AR1, AV2
|
|
329
|
-
| FR5
|
|
330
|
-
|
|
|
331
|
-
|
|
|
332
|
-
|
|
|
334
|
+
| Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
|
|
335
|
+
| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- |
|
|
336
|
+
| FR1, AR2, AR3 | `Selector.test.tsx` selection, focus, and keyboard suites | closed/open, search/non-search, disabled option | Removing selection wiring, focus movement, or keyboard behavior fails the named interaction tests | `audit:Selector/behavior` |
|
|
337
|
+
| FR2 | placement and selected-item geometry tests | default, explicit, RTL, transformed entry | Using the wrong positioning model fails the expected position-area or margin | `audit:Selector/behavior` |
|
|
338
|
+
| FR3, AV1 | Focused `Selector.test.tsx` computed-display checks plus guarded Chromium Storybook matrix and stable visual stories | popover/bottom sheet, narrow/wide, start/end, LTR/RTL, selected/unselected, check/radio | Empty output reserves width, visible output collapses, logical placement flips incorrectly, or row content overflows | `audit:Selector/design-rendered` |
|
|
339
|
+
| FR4, AR1, AR2 | presentation tests plus `aria-haspopup` source review | pointer, compact coarse pointer, search/non-search | Wrong Popover/dialog roles or focus destinations fail tests; `aria-haspopup` values require source/a11y review | `audit:Selector/accessibility` |
|
|
340
|
+
| AR1, AV2 | `Selector.listbox.a11y.test.tsx` and `Listbox.a11y.chromium.spec.ts` against the shared Listbox contract | popover/sheet, flat/grouped, selected/unselected, disabled, search, loading, custom RTL | A new or wider loss of role, listbox/option name, state, or ownership gates; the exact unnamed no-search sheet state remains known debt | `audit:Selector/accessibility` |
|
|
341
|
+
| FR5, FR6, AR1, AR2 (anchored), AR4 | `Selector.combobox.a11y.test.tsx` and `Selector.combobox.a11y.chromium.spec.ts` against the shared Combobox contract | closed, open with active option, read-only, busy, bottom-sheet open, search input with active option | The trigger or search input loses its role/name/state or popup kind, its open popup or active option relationship breaks, or read-only exposes a selection surface; the bottom-sheet trigger's `aria-controls` naming the inner listbox remains exact known debt | `audit:Selector/accessibility` |
|
|
342
|
+
| FR5 | loading, empty-state, and live-region tests | empty options, unmatched search, loading | Empty/no-results output appears or is announced while loading | `audit:Selector/behavior` |
|
|
343
|
+
| FR6, AR4 | read-only interaction, form, ARIA, and theme-state tests | search/non-search, clearable, open→read-only, disabled precedence | A value changes, popup or edit affordance remains, form value disappears, or read-only semantics are absent | `audit:Selector/accessibility` |
|
|
344
|
+
| FR7 | `Selector.test.tsx` press model suite | finger release over another option, finger/mouse release outside, listbox marker | The press option is selected, the listbox takes focus, a finger release outside closes the list, or the stray click selects | `audit:Selector/behavior` |
|
|
345
|
+
| source-build contract | `Selector.source-build.test.mjs` | package source compiled by consumer Babel | Moving evaluated StyleX values outside the supported source form fails compilation | `audit:Selector/code-health` |
|
|
333
346
|
|
|
334
347
|
## Decision log
|
|
335
348
|
|