@astryxdesign/core 0.6.2 → 0.6.3-canary.0788c49
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 +81 -0
- package/dist/BottomSheet/BottomSheet.d.ts +1 -1
- package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheet.js +3 -1
- package/dist/BottomSheet/BottomSheetPanel.d.ts +7 -5
- package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetPanel.js +56 -19
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +13 -28
- package/dist/Chat/ChatComposer.d.ts.map +1 -1
- package/dist/Chat/ChatComposer.js +10 -5
- package/dist/Chat/ChatComposerDrawer.d.ts +19 -5
- package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
- package/dist/Chat/ChatComposerDrawer.js +48 -23
- package/dist/Chat/ChatComposerInput.d.ts +11 -3
- package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
- package/dist/Chat/ChatComposerInput.js +63 -16
- package/dist/Chat/ChatDictationButton.d.ts +3 -2
- package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
- package/dist/Chat/ChatDictationButton.js +6 -4
- package/dist/Chat/ChatLayout.d.ts +19 -0
- package/dist/Chat/ChatLayout.d.ts.map +1 -1
- package/dist/Chat/ChatLayout.js +19 -0
- package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
- package/dist/Chat/ChatLayoutScrollButton.js +44 -34
- package/dist/Chat/ChatMessageBubble.d.ts +2 -0
- package/dist/Chat/ChatMessageBubble.d.ts.map +1 -1
- package/dist/Chat/ChatMessageBubble.js +5 -3
- package/dist/Chat/ChatMessageList.d.ts +2 -1
- package/dist/Chat/ChatMessageList.d.ts.map +1 -1
- package/dist/Chat/ChatMessageList.js +4 -3
- package/dist/Chat/ChatMessageMetadata.d.ts +5 -4
- package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
- package/dist/Chat/ChatMessageMetadata.js +12 -9
- package/dist/Chat/ChatSendButton.d.ts +2 -1
- package/dist/Chat/ChatSendButton.d.ts.map +1 -1
- package/dist/Chat/ChatSendButton.js +6 -4
- package/dist/Chat/index.d.ts +1 -1
- package/dist/Chat/index.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +12 -2
- package/dist/Citation/Citation.d.ts +1 -1
- package/dist/Citation/Citation.d.ts.map +1 -1
- package/dist/Citation/Citation.js +3 -2
- package/dist/CodeBlock/highlightRanges.d.ts.map +1 -1
- package/dist/CodeBlock/highlightRanges.js +14 -3
- package/dist/Collapsible/Collapsible.d.ts.map +1 -1
- package/dist/Collapsible/Collapsible.js +6 -1
- package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteInput.js +1 -1
- package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
- package/dist/ComplexSelector/ComplexSelector.js +1 -1
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +4 -4
- package/dist/DateInput/NativeDateField.d.ts.map +1 -1
- package/dist/DateInput/NativeDateField.js +16 -16
- package/dist/DateInput/TouchDateField.d.ts.map +1 -1
- package/dist/DateInput/TouchDateField.js +2 -2
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +4 -4
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +8 -8
- package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
- package/dist/DateTimeInput/TouchDateTimeField.js +4 -4
- package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts +9 -3
- package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts.map +1 -1
- package/dist/DateTimeInput/nativePickerSegmentStyles.js +3 -3
- package/dist/Dialog/DialogHeader.d.ts +8 -1
- package/dist/Dialog/DialogHeader.d.ts.map +1 -1
- package/dist/Dialog/DialogHeader.js +13 -4
- package/dist/Field/InputClearButton.d.ts +4 -2
- package/dist/Field/InputClearButton.d.ts.map +1 -1
- package/dist/Field/InputClearButton.js +4 -2
- package/dist/Field/PanelSearchInput.d.ts.map +1 -1
- package/dist/Field/PanelSearchInput.js +1 -1
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +7 -7
- package/dist/Icon/Icon.d.ts +6 -31
- package/dist/Icon/Icon.d.ts.map +1 -1
- package/dist/Icon/Icon.js +8 -71
- package/dist/Icon/IconDefaultSizeContext.d.ts +4 -0
- package/dist/Icon/IconDefaultSizeContext.d.ts.map +1 -0
- package/dist/Icon/IconDefaultSizeContext.js +18 -0
- package/dist/Icon/IconSize.stylex.d.ts +65 -0
- package/dist/Icon/IconSize.stylex.d.ts.map +1 -0
- package/dist/Icon/IconSize.stylex.js +75 -0
- package/dist/Item/Item.d.ts +1 -1
- package/dist/Item/Item.d.ts.map +1 -1
- package/dist/Item/Item.js +4 -3
- package/dist/Kbd/Kbd.d.ts +5 -3
- package/dist/Kbd/Kbd.d.ts.map +1 -1
- package/dist/Kbd/Kbd.js +36 -42
- package/dist/Link/Link.d.ts.map +1 -1
- package/dist/Link/Link.js +6 -2
- package/dist/Link/useLinkComponent.d.ts +5 -15
- package/dist/Link/useLinkComponent.d.ts.map +1 -1
- package/dist/Link/useLinkComponent.js +34 -51
- package/dist/List/List.d.ts +19 -1
- package/dist/List/List.d.ts.map +1 -1
- package/dist/List/List.js +9 -2
- package/dist/List/ListContext.d.ts +1 -0
- package/dist/List/ListContext.d.ts.map +1 -1
- package/dist/List/ListContext.js +2 -1
- package/dist/List/ListItem.d.ts +1 -1
- package/dist/List/ListItem.d.ts.map +1 -1
- package/dist/List/ListItem.js +9 -2
- package/dist/Markdown/Markdown.d.ts +8 -2
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.fr23.bench.d.ts +2 -0
- package/dist/Markdown/Markdown.fr23.bench.d.ts.map +1 -0
- package/dist/Markdown/Markdown.fr23.bench.js +150 -0
- package/dist/Markdown/Markdown.fr23.sampling.d.ts +2 -0
- package/dist/Markdown/Markdown.fr23.sampling.d.ts.map +1 -0
- package/dist/Markdown/Markdown.fr23.sampling.js +43 -0
- package/dist/Markdown/Markdown.js +262 -109
- package/dist/Markdown/ast.d.ts +162 -0
- package/dist/Markdown/ast.d.ts.map +1 -0
- package/dist/Markdown/ast.js +74 -0
- package/dist/Markdown/index.d.ts +5 -3
- package/dist/Markdown/index.d.ts.map +1 -1
- package/dist/Markdown/index.js +3 -2
- package/dist/Markdown/parser/index.d.ts +10 -0
- package/dist/Markdown/parser/index.d.ts.map +1 -0
- package/dist/Markdown/parser/index.js +10 -0
- package/dist/Markdown/parser.d.ts +126 -58
- package/dist/Markdown/parser.d.ts.map +1 -1
- package/dist/Markdown/parser.js +726 -177
- package/dist/Markdown/plugins/frontmatter.d.ts +32 -0
- package/dist/Markdown/plugins/frontmatter.d.ts.map +1 -0
- package/dist/Markdown/plugins/frontmatter.js +132 -0
- package/dist/Markdown/plugins/index.d.ts +17 -0
- package/dist/Markdown/plugins/index.d.ts.map +1 -0
- package/dist/Markdown/plugins/index.js +14 -0
- package/dist/Markdown/plugins/protocol.d.ts +191 -0
- package/dist/Markdown/plugins/protocol.d.ts.map +1 -0
- package/dist/Markdown/plugins/protocol.js +957 -0
- package/dist/Markdown/plugins/semanticFence.d.ts +36 -0
- package/dist/Markdown/plugins/semanticFence.d.ts.map +1 -0
- package/dist/Markdown/plugins/semanticFence.js +213 -0
- package/dist/Markdown/plugins/softBreaks.d.ts +3 -0
- package/dist/Markdown/plugins/softBreaks.d.ts.map +1 -0
- package/dist/Markdown/plugins/softBreaks.js +172 -0
- package/dist/Markdown/plugins/sourceDecoration.d.ts +76 -0
- package/dist/Markdown/plugins/sourceDecoration.d.ts.map +1 -0
- package/dist/Markdown/plugins/sourceDecoration.js +393 -0
- package/dist/Markdown/plugins/textTransform.d.ts +30 -0
- package/dist/Markdown/plugins/textTransform.d.ts.map +1 -0
- package/dist/Markdown/plugins/textTransform.js +374 -0
- package/dist/Markdown/remark.d.ts +196 -0
- package/dist/Markdown/remark.d.ts.map +1 -0
- package/dist/Markdown/remark.js +1062 -0
- package/dist/Markdown/url.d.ts +6 -0
- package/dist/Markdown/url.d.ts.map +1 -0
- package/dist/Markdown/url.js +31 -0
- package/dist/Markdown/utils.d.ts +4 -2
- package/dist/Markdown/utils.d.ts.map +1 -1
- package/dist/Markdown/utils.js +2 -1
- package/dist/MetadataList/MetadataList.js +3 -3
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +4 -4
- package/dist/Outline/index.d.ts +1 -0
- package/dist/Outline/index.d.ts.map +1 -1
- package/dist/Outline/parseOutlineFromMarkdown.d.ts +7 -1
- package/dist/Outline/parseOutlineFromMarkdown.d.ts.map +1 -1
- package/dist/Outline/parseOutlineFromMarkdown.js +14 -8
- package/dist/Outline/useOutlineFromMarkdown.d.ts +3 -1
- package/dist/Outline/useOutlineFromMarkdown.d.ts.map +1 -1
- package/dist/Outline/useOutlineFromMarkdown.js +8 -3
- package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchEditPopover.js +46 -30
- package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchValueEditor.js +5 -0
- package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
- package/dist/ProgressBar/ProgressBar.js +36 -31
- package/dist/RadioList/RadioListItem.d.ts.map +1 -1
- package/dist/RadioList/RadioListItem.js +13 -1
- package/dist/ScrollableArea/ScrollableArea.d.ts +1 -0
- package/dist/ScrollableArea/ScrollableArea.d.ts.map +1 -1
- package/dist/ScrollableArea/ScrollableArea.js +1 -0
- package/dist/SegmentedControl/SegmentedControl.d.ts +1 -1
- package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControl.js +1 -0
- package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.js +5 -5
- package/dist/Selector/Selector.d.ts +9 -7
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +16 -7
- package/dist/SideNav/SideNav.d.ts +2 -1
- package/dist/SideNav/SideNav.d.ts.map +1 -1
- package/dist/SideNav/SideNav.js +9 -3
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +28 -12
- package/dist/Spinner/Spinner.d.ts.map +1 -1
- package/dist/Spinner/Spinner.js +23 -7
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +11 -0
- package/dist/TabList/Tab.d.ts +1 -1
- package/dist/TabList/Tab.d.ts.map +1 -1
- package/dist/TabList/Tab.js +20 -7
- package/dist/Table/Table.d.ts +1 -0
- package/dist/Table/Table.d.ts.map +1 -1
- package/dist/Table/Table.js +29 -13
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +1 -1
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +2 -2
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +4 -4
- package/dist/Timer/Timer.d.ts +49 -0
- package/dist/Timer/Timer.d.ts.map +1 -0
- package/dist/Timer/Timer.js +158 -0
- package/dist/Timer/index.d.ts +9 -0
- package/dist/Timer/index.d.ts.map +1 -0
- package/dist/Timer/index.js +10 -0
- package/dist/ToggleButton/ToggleButton.d.ts +9 -6
- package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
- package/dist/ToggleButton/ToggleButton.js +15 -27
- package/dist/TopNav/TopNavMenu.d.ts +1 -1
- package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMenu.js +3 -2
- package/dist/TreeList/TreeList.d.ts.map +1 -1
- package/dist/TreeList/TreeList.js +3 -0
- package/dist/TreeList/TreeListItem.d.ts +6 -1
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +12 -2
- package/dist/TreeList/TreeListTypes.d.ts +8 -1
- package/dist/TreeList/TreeListTypes.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +16 -7
- package/dist/astryx.css +27 -11
- package/dist/hooks/scrollKeyboardDelegation.d.ts +3 -0
- package/dist/hooks/scrollKeyboardDelegation.d.ts.map +1 -0
- package/dist/hooks/scrollKeyboardDelegation.js +146 -0
- package/dist/hooks/useClickableContainer.d.ts +10 -1
- package/dist/hooks/useClickableContainer.d.ts.map +1 -1
- package/dist/hooks/useClickableContainer.js +15 -4
- package/dist/hooks/useScrollableArea.d.ts +6 -2
- package/dist/hooks/useScrollableArea.d.ts.map +1 -1
- package/dist/hooks/useScrollableArea.js +17 -5
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/theme/declarationBoundary.d.ts +17 -0
- package/dist/theme/declarationBoundary.d.ts.map +1 -0
- package/dist/theme/declarationBoundary.js +343 -0
- package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
- package/dist/theme/derivedVarRegistry.js +4 -0
- package/dist/theme/generateThemeRules.d.ts +13 -7
- package/dist/theme/generateThemeRules.d.ts.map +1 -1
- package/dist/theme/generateThemeRules.js +140 -34
- package/dist/utils/interactionOverlay.stylex.d.ts +8 -0
- package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
- package/dist/utils/interactionOverlay.stylex.js +9 -0
- package/dist/utils/safeUrl.d.ts +11 -0
- package/dist/utils/safeUrl.d.ts.map +1 -0
- package/dist/utils/safeUrl.js +78 -0
- package/locales/af-ZA.json +530 -1
- package/locales/ar-SA.json +490 -1
- package/locales/ca-ES.json +514 -1
- package/locales/cs-CZ.json +498 -1
- package/locales/da-DK.json +522 -1
- package/locales/de-DE.json +522 -1
- package/locales/el-GR.json +498 -1
- package/locales/es-ES.json +510 -1
- package/locales/fi-FI.json +498 -1
- package/locales/fr-FR.json +534 -1
- package/locales/he-IL.json +498 -1
- package/locales/hu-HU.json +498 -1
- package/locales/it-IT.json +510 -1
- package/locales/ja-JP.json +490 -1
- package/locales/ko-KR.json +498 -1
- package/locales/nl-NL.json +534 -1
- package/locales/no-NO.json +510 -1
- package/locales/pl-PL.json +506 -1
- package/locales/pt-BR.json +506 -1
- package/locales/pt-PT.json +506 -1
- package/locales/ro-RO.json +506 -1
- package/locales/ru-RU.json +498 -1
- package/locales/sr-SP.json +498 -1
- package/locales/sv-SE.json +502 -1
- package/locales/tr-TR.json +498 -1
- package/locales/uk-UA.json +498 -1
- package/locales/vi-VN.json +502 -1
- package/locales/zh-CN.json +490 -1
- package/locales/zh-TW.json +490 -1
- package/package.json +24 -4
- package/src/BottomSheet/BottomSheet.doc.mjs +8 -1
- package/src/BottomSheet/BottomSheet.spec.md +46 -20
- package/src/BottomSheet/BottomSheet.test.tsx +6 -3
- package/src/BottomSheet/BottomSheet.tsx +3 -1
- package/src/BottomSheet/BottomSheetKeyboard.test.tsx +195 -0
- package/src/BottomSheet/BottomSheetPanel.test.tsx +11 -1
- package/src/BottomSheet/BottomSheetPanel.tsx +49 -16
- package/src/BottomSheet/__tests__/BottomSheetKeyboard.a11y.browser.spec.ts +344 -0
- package/src/Button/Button.doc.mjs +5 -5
- package/src/Button/Button.tsx +15 -13
- package/src/Button/__tests__/Button.a11y.chromium.spec.ts +17 -1
- package/src/Button/__tests__/Button.a11y.known-failures.ts +0 -29
- package/src/Button/__tests__/Button.a11y.renders.tsx +9 -2
- package/src/Button/__tests__/Button.a11y.states.ts +9 -0
- package/src/Chat/ChatComposer.doc.mjs +14 -0
- package/src/Chat/ChatComposer.spec.md +230 -0
- package/src/Chat/ChatComposer.test.tsx +57 -0
- package/src/Chat/ChatComposer.tsx +21 -9
- package/src/Chat/ChatComposerDrawer.doc.mjs +63 -5
- package/src/Chat/ChatComposerDrawer.spec.md +267 -0
- package/src/Chat/ChatComposerDrawer.test.tsx +81 -12
- package/src/Chat/ChatComposerDrawer.tsx +38 -9
- package/src/Chat/ChatComposerInput.doc.mjs +114 -26
- package/src/Chat/ChatComposerInput.spec.md +185 -0
- package/src/Chat/ChatComposerInput.test.tsx +113 -3
- package/src/Chat/ChatComposerInput.tsx +78 -13
- package/src/Chat/ChatComposerTokenElement.spec.md +152 -0
- package/src/Chat/ChatComposerTokenElement.test.tsx +85 -0
- package/src/Chat/ChatDictationButton.doc.mjs +3 -3
- package/src/Chat/ChatDictationButton.spec.md +160 -0
- package/src/Chat/ChatDictationButton.test.tsx +92 -27
- package/src/Chat/ChatDictationButton.tsx +8 -6
- package/src/Chat/ChatLayout.doc.mjs +12 -4
- package/src/Chat/ChatLayout.spec.md +271 -0
- package/src/Chat/ChatLayout.test.tsx +28 -0
- package/src/Chat/ChatLayout.tsx +19 -0
- package/src/Chat/ChatLayoutScrollButton.spec.md +338 -0
- package/src/Chat/ChatLayoutScrollButton.test.tsx +31 -0
- package/src/Chat/ChatLayoutScrollButton.tsx +31 -14
- package/src/Chat/ChatMessageBubble.doc.mjs +28 -15
- package/src/Chat/ChatMessageBubble.spec.md +263 -0
- package/src/Chat/ChatMessageBubble.test.tsx +93 -0
- package/src/Chat/ChatMessageBubble.tsx +8 -3
- package/src/Chat/ChatMessageList.spec.md +222 -0
- package/src/Chat/ChatMessageList.test.tsx +64 -2
- package/src/Chat/ChatMessageList.tsx +4 -3
- package/src/Chat/ChatMessageMetadata.doc.mjs +57 -3
- package/src/Chat/ChatMessageMetadata.spec.md +220 -0
- package/src/Chat/ChatMessageMetadata.test.tsx +34 -0
- package/src/Chat/ChatMessageMetadata.tsx +13 -13
- package/src/Chat/ChatSendButton.doc.mjs +32 -0
- package/src/Chat/ChatSendButton.spec.md +227 -0
- package/src/Chat/ChatSendButton.test.tsx +128 -8
- package/src/Chat/ChatSendButton.tsx +6 -4
- package/src/Chat/__tests__/ChatLayoutScrollButton.a11y.chromium.spec.ts +514 -0
- package/src/Chat/__tests__/ChatLayoutScrollButtonSurface.a11y.chromium.spec.ts +740 -0
- package/src/Chat/__tests__/ChatMessageBubble.a11y.chromium.spec.ts +457 -0
- package/src/Chat/__tests__/ChatMessageBubble.auditProvenance.test.ts +91 -0
- package/src/Chat/__tests__/ChatMessageBubble.auditProvenance.ts +91 -0
- package/src/Chat/__tests__/ChatMessageList.a11y.chromium.spec.ts +456 -0
- package/src/Chat/__tests__/ChatMessageMetadata.a11y.chromium.spec.ts +413 -0
- package/src/Chat/__tests__/ChatSendButton.a11y.chromium.spec.ts +1522 -0
- package/src/Chat/index.ts +1 -0
- package/src/CheckboxInput/CheckboxInput.doc.mjs +11 -0
- package/src/CheckboxInput/CheckboxInput.test.tsx +34 -0
- package/src/CheckboxInput/CheckboxInput.tsx +21 -1
- package/src/Citation/Citation.doc.mjs +2 -2
- package/src/Citation/Citation.test.tsx +17 -0
- package/src/Citation/Citation.tsx +4 -2
- package/src/ClickableCard/ClickableCard.doc.mjs +2 -2
- package/src/ClickableCard/ClickableCard.test.tsx +102 -5
- package/src/CodeBlock/highlightRanges.test.ts +143 -1
- package/src/CodeBlock/highlightRanges.ts +15 -5
- package/src/Collapsible/Collapsible.doc.mjs +11 -0
- package/src/Collapsible/Collapsible.test.tsx +21 -0
- package/src/Collapsible/Collapsible.tsx +5 -0
- package/src/CommandPalette/CommandPaletteInput.tsx +6 -1
- package/src/ComplexSelector/ComplexSelector.tsx +6 -1
- package/src/DateInput/DateInput.tsx +6 -1
- package/src/DateInput/NativeDateField.tsx +24 -8
- package/src/DateInput/TouchDateField.tsx +6 -2
- package/src/DateRangeInput/DateRangeInput.tsx +6 -1
- package/src/DateTimeInput/DateTimeInput.tsx +6 -1
- package/src/DateTimeInput/TouchDateTimeField.tsx +6 -1
- package/src/DateTimeInput/nativePickerSegmentStyles.ts +24 -8
- package/src/Dialog/Dialog.doc.mjs +2 -0
- package/src/Dialog/DialogHeader.doc.mjs +22 -0
- package/src/Dialog/DialogHeader.test.tsx +167 -3
- package/src/Dialog/DialogHeader.tsx +37 -6
- package/src/Dialog/modules/DialogHeader.spec.md +101 -42
- package/src/DropdownMenu/DropdownMenu.test.tsx +5 -2
- package/src/Field/InputClearButton.test.tsx +17 -3
- package/src/Field/InputClearButton.tsx +5 -2
- package/src/Field/PanelSearchInput.tsx +5 -2
- package/src/FieldStatus/__tests__/StatusMessage.a11y.states.ts +1 -1
- package/src/FileInput/FileInput.tsx +11 -2
- package/src/Icon/Icon.doc.mjs +7 -5
- package/src/Icon/Icon.spec.md +81 -40
- package/src/Icon/Icon.test.tsx +6 -3
- package/src/Icon/Icon.tsx +20 -68
- package/src/Icon/IconDefaultSizeContext.ts +23 -0
- package/src/Icon/IconSize.stylex.ts +70 -0
- package/src/IconButton/IconButton.doc.mjs +3 -3
- package/src/IconButton/IconButton.test.tsx +40 -0
- package/src/Item/Item.doc.mjs +6 -2
- package/src/Item/Item.tsx +9 -3
- package/src/Kbd/Kbd.doc.mjs +3 -3
- package/src/Kbd/Kbd.test.tsx +57 -1
- package/src/Kbd/Kbd.tsx +57 -37
- package/src/Layout/LayoutFooter.doc.mjs +17 -0
- package/src/Link/Link.doc.mjs +17 -4
- package/src/Link/Link.test.tsx +24 -0
- package/src/Link/Link.tsx +5 -0
- package/src/Link/LinkProvider.doc.mjs +2 -2
- package/src/Link/__tests__/Link.navigation.a11y.chromium.spec.ts +261 -0
- package/src/Link/useLinkComponent.test.tsx +333 -0
- package/src/Link/useLinkComponent.ts +29 -57
- package/src/List/List.doc.mjs +6 -0
- package/src/List/List.spec.md +200 -0
- package/src/List/List.test.tsx +117 -1
- package/src/List/List.tsx +22 -2
- package/src/List/ListContext.tsx +3 -1
- package/src/List/ListItem.doc.mjs +2 -2
- package/src/List/ListItem.source-build.test.mjs +41 -0
- package/src/List/ListItem.tsx +26 -2
- package/src/Markdown/Markdown.doc.mjs +300 -2
- package/src/Markdown/Markdown.fr23.bench.ts +174 -0
- package/src/Markdown/Markdown.fr23.perf.test.ts +249 -0
- package/src/Markdown/Markdown.fr23.sampling.ts +49 -0
- package/src/Markdown/Markdown.helpers.perf.test.ts +489 -0
- package/src/Markdown/Markdown.public.test.ts +130 -3
- package/src/Markdown/Markdown.renderBoundary.test.tsx +72 -0
- package/src/Markdown/Markdown.spec.md +210 -45
- package/src/Markdown/Markdown.test.tsx +87 -3
- package/src/Markdown/Markdown.tsx +414 -135
- package/src/Markdown/ast.test.ts +307 -0
- package/src/Markdown/ast.ts +337 -0
- package/src/Markdown/incremental.test.ts +43 -0
- package/src/Markdown/index.ts +37 -1
- package/src/Markdown/modules/remark.spec.md +269 -0
- package/src/Markdown/modules/softBreaks.spec.md +137 -0
- package/src/Markdown/parser/index.ts +64 -0
- package/src/Markdown/parser.public.test.ts +103 -0
- package/src/Markdown/parser.test.ts +38 -6
- package/src/Markdown/parser.ts +1221 -242
- package/src/Markdown/plugins/frontmatter.test.tsx +125 -0
- package/src/Markdown/plugins/frontmatter.ts +198 -0
- package/src/Markdown/plugins/index.ts +54 -0
- package/src/Markdown/plugins/protocol.test.tsx +1022 -0
- package/src/Markdown/plugins/protocol.ts +1618 -0
- package/src/Markdown/plugins/semanticFence.test.tsx +546 -0
- package/src/Markdown/plugins/semanticFence.ts +424 -0
- package/src/Markdown/plugins/softBreaks.test.tsx +172 -0
- package/src/Markdown/plugins/softBreaks.ts +169 -0
- package/src/Markdown/plugins/sourceDecoration.test.tsx +799 -0
- package/src/Markdown/plugins/sourceDecoration.ts +539 -0
- package/src/Markdown/plugins/textTransform.test.ts +467 -0
- package/src/Markdown/plugins/textTransform.ts +554 -0
- package/src/Markdown/remark.test.tsx +1877 -0
- package/src/Markdown/remark.ts +1574 -0
- package/src/Markdown/url.ts +36 -0
- package/src/Markdown/utils.ts +13 -1
- package/src/MetadataList/MetadataList.test.tsx +4 -2
- package/src/MetadataList/MetadataList.tsx +3 -3
- package/src/MultiSelector/MultiSelector.test.tsx +1 -35
- package/src/MultiSelector/__tests__/MultiSelector.listbox.a11y.test.tsx +128 -0
- package/src/NumberInput/NumberInput.tsx +6 -1
- package/src/Outline/Outline.doc.mjs +7 -5
- package/src/Outline/Outline.spec.md +1 -1
- package/src/Outline/index.ts +1 -0
- package/src/Outline/modules/parseOutlineFromMarkdown.spec.md +142 -0
- package/src/Outline/parseOutlineFromMarkdown.ts +40 -10
- package/src/Outline/useOutlineFromMarkdown.ts +15 -3
- package/src/PowerSearch/PowerSearch.doc.mjs +2 -2
- package/src/PowerSearch/PowerSearchEditPopover.test.tsx +150 -1
- package/src/PowerSearch/PowerSearchEditPopover.tsx +51 -28
- package/src/PowerSearch/PowerSearchValueEditor.test.tsx +51 -0
- package/src/PowerSearch/PowerSearchValueEditor.tsx +4 -0
- package/src/ProgressBar/ProgressBar.test.tsx +29 -11
- package/src/ProgressBar/ProgressBar.tsx +59 -72
- package/src/RadioList/RadioList.doc.mjs +11 -0
- package/src/RadioList/RadioList.test.tsx +32 -0
- package/src/RadioList/RadioListItem.tsx +25 -1
- package/src/ScrollableArea/ScrollableArea.tsx +1 -0
- package/src/ScrollableArea/modules/useScrollableArea.spec.md +50 -22
- package/src/SegmentedControl/SegmentedControl.doc.mjs +2 -2
- package/src/SegmentedControl/SegmentedControl.test.tsx +61 -0
- package/src/SegmentedControl/SegmentedControl.tsx +2 -1
- package/src/SegmentedControl/SegmentedControlItem.tsx +6 -9
- package/src/Selector/Selector.doc.mjs +3 -3
- package/src/Selector/Selector.spec.md +51 -49
- package/src/Selector/Selector.test.tsx +61 -55
- package/src/Selector/Selector.tsx +34 -15
- package/src/Selector/__tests__/Listbox.a11y.chromium.spec.ts +130 -0
- package/src/Selector/__tests__/Listbox.a11y.dom.ts +38 -0
- package/src/Selector/__tests__/Listbox.a11y.inventory.test.ts +63 -0
- package/src/Selector/__tests__/Listbox.a11y.known-failures.ts +37 -0
- package/src/Selector/__tests__/Listbox.a11y.states.ts +232 -0
- package/src/Selector/__tests__/Selector.a11y.chromium.spec.ts +45 -0
- package/src/Selector/__tests__/Selector.listbox.a11y.test.tsx +121 -0
- package/src/SideNav/SideNav.doc.mjs +1 -1
- package/src/SideNav/SideNav.test.tsx +10 -0
- package/src/SideNav/SideNav.tsx +14 -2
- package/src/Slider/Slider.doc.mjs +17 -3
- package/src/Slider/Slider.test.tsx +221 -0
- package/src/Slider/Slider.tsx +40 -9
- package/src/Spinner/Spinner.test.tsx +4 -0
- package/src/Spinner/Spinner.tsx +31 -18
- package/src/Switch/Switch.doc.mjs +11 -0
- package/src/Switch/Switch.test.tsx +16 -0
- package/src/Switch/Switch.tsx +28 -0
- package/src/TabList/Tab.tsx +35 -7
- package/src/TabList/TabList.doc.mjs +11 -0
- package/src/TabList/TabList.spec.md +204 -0
- package/src/TabList/TabList.test.tsx +66 -0
- package/src/TabList/__tests__/Tabs.a11y.known-failures.ts +1 -34
- package/src/Table/Table.doc.mjs +1 -1
- package/src/Table/Table.spec.md +54 -40
- package/src/Table/Table.test.tsx +83 -10
- package/src/Table/Table.tsx +30 -22
- package/src/Table/__tests__/TableScroll.a11y.chromium.spec.ts +137 -0
- package/src/TextArea/TextArea.tsx +6 -1
- package/src/TextInput/TextInput.test.tsx +20 -1
- package/src/TextInput/TextInput.tsx +6 -1
- package/src/TimeInput/TimeInput.tsx +6 -1
- package/src/Timer/Timer.doc.mjs +183 -0
- package/src/Timer/Timer.spec.md +215 -0
- package/src/Timer/Timer.test.tsx +302 -0
- package/src/Timer/Timer.tsx +258 -0
- package/src/Timer/index.ts +11 -0
- package/src/ToggleButton/ToggleButton.doc.mjs +3 -3
- package/src/ToggleButton/ToggleButton.test.tsx +299 -4
- package/src/ToggleButton/ToggleButton.tsx +26 -33
- package/src/ToggleButton/ToggleButtonGroup.doc.mjs +3 -3
- package/src/ToggleButton/__tests__/ToggleButton.a11y.chromium.spec.ts +209 -0
- package/src/Token/Token.doc.mjs +2 -2
- package/src/Tokenizer/Tokenizer.spec.md +142 -75
- package/src/TopNav/TopNavMenu.doc.mjs +2 -2
- package/src/TopNav/TopNavMenu.test.tsx +30 -0
- package/src/TopNav/TopNavMenu.tsx +7 -2
- package/src/TreeList/TreeList.doc.mjs +3 -3
- package/src/TreeList/TreeList.spec.md +123 -75
- package/src/TreeList/TreeList.test.tsx +29 -0
- package/src/TreeList/TreeList.tsx +3 -0
- package/src/TreeList/TreeListItem.tsx +15 -1
- package/src/TreeList/TreeListTypes.ts +11 -1
- package/src/Typeahead/BaseTypeahead.spec.md +4 -3
- package/src/Typeahead/BaseTypeahead.tsx +21 -7
- package/src/Typeahead/Typeahead.test.tsx +53 -0
- package/src/__tests__/PressedState.a11y.chromium.spec.ts +813 -0
- package/src/__tests__/pressState.ts +93 -0
- package/src/hooks/scrollKeyboardDelegation.test.ts +155 -0
- package/src/hooks/scrollKeyboardDelegation.ts +233 -0
- package/src/hooks/useClickableContainer.test.tsx +236 -0
- package/src/hooks/useClickableContainer.ts +20 -4
- package/src/hooks/useScrollableArea.doc.mjs +15 -3
- package/src/hooks/useScrollableArea.test.tsx +59 -1
- package/src/hooks/useScrollableArea.ts +34 -10
- package/src/index.ts +3 -0
- package/src/inputFontFloor.test.ts +106 -0
- package/src/tailwind-theme.css +0 -6
- package/src/theme/Theme.test.tsx +32 -0
- package/src/theme/declarationBoundary.test.ts +126 -0
- package/src/theme/declarationBoundary.ts +347 -0
- package/src/theme/derivedVarRegistry.test.ts +7 -0
- package/src/theme/derivedVarRegistry.ts +1 -0
- package/src/theme/generateThemeRules.test.ts +526 -1
- package/src/theme/generateThemeRules.ts +228 -50
- package/src/theme/tokenValueCompat.test.ts +4 -1
- package/src/utils/interactionOverlay.stylex.ts +20 -0
- package/src/utils/safeUrl.test.ts +88 -0
- package/src/utils/safeUrl.ts +85 -0
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 3
|
|
3
|
+
template_version: 5
|
|
4
|
+
kind: component
|
|
5
|
+
id: component:ChatLayoutScrollButton
|
|
6
|
+
authority: draft
|
|
7
|
+
archive_reason: null
|
|
8
|
+
superseded_by: null
|
|
9
|
+
approved_by: null
|
|
10
|
+
approved_at: null
|
|
11
|
+
owners: [cixzhang]
|
|
12
|
+
review_triggers: [public-api, behavior, accessibility, theming, testing]
|
|
13
|
+
verified_by:
|
|
14
|
+
[
|
|
15
|
+
packages/core/src/Chat/ChatLayoutScrollButton.test.tsx,
|
|
16
|
+
packages/core/src/Chat/__tests__/ChatLayoutScrollButton.a11y.chromium.spec.ts,
|
|
17
|
+
packages/core/src/Chat/__tests__/ChatLayoutScrollButtonSurface.a11y.chromium.spec.ts,
|
|
18
|
+
apps/storybook/stories/ChatLayout.stories.tsx,
|
|
19
|
+
apps/storybook/rtl-audit/verified-not-applicable.json,
|
|
20
|
+
]
|
|
21
|
+
modules: []
|
|
22
|
+
families: []
|
|
23
|
+
design_specs: []
|
|
24
|
+
architecture:
|
|
25
|
+
[
|
|
26
|
+
architecture:public-component-api,
|
|
27
|
+
architecture:component-style-authoring,
|
|
28
|
+
architecture:component-theming-surface,
|
|
29
|
+
architecture:theme-tokens,
|
|
30
|
+
architecture:component-test-sufficiency,
|
|
31
|
+
architecture:knowledge-contracts,
|
|
32
|
+
]
|
|
33
|
+
contributing: []
|
|
34
|
+
system_specs: [spec:AST-029]
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
# ChatLayoutScrollButton component contract
|
|
38
|
+
|
|
39
|
+
## Contract at a glance
|
|
40
|
+
|
|
41
|
+
| Area | Contract |
|
|
42
|
+
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
43
|
+
| Public contract | `isVisible`, `label`, and `onClick`, plus root `div` passthrough, styles, and ref. No public surface changes here. |
|
|
44
|
+
| Behavior | A pill holding one ghost Button. Hidden state paints nothing and leaves the tab order; a non-empty `label` expands the pill and becomes the visible text; omitted or empty renders icon-only. |
|
|
45
|
+
| End-user impact | A theme that restyles the documented target now repaints the pill a reader sees instead of an invisible full-width row behind it. |
|
|
46
|
+
| Builder impact | None. Props, defaults, DOM shape, ref target, and passthrough element are unchanged. |
|
|
47
|
+
| Compatibility/readiness | Patch-compatible repair. The public target keeps its name and stays a single target; it moves onto the element that paints, which no `guaranteedProperties` declaration existed to promise before. Three inherited violations remain open (FR1a, FR3a, FR6a). |
|
|
48
|
+
| Review checks | Reject a target on the centring row, a hidden pill that keeps keyboard focus, a non-empty label that is not also the accessible name, or a state that paints identically to its opposite. FR1a, FR3a, and FR6a are recorded open violations, not acceptances. |
|
|
49
|
+
| Governing rules | `architecture:component-theming-surface/INV4, INV6`; `architecture:component-style-authoring/INV1, INV5`; `architecture:public-component-api/INV5, INV6, INV8`; WCAG 2.2 SC 2.4.7 and SC 2.5.8 (AA). |
|
|
50
|
+
|
|
51
|
+
This table is a review projection; the body below is authoritative.
|
|
52
|
+
|
|
53
|
+
## Intent
|
|
54
|
+
|
|
55
|
+
ChatLayoutScrollButton is the floating return-to-newest affordance for a chat
|
|
56
|
+
transcript. It owns the pill's appearance and its visible/hidden presentation;
|
|
57
|
+
it owns no scroll state. ChatLayout composes it with `useChatStreamScroll` and
|
|
58
|
+
`useChatNewMessages` by default, and a caller may replace or remove it through
|
|
59
|
+
`ChatLayout`'s `scrollButton` slot.
|
|
60
|
+
|
|
61
|
+
This record is an observational backfill written during the 2026-09-23
|
|
62
|
+
whole-component audit. It describes verified shipped behavior and the one
|
|
63
|
+
objective repair that travels with it. It adds no behavior, default,
|
|
64
|
+
compatibility promise, or design decision.
|
|
65
|
+
|
|
66
|
+
## Compatibility and migration
|
|
67
|
+
|
|
68
|
+
- Released default preserved: yes — `@astryxdesign/core@0.6.3` ships
|
|
69
|
+
`isVisible`, `label`, and `onClick` with the same meanings.
|
|
70
|
+
- Compatibility class: theming repair. The target name, its documentation entry,
|
|
71
|
+
and its count are unchanged; only the element carrying it moves, from the
|
|
72
|
+
centring row to the pill it centres.
|
|
73
|
+
- Controlled/uncontrolled behavior: unchanged — visibility is a required caller
|
|
74
|
+
input, and the component holds no state.
|
|
75
|
+
- Migration decision: `component:ChatLayoutScrollButton/DEC-1`
|
|
76
|
+
|
|
77
|
+
Consumer migration instructions belong in consumer docs and release notes.
|
|
78
|
+
|
|
79
|
+
## Ownership boundary
|
|
80
|
+
|
|
81
|
+
**Owns**
|
|
82
|
+
|
|
83
|
+
- The pill surface: its fill, elevation, radius, resolved height, and the
|
|
84
|
+
collapsed/expanded width ceiling.
|
|
85
|
+
- The visible/hidden presentation, including removal from sequential focus
|
|
86
|
+
navigation while hidden.
|
|
87
|
+
- The default accessible name when the caller supplies no `label`.
|
|
88
|
+
- Centring within its parent, and the gap between the pill and what sits below.
|
|
89
|
+
|
|
90
|
+
**Does not own / non-goals**
|
|
91
|
+
|
|
92
|
+
- Scroll position, lock state, and new-message detection — owned by
|
|
93
|
+
`useChatStreamScroll` and `useChatNewMessages`.
|
|
94
|
+
- Placement in the chat dock and whether the affordance renders at all — owned
|
|
95
|
+
by `component:ChatLayout` through its `scrollButton` slot.
|
|
96
|
+
- Action semantics, focus ring, press feedback, size geometry, and variant
|
|
97
|
+
surface — owned by `component:Button`, which this component composes.
|
|
98
|
+
|
|
99
|
+
## Public concepts
|
|
100
|
+
|
|
101
|
+
| Concept | Closed values or states | Meaning | Availability by variant/orientation/state | Default | Owner | Stability | Invalid-value behavior |
|
|
102
|
+
| ------------------- | --------------------------- | -------------------------------------------------------------------- | ----------------------------------------- | ------------------- | ----------------------------------- | --------- | ------------------------------------------------- |
|
|
103
|
+
| `isVisible` | `true`, `false` | Whether the affordance is presented and operable | always | required | `component:ChatLayoutScrollButton` | stable | required boolean; no fallback |
|
|
104
|
+
| `label` — omitted | `undefined` | Icon-only; the translated default becomes the accessible name | always | this is the default | `component:ChatLayoutScrollButton` | stable | — |
|
|
105
|
+
| `label` — non-empty | any non-empty string | Visible text, which is also the accessible name | always | — | `component:ChatLayoutScrollButton` | stable | — |
|
|
106
|
+
| `label` — empty | `''` | Icon-only with an empty accessible name — see FR1a | always | — | `component:ChatLayoutScrollButton` | stable | no fallback is applied; the control is unnamed |
|
|
107
|
+
| `onClick` | `() => void` | Activation callback; receives no event | always | required | `component:ChatLayoutScrollButton` | stable | required; no default action |
|
|
108
|
+
| root `div` | `BaseProps<HTMLDivElement>` | `ref`, `xstyle`, `className`, `style`, and remaining DOM passthrough | always | none | `architecture:public-component-api` | stable | `onClick` is omitted from the inherited DOM props |
|
|
109
|
+
|
|
110
|
+
Consumer syntax and prop defaults remain in `ChatLayoutScrollButton.doc.mjs`.
|
|
111
|
+
|
|
112
|
+
## Behavioral and layout contract
|
|
113
|
+
|
|
114
|
+
Draft requirements identify their basis so observed code is not mistaken for an
|
|
115
|
+
intentional decision. A `current` contract contains no unresolved rows.
|
|
116
|
+
|
|
117
|
+
| ID | Candidate invariant | Basis | Draft review state |
|
|
118
|
+
| ---- | ------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | --------------------- |
|
|
119
|
+
| FR1 | The control MUST expose a non-empty accessible name in every reachable state. | WCAG 2.2 SC 4.1.2 | settled obligation |
|
|
120
|
+
| FR1a | `label` omitted uses the translated default; a non-empty `label` is the name. **`label=''` currently satisfies neither** — see below. | current behavior, which violates FR1 | **violation of FR1** |
|
|
121
|
+
| FR2 | While `isVisible` is false the pill MUST paint nothing and MUST NOT accept focus, programmatic or sequential. | current behavior; WCAG 2.2 SC 2.4.7 | settled |
|
|
122
|
+
| FR3 | While `isVisible` is true the pill MUST remain keyboard reachable and activate on Enter. | current behavior; WCAG 2.2 SC 2.1.1 | settled |
|
|
123
|
+
| FR3a | A focused control MUST paint a visible focus indicator. **The ring is currently clipped away entirely** — see below. | WCAG 2.2 SC 2.4.7; `spec:AST-020/FR1` | **violation of FR3a** |
|
|
124
|
+
| FR4 | A **non-empty** `label` MUST render as visible text; omitted or empty renders icon-only with no visible text. | current behavior | settled |
|
|
125
|
+
| FR5 | The pill MUST take its resolved height from the element-size token so no theme scale makes it clip the Button it wraps. | current behavior | settled |
|
|
126
|
+
| FR6 | The public theming target MUST sit on the pill — the element painting fill, elevation, and radius — not on the row that centres it. | `architecture:component-theming-surface/INV4` | settled |
|
|
127
|
+
| FR6a | The target MUST expose the state axes that drive its painted styles. **Currently it reflects none** — see below. | `architecture:component-theming-surface/INV6` | **violation of INV6** |
|
|
128
|
+
| FR7 | The transition between states MUST collapse to `0s` under `prefers-reduced-motion: reduce`. | current behavior | settled |
|
|
129
|
+
| FR8 | The collapsed control MUST fit a 24x24 CSS-px square. | WCAG 2.2 SC 2.5.8 (AA) | settled |
|
|
130
|
+
| FR9 | Consumer `ref`, styles, and remaining DOM props MUST reach the component's outer element. | current behavior; `architecture:public-component-api/INV5, INV6, INV8` | settled |
|
|
131
|
+
|
|
132
|
+
**FR1a — the empty-label naming gap.** `label=''` is permitted by the public
|
|
133
|
+
type and is what ordinary caller code produces from an empty or not-yet-loaded
|
|
134
|
+
string. It reaches the Button as `label=''`, `aria-label=''`, and
|
|
135
|
+
`isIconOnly={true}`, because `??` passes an empty string through. Button sets
|
|
136
|
+
its own `aria-label` only when `label !== ''`, so the caller's empty
|
|
137
|
+
`aria-label` survives; icon-only renders no visible text; and the chevron Icon
|
|
138
|
+
carries no `label`, so it is `aria-hidden="true"`. The result is a focusable,
|
|
139
|
+
operable control with no accessible name.
|
|
140
|
+
|
|
141
|
+
This record states the obligation and records the current behavior as violating
|
|
142
|
+
it. Closing the gap means choosing between falling back to the default name,
|
|
143
|
+
rejecting the value, or treating an empty label as a caller error — a public
|
|
144
|
+
API and compatibility decision that belongs to the owner, not to an audit. See
|
|
145
|
+
OQ7.
|
|
146
|
+
|
|
147
|
+
**FR3a — the clipped focus ring.** The composed Button declares a focus ring
|
|
148
|
+
as an `outline` at a positive `outline-offset`, so it is painted entirely
|
|
149
|
+
outside the button's border box. The button fills the pill exactly (measured
|
|
150
|
+
32x32 in 32x32 collapsed, 149x32 in 149x32 labelled), and the pill clips with
|
|
151
|
+
`overflow: hidden`, which it needs to keep the collapse/expand animation inside
|
|
152
|
+
its own rounded shape. There is therefore no room for the ring on any side and
|
|
153
|
+
none of it is painted: captured frames of the focused control are byte-identical
|
|
154
|
+
to the resting control in both configurations and both color modes.
|
|
155
|
+
|
|
156
|
+
Keyboard access itself is intact — the control takes focus and activates — so
|
|
157
|
+
this is a visibility defect, not a reachability one. The remedy is a production
|
|
158
|
+
change to how the pill clips or where the ring is drawn, and the choice between
|
|
159
|
+
those changes rendered geometry, so it needs a visual review rather than a
|
|
160
|
+
settled correction. `spec:AST-029/FR7` would allow a settled objective fix to
|
|
161
|
+
travel with an audit; this one is not settled, so it is outside **this** PR.
|
|
162
|
+
Recorded as OQ8.
|
|
163
|
+
|
|
164
|
+
**FR6a — the unreflected state axes.** `isVisible` selects visible/hidden
|
|
165
|
+
styles and `label` selects collapsed/expanded styles, both on the painting
|
|
166
|
+
target, and `themeProps('chat-layout-scroll-button')` is called with no state
|
|
167
|
+
argument. A theme can therefore restyle the pill but cannot address either
|
|
168
|
+
state. Naming those axes is new public theming surface, so the shape belongs to
|
|
169
|
+
the owner. See OQ1.
|
|
170
|
+
|
|
171
|
+
### Allowed variation
|
|
172
|
+
|
|
173
|
+
- **AV1 — Expanded width.** The labelled pill's width ceiling is a component
|
|
174
|
+
design decision, not a theme value. What happens to a label past that ceiling
|
|
175
|
+
is not settled here; see OQ3.
|
|
176
|
+
- **AV2 — Resolved geometry.** Height, radius, spacing, and duration resolve
|
|
177
|
+
from theme tokens, so absolute values differ by theme without becoming
|
|
178
|
+
regressions.
|
|
179
|
+
- **AV3 — Composition.** ChatLayout renders this by default, but a caller may
|
|
180
|
+
substitute any node or remove the affordance entirely.
|
|
181
|
+
|
|
182
|
+
### Representative states
|
|
183
|
+
|
|
184
|
+
| State | Required invariant | Allowed variation |
|
|
185
|
+
| ------------------------- | ------------------------------------------------------------------------------------------------------------ | --------------------------------- |
|
|
186
|
+
| hidden | paints nothing, refuses focus, keeps its layout box (FR2) | transition duration |
|
|
187
|
+
| visible, label omitted | named from the default, focusable, fits a 24px square, no visible text (FR1, FR3, FR4, FR8) | resolved pill size |
|
|
188
|
+
| visible, non-empty label | the label is both the visible text and the accessible name (FR1, FR4) | expanded width up to the ceiling |
|
|
189
|
+
| visible, empty label | **fails FR1** — icon-only with an empty accessible name (FR1a) | none; this is a recorded defect |
|
|
190
|
+
| visible, hovered | the pointer paints a state distinct from rest | the overlay the theme resolves |
|
|
191
|
+
| visible, keyboard-focused | **fails FR3a** — focus is held and `:focus-visible` matches, but the ring is clipped away and paints nothing | none; this is a recorded defect |
|
|
192
|
+
| visible, pressed | the press paints a state distinct from hover and rest | the pressed treatment |
|
|
193
|
+
| any visible state, themed | the documented target repaints the pill (FR6); its state axes are unreachable (FR6a) | which properties a theme declares |
|
|
194
|
+
|
|
195
|
+
### Performance and resources
|
|
196
|
+
|
|
197
|
+
- **PR1 — No state, no effects, no observers.** The component derives every
|
|
198
|
+
rendered difference from its props during render and registers no listener,
|
|
199
|
+
timer, observer, or animation frame.
|
|
200
|
+
|
|
201
|
+
Current measurements belong in the audit record; this subsection owns only
|
|
202
|
+
durable constraints and their verification target.
|
|
203
|
+
|
|
204
|
+
## Accessibility contract
|
|
205
|
+
|
|
206
|
+
- **AR1 — Named.** The control MUST expose a non-empty accessible name in every
|
|
207
|
+
reachable state (WCAG 2.2 SC 4.1.2) (FR1). Omitted and non-empty `label`
|
|
208
|
+
satisfy this; `label=''` does not, and that gap is recorded as FR1a rather
|
|
209
|
+
than resolved here.
|
|
210
|
+
- **AR2 — Focus follows paint.** A control that paints nothing MUST NOT be
|
|
211
|
+
focusable, because focus landing on it would have no visible indicator
|
|
212
|
+
(WCAG 2.2 SC 2.4.7). `opacity` and `pointer-events` do not achieve this;
|
|
213
|
+
`visibility` does (FR2).
|
|
214
|
+
- **AR3a — Focus is visible.** A focused control MUST paint a focus indicator
|
|
215
|
+
(WCAG 2.2 SC 2.4.7). The ring is declared but clipped away; recorded as FR3a
|
|
216
|
+
rather than resolved here.
|
|
217
|
+
- **AR3 — Target size.** The collapsed control MUST fit a 24x24 CSS-px square
|
|
218
|
+
(WCAG 2.2 SC 2.5.8 AA) (FR8).
|
|
219
|
+
- **AR4 — Reduced motion.** The state transition MUST collapse to `0s` under
|
|
220
|
+
`prefers-reduced-motion: reduce` (FR7).
|
|
221
|
+
- **AR5 — Translated strings.** The default accessible name MUST resolve through
|
|
222
|
+
the translator catalog, never a literal.
|
|
223
|
+
|
|
224
|
+
## Design relationships
|
|
225
|
+
|
|
226
|
+
| Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
|
|
227
|
+
| ---------------- | ------------------------------------------- | ------------------------ | -------------- | ------------------ |
|
|
228
|
+
| pill surface | floating affordance over the transcript | unsettled | supporting | FR5, FR6 |
|
|
229
|
+
| hidden state | absent rather than dimmed | unsettled | supporting | FR2, AR2 |
|
|
230
|
+
| labelled state | text accompanies the glyph on the same pill | unsettled | supporting | FR4 |
|
|
231
|
+
|
|
232
|
+
The component implements design requirements without copying their rationale.
|
|
233
|
+
An `unsettled` representation remains a human decision; principles do not let an
|
|
234
|
+
agent invent the answer. No `authority: current` design record covers a floating
|
|
235
|
+
scroll affordance today, so these rows record the gap rather than a requirement.
|
|
236
|
+
|
|
237
|
+
## Family and system relationships
|
|
238
|
+
|
|
239
|
+
- `family:buttons` owns the action surface this component composes through
|
|
240
|
+
`component:Button`. This component is not a member: its public purpose is a
|
|
241
|
+
transcript affordance that contains a button, and the family's membership rule
|
|
242
|
+
excludes components that merely use a Button as an action slot. See OQ4.
|
|
243
|
+
- `architecture:component-theming-surface` owns the target/anatomy relationship
|
|
244
|
+
this component's theming must satisfy; FR6 adopts INV4 directly.
|
|
245
|
+
- `spec:AST-029` owns the audit flow that produced this observational record.
|
|
246
|
+
|
|
247
|
+
## Verification map
|
|
248
|
+
|
|
249
|
+
| Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
|
|
250
|
+
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ----------------------------------------- |
|
|
251
|
+
| FR1, FR4 | `ChatLayoutScrollButton.test.tsx` role/name and visible-text cases | label omitted; non-empty label | dropping `isIconOnly` renders the translated name as clipped visible text, and the name case still passes | `audit:ChatLayoutScrollButton/a11y` |
|
|
252
|
+
| FR1a | **no oracle in any lane today.** Derived from source across three files (`??` passing `''` through, Button's `label !== ''` guard, the Icon's decorative default). A checked-in fixture would add an unnamed control to the shared story set and a new axe baseline entry, so the audit did not add one. | label empty | a fallback added here would make the derivation stale without any test failing | `audit:ChatLayoutScrollButton/a11y` |
|
|
253
|
+
| FR2, FR3 | `ChatLayoutScrollButton.test.tsx` tab cases; `ChatLayoutScrollButton.a11y.chromium.spec.ts` | hidden at rest; scrolled up; re-hidden | replacing `visibility` with `opacity` alone leaves the invisible control in the tab order | `audit:ChatLayoutScrollButton/a11y` |
|
|
254
|
+
| FR3a | `ChatLayoutScrollButtonSurface.a11y.chromium.spec.ts` interaction pass: the focused frame's bytes are compared with a rest frame captured from the same page, and the ring's outward reach is measured against the clipping ancestor's room (recorded as `ringChangedPixels`, `outreach`, `roomPx`) | collapsed and labelled, light and dark | the result is recorded and annotated, never asserted, so repairing the clip cannot turn this check red | `audit:ChatLayoutScrollButton/a11y` |
|
|
255
|
+
| FR5 | `ChatLayoutScrollButton.a11y.chromium.spec.ts` two-theme geometry pair and its pre-fix arm | neutral and butter | a literal height lets a larger element scale clip the Button the pill wraps | `audit:ChatLayoutScrollButton/theming` |
|
|
256
|
+
| FR6 | `ChatLayoutScrollButtonSurface.a11y.chromium.spec.ts` placement and probe-theme reach tests | visible, collapsed, neutral and probe | moving the target back to the centring row leaves the pill unchanged under the probe theme | `audit:ChatLayoutScrollButton/theming` |
|
|
257
|
+
| FR6a | source: `themeProps()` is called with no state argument, and `Chat.doc.mjs` declares the target with no `visualProps`/`states` | visible/hidden; collapsed/expanded | adding either axis is new public theming surface, so no test may assert its shape before the owner decides | `audit:ChatLayoutScrollButton/theming` |
|
|
258
|
+
| hover, pressed | `ChatLayoutScrollButtonSurface.a11y.chromium.spec.ts` interaction pass — each frame asserts the pseudo-class matched and that the captured bytes differ from a rest frame of the same page | collapsed and labelled, light and dark | a frame captured after release, or with the pointer elsewhere, fails its own engagement assertion | `audit:ChatLayoutScrollButton/design` |
|
|
259
|
+
| FR7 | source declaration plus `holdMotionStill` capture conditions | any transition | removing the reduced-motion branch restores animation for readers who asked for none | `audit:ChatLayoutScrollButton/a11y` |
|
|
260
|
+
| FR8 | `ChatLayoutScrollButtonSurface.a11y.chromium.spec.ts` measured target box | visible, collapsed | a smaller resolved size drops the control below the AA minimum | `audit:ChatLayoutScrollButton/a11y` |
|
|
261
|
+
| FR9 | `ChatLayoutScrollButton.test.tsx` passthrough case | any | dropping `...rest` silently discards `data-*`, `id`, and ARIA the caller set | `audit:ChatLayoutScrollButton/public-api` |
|
|
262
|
+
|
|
263
|
+
## Decision log
|
|
264
|
+
|
|
265
|
+
### DEC-1 — The public theming target rides the pill, not the row that centres it
|
|
266
|
+
|
|
267
|
+
**Reference:** `component:ChatLayoutScrollButton/DEC-1`
|
|
268
|
+
**Decider:** `cixzhang`, `2026-09-23`
|
|
269
|
+
|
|
270
|
+
`architecture:component-theming-surface/INV4` requires a target to sit on a
|
|
271
|
+
stable visible element that paints theme-controlled output. The component
|
|
272
|
+
renders two elements: a full-width row that centres the pill and holds the gap
|
|
273
|
+
below it, and the pill itself, which paints the fill, elevation, and radius. The
|
|
274
|
+
target sat on the row, so a theme that styled the documented name painted a band
|
|
275
|
+
across the chat dock while the pill kept the surface the theme asked to replace.
|
|
276
|
+
|
|
277
|
+
The name, the documentation entry, and the target count are unchanged, and no
|
|
278
|
+
`guaranteedProperties` declaration existed to promise the old element, so this
|
|
279
|
+
repairs a reachability gap rather than removing a compatibility path.
|
|
280
|
+
|
|
281
|
+
Rejected: adding a second target for the pill. That is new public theming
|
|
282
|
+
surface for a component that needs exactly one, and it would leave the
|
|
283
|
+
non-painting target in place.
|
|
284
|
+
|
|
285
|
+
Rejected: moving consumer passthrough to the pill alongside the target.
|
|
286
|
+
`ref`, `xstyle`, `className`, `style`, and the remaining DOM props keep
|
|
287
|
+
landing on the outer element, which is the element the released type, the
|
|
288
|
+
existing passthrough test, and `architecture:public-component-api/INV5, INV8`
|
|
289
|
+
name as the contract's owner. Relocating them would change where a caller's
|
|
290
|
+
`id`, `data-*`, and ref resolve, which is a compatibility decision and not part
|
|
291
|
+
of this repair.
|
|
292
|
+
|
|
293
|
+
## Open questions
|
|
294
|
+
|
|
295
|
+
- **OQ1 — Should the target reflect its style-driving states?** (`human-api`)
|
|
296
|
+
The pill selects between visible/hidden and collapsed/expanded style objects,
|
|
297
|
+
and `themeProps` reflects neither, so a theme cannot address either state.
|
|
298
|
+
Exposing them means adding `visualProps`/`states` to a public target, which is
|
|
299
|
+
new theming surface rather than a repair.
|
|
300
|
+
- **OQ2 — Is `isVisible` the right name on a non-layer component?** (`human-api`)
|
|
301
|
+
The shared convention reserves `isOpen`/`isVisible` for layer components. The
|
|
302
|
+
prop is released in `@astryxdesign/core@0.6.3`, so any change is breaking and
|
|
303
|
+
needs a compatibility decision.
|
|
304
|
+
- **OQ3 — What should happen to a label past the expanded ceiling?** (`human-design`)
|
|
305
|
+
The pill clips at its width ceiling with no ellipsis and no wrap. The
|
|
306
|
+
accessible name survives, so only sighted readers lose text, and locale
|
|
307
|
+
expansion is the realistic trigger. No `authority: current` design record
|
|
308
|
+
covers truncation for this surface.
|
|
309
|
+
- **OQ4 — Does this component belong to `family:buttons`?** (`human-api`)
|
|
310
|
+
Its public purpose is a transcript affordance, and it is absent from the
|
|
311
|
+
family's member list, but it is a single composed Button with no other
|
|
312
|
+
content. The family contract's exclusion for "components that merely use a
|
|
313
|
+
Button as a trigger or action slot" is the reading applied above.
|
|
314
|
+
- **OQ5 — Is animating the pill's `max-width` acceptable?** (`human-design`)
|
|
315
|
+
Expanding and collapsing animates a layout property. Reduced motion is
|
|
316
|
+
honored and the subtree is one button, but the record that would govern
|
|
317
|
+
animated properties, `design:motion`, is `authority: draft`.
|
|
318
|
+
- **OQ6 — The consumer doc has no anatomy inventory.** (`human-api`)
|
|
319
|
+
`architecture:component-theming-surface` records this as open migration work
|
|
320
|
+
across Core, so no `### Theming anatomy` block is written here: there are no
|
|
321
|
+
published anatomy names for it to map.
|
|
322
|
+
|
|
323
|
+
- **OQ8 — How should the focus ring escape the pill's clip?** (`human-design`)
|
|
324
|
+
The pill needs `overflow: hidden` for its collapse/expand animation, and the
|
|
325
|
+
Button's ring is drawn outside its border box, so the two are in direct
|
|
326
|
+
conflict. Candidate answers — inset the button so the ring fits, draw the
|
|
327
|
+
ring on the pill, or clip on a different element — each change rendered
|
|
328
|
+
geometry and belong to a visual review.
|
|
329
|
+
- **OQ7 — What should `label=''` do?** (`human-api`)
|
|
330
|
+
It currently produces an unnamed control (FR1a). The candidate answers — fall
|
|
331
|
+
back to the translated default, reject the value in the type, or treat it as
|
|
332
|
+
a caller error — are a public API and compatibility decision on a released
|
|
333
|
+
prop, so the audit recorded the violation instead of choosing one.
|
|
334
|
+
|
|
335
|
+
## Content boundary
|
|
336
|
+
|
|
337
|
+
This file does not duplicate consumer prop tables/examples, current audit
|
|
338
|
+
results, implementation steps, or family/system rules. It links to their owners.
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import {describe, it, expect} from 'vitest';
|
|
4
4
|
import {render, screen} from '@testing-library/react';
|
|
5
|
+
import userEvent from '@testing-library/user-event';
|
|
5
6
|
import {ChatLayoutScrollButton} from './ChatLayoutScrollButton';
|
|
6
7
|
|
|
7
8
|
describe('ChatLayoutScrollButton', () => {
|
|
@@ -52,4 +53,34 @@ describe('ChatLayoutScrollButton', () => {
|
|
|
52
53
|
expect(root).toHaveAttribute('data-custom', 'x');
|
|
53
54
|
expect(root).toHaveAttribute('id', 'scroll-1');
|
|
54
55
|
});
|
|
56
|
+
|
|
57
|
+
// The hidden state paints nothing, so focus landing on it would have no
|
|
58
|
+
// visible indicator (WCAG 2.2 SC 2.4.7). `opacity: 0` and
|
|
59
|
+
// `pointer-events: none` suppress paint and the pointer but leave the button
|
|
60
|
+
// in sequential focus navigation, so the hidden state must also stop being
|
|
61
|
+
// focusable — without costing the visible state its keyboard access.
|
|
62
|
+
it('is keyboard reachable while visible', async () => {
|
|
63
|
+
const user = userEvent.setup();
|
|
64
|
+
render(<ChatLayoutScrollButton isVisible onClick={() => {}} />);
|
|
65
|
+
|
|
66
|
+
await user.tab();
|
|
67
|
+
|
|
68
|
+
expect(
|
|
69
|
+
screen.getByRole('button', {name: 'Scroll to bottom'}),
|
|
70
|
+
).toHaveFocus();
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('is not keyboard reachable while hidden', async () => {
|
|
74
|
+
const user = userEvent.setup();
|
|
75
|
+
render(
|
|
76
|
+
<>
|
|
77
|
+
<ChatLayoutScrollButton isVisible={false} onClick={() => {}} />
|
|
78
|
+
<button type="button">After</button>
|
|
79
|
+
</>,
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
await user.tab();
|
|
83
|
+
|
|
84
|
+
expect(screen.getByRole('button', {name: 'After'})).toHaveFocus();
|
|
85
|
+
});
|
|
55
86
|
});
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
spacingVars,
|
|
24
24
|
radiusVars,
|
|
25
25
|
shadowVars,
|
|
26
|
+
sizeVars,
|
|
26
27
|
durationVars,
|
|
27
28
|
easeVars,
|
|
28
29
|
} from '../theme/tokens.stylex';
|
|
@@ -67,8 +68,14 @@ const styles = stylex.create({
|
|
|
67
68
|
borderRadius: radiusVars['--radius-full'],
|
|
68
69
|
backgroundColor: colorVars['--color-background-popover'],
|
|
69
70
|
boxShadow: shadowVars['--shadow-med'],
|
|
70
|
-
height
|
|
71
|
-
|
|
71
|
+
// The pill clips its own content, so it must track the height of the
|
|
72
|
+
// md Button it wraps. A literal would clip that Button under any theme
|
|
73
|
+
// that retunes the element scale.
|
|
74
|
+
height: sizeVars['--size-element-md'],
|
|
75
|
+
// `visibility` rides the same transition so the fade-out still plays:
|
|
76
|
+
// it flips to `visible` immediately on the way in and only at the end
|
|
77
|
+
// of the duration on the way out.
|
|
78
|
+
transitionProperty: 'opacity, transform, max-width, visibility',
|
|
72
79
|
transitionTimingFunction: easeVars['--ease-standard'],
|
|
73
80
|
transitionDuration: {
|
|
74
81
|
default: durationVars['--duration-fast-max'],
|
|
@@ -78,14 +85,19 @@ const styles = stylex.create({
|
|
|
78
85
|
hidden: {
|
|
79
86
|
opacity: 0,
|
|
80
87
|
pointerEvents: 'none',
|
|
81
|
-
|
|
88
|
+
// The hidden pill paints nothing, so focus landing on it would have no
|
|
89
|
+
// visible indicator (WCAG 2.2 SC 2.4.7). `opacity` and `pointer-events`
|
|
90
|
+
// leave the button in sequential focus navigation; `visibility` removes it.
|
|
91
|
+
visibility: 'hidden',
|
|
92
|
+
maxWidth: sizeVars['--size-element-md'],
|
|
82
93
|
},
|
|
83
94
|
visible: {
|
|
84
95
|
opacity: 1,
|
|
85
96
|
pointerEvents: 'auto',
|
|
97
|
+
visibility: 'visible',
|
|
86
98
|
},
|
|
87
99
|
collapsed: {
|
|
88
|
-
maxWidth: '
|
|
100
|
+
maxWidth: sizeVars['--size-element-md'],
|
|
89
101
|
},
|
|
90
102
|
expanded: {
|
|
91
103
|
maxWidth: '200px',
|
|
@@ -127,20 +139,25 @@ export function ChatLayoutScrollButton({
|
|
|
127
139
|
}: ChatLayoutScrollButtonProps) {
|
|
128
140
|
const t = useTranslator();
|
|
129
141
|
return (
|
|
142
|
+
// Two elements, two responsibilities. The outer one centres the pill and
|
|
143
|
+
// holds the gap above the composer — spacing outside the pill's border
|
|
144
|
+
// box, which the pill cannot own itself. The inner one is the pill: it is
|
|
145
|
+
// what a reader sees, so it carries the painted surface AND the public
|
|
146
|
+
// theming target. Keeping the target on the outer element would satisfy
|
|
147
|
+
// every automated check while leaving a theme styling an invisible
|
|
148
|
+
// full-width row (architecture:component-theming-surface INV4).
|
|
130
149
|
<div
|
|
131
150
|
ref={ref}
|
|
132
|
-
{...mergeProps(
|
|
133
|
-
themeProps('chat-layout-scroll-button'),
|
|
134
|
-
stylex.props(styles.wrapper, xstyle),
|
|
135
|
-
className,
|
|
136
|
-
style,
|
|
137
|
-
)}
|
|
151
|
+
{...mergeProps(stylex.props(styles.wrapper, xstyle), className, style)}
|
|
138
152
|
{...rest}>
|
|
139
153
|
<div
|
|
140
|
-
{...
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
154
|
+
{...mergeProps(
|
|
155
|
+
themeProps('chat-layout-scroll-button'),
|
|
156
|
+
stylex.props(
|
|
157
|
+
styles.container,
|
|
158
|
+
isVisible ? styles.visible : styles.hidden,
|
|
159
|
+
label ? styles.expanded : styles.collapsed,
|
|
160
|
+
),
|
|
144
161
|
)}>
|
|
145
162
|
<Button
|
|
146
163
|
label={label ?? t('@astryx.chatLayoutScrollButton.scrollToBottom')}
|
|
@@ -7,7 +7,8 @@ export const docs = {
|
|
|
7
7
|
subComponentOf: 'Chat',
|
|
8
8
|
displayName: 'Chat Message Bubble',
|
|
9
9
|
isHiddenFromOverview: true,
|
|
10
|
-
description:
|
|
10
|
+
description:
|
|
11
|
+
'Styled content container for the chat "bubble." Reads sender from parent ChatMessage context to auto-style the background. Use filled for standard messages and ghost when content needs alignment without a visible boundary. Supports name/metadata slots aligned with bubble padding, and multi-bubble grouping via the group prop for consecutive messages from the same sender.',
|
|
11
12
|
props: [
|
|
12
13
|
{
|
|
13
14
|
name: 'children',
|
|
@@ -18,18 +19,21 @@ export const docs = {
|
|
|
18
19
|
{
|
|
19
20
|
name: 'variant',
|
|
20
21
|
type: "'filled' | 'ghost'",
|
|
21
|
-
description:
|
|
22
|
+
description:
|
|
23
|
+
"Visual variant. 'filled' renders sender-colored background (default). 'ghost' renders transparent background but keeps padding for alignment.",
|
|
22
24
|
default: "'filled'",
|
|
23
25
|
},
|
|
24
26
|
{
|
|
25
27
|
name: 'name',
|
|
26
28
|
type: 'ReactNode',
|
|
27
|
-
description:
|
|
29
|
+
description:
|
|
30
|
+
"Sender name rendered above the bubble, aligned with bubble text padding. Use on the first bubble in a message. Non-rendering scalar values (null, undefined, booleans, and the empty string) omit the aligned wrapper; numeric 0 remains aligned. If the first content is raw (no bubble), use ChatMessage's `name` prop instead.",
|
|
28
31
|
},
|
|
29
32
|
{
|
|
30
33
|
name: 'metadata',
|
|
31
34
|
type: 'ReactNode',
|
|
32
|
-
description:
|
|
35
|
+
description:
|
|
36
|
+
"Metadata content rendered below the bubble, aligned with bubble text padding. Use on the last bubble in a message. Non-rendering scalar values (null, undefined, booleans, and the empty string) omit the aligned wrapper; numeric 0 remains aligned. If the last content is raw (no bubble), use ChatMessage's `metadata` prop instead.",
|
|
33
37
|
slotElements: [
|
|
34
38
|
{
|
|
35
39
|
__element: 'Text',
|
|
@@ -43,12 +47,14 @@ export const docs = {
|
|
|
43
47
|
{
|
|
44
48
|
name: 'group',
|
|
45
49
|
type: "'first' | 'middle' | 'last'",
|
|
46
|
-
description:
|
|
50
|
+
description:
|
|
51
|
+
'Position within a multi-bubble group. Controls corner radius reduction on the sender side. Leave unset for standalone bubbles (full radius).',
|
|
47
52
|
},
|
|
48
53
|
{
|
|
49
54
|
name: 'width',
|
|
50
55
|
type: 'SizeValue',
|
|
51
|
-
description:
|
|
56
|
+
description:
|
|
57
|
+
'Width of the bubble (number = pixels, string = used as-is). When set, replaces the default max(80%, 280px) width cap. Combine with variant="ghost" to let custom content (an artifact card, attachments) span the full message column.',
|
|
52
58
|
},
|
|
53
59
|
],
|
|
54
60
|
};
|
|
@@ -57,14 +63,18 @@ export const docsZh = {
|
|
|
57
63
|
name: 'ChatMessageBubble',
|
|
58
64
|
isHiddenFromOverview: true,
|
|
59
65
|
displayName: 'Chat Message Bubble',
|
|
60
|
-
description:
|
|
66
|
+
description:
|
|
67
|
+
'样式化的气泡容器,从父上下文读取发送者信息进行自动样式化。支持 name/metadata 插槽、多气泡分组和透明变体。',
|
|
61
68
|
propDescriptions: {
|
|
62
69
|
children: '气泡内容:文本、Markdown 或任何 ReactNode。',
|
|
63
|
-
variant:
|
|
64
|
-
|
|
65
|
-
|
|
70
|
+
variant:
|
|
71
|
+
"视觉变体。'filled' 渲染发送者颜色背景,'ghost' 渲染透明背景但保持填充对齐。",
|
|
72
|
+
name: '气泡上方渲染的发送者名称,与气泡文本内边距对齐。null、undefined、布尔值和空字符串会省略对齐容器;数字 0 仍保持对齐。用于消息中的第一个气泡。',
|
|
73
|
+
metadata:
|
|
74
|
+
'气泡下方渲染的元数据内容,与气泡文本内边距对齐。null、undefined、布尔值和空字符串会省略对齐容器;数字 0 仍保持对齐。用于消息中的最后一个气泡。',
|
|
66
75
|
group: '多气泡组中的位置。控制发送者侧的圆角缩减。',
|
|
67
|
-
width:
|
|
76
|
+
width:
|
|
77
|
+
'气泡宽度(数字 = 像素,字符串 = 按原样使用)。设置后替代默认的 max(80%, 280px) 宽度上限;与 ghost 变体组合可让自定义内容占满消息列宽度。',
|
|
68
78
|
},
|
|
69
79
|
};
|
|
70
80
|
|
|
@@ -72,14 +82,17 @@ export const docsDense = {
|
|
|
72
82
|
name: 'ChatMessageBubble',
|
|
73
83
|
isHiddenFromOverview: true,
|
|
74
84
|
displayName: 'Chat Message Bubble',
|
|
75
|
-
description:
|
|
85
|
+
description:
|
|
86
|
+
'styled bubble container; reads sender from context; supports name/metadata slots, group corners, ghost variant',
|
|
76
87
|
propDescriptions: {
|
|
77
88
|
children: 'bubble content: text, Markdown, any ReactNode',
|
|
78
89
|
variant: 'filled (sender bg) or ghost (transparent, keeps padding)',
|
|
79
|
-
name: 'sender name above bubble
|
|
90
|
+
name: 'sender name above bubble; omits non-rendering scalars; keeps numeric 0 aligned',
|
|
80
91
|
displayName: 'sender name above bubble, aligned w/ bubble padding',
|
|
81
|
-
metadata:
|
|
92
|
+
metadata:
|
|
93
|
+
'metadata below bubble; omits non-rendering scalars; keeps numeric 0 aligned',
|
|
82
94
|
group: 'position in multi-bubble group; controls corner radius reduction',
|
|
83
|
-
width:
|
|
95
|
+
width:
|
|
96
|
+
'bubble width (number=px, string=as-is); replaces default max(80%,280px) cap; ghost+width="100%" spans full message column',
|
|
84
97
|
},
|
|
85
98
|
};
|