@astryxdesign/core 0.6.2 → 0.6.3-canary.039a67e
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/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +33 -12
- 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/ChatSystemMessage.d.ts +3 -3
- package/dist/Chat/ChatSystemMessage.d.ts.map +1 -1
- package/dist/Chat/ChatSystemMessage.js +2 -2
- package/dist/Chat/ChatTokenizedText.d.ts +6 -6
- package/dist/Chat/ChatTokenizedText.js +10 -6
- package/dist/Chat/ChatToolCalls.d.ts +7 -9
- package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
- package/dist/Chat/ChatToolCalls.js +43 -26
- 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 +25 -5
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +29 -17
- 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/DateInput/index.d.ts +1 -1
- package/dist/DateInput/index.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +4 -4
- package/dist/DateTimeInput/DateTimeInput.d.ts +32 -15
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +55 -30
- package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
- package/dist/DateTimeInput/TouchDateTimeField.js +4 -4
- package/dist/DateTimeInput/index.d.ts +1 -1
- package/dist/DateTimeInput/index.d.ts.map +1 -1
- 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 +30 -14
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +61 -13
- package/dist/TimeInput/TouchTimeField.d.ts +11 -0
- package/dist/TimeInput/TouchTimeField.d.ts.map +1 -0
- package/dist/TimeInput/TouchTimeField.js +417 -0
- package/dist/TimeInput/index.d.ts +1 -1
- package/dist/TimeInput/index.d.ts.map +1 -1
- 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/defineTheme.d.ts +3 -0
- package/dist/theme/defineTheme.d.ts.map +1 -1
- package/dist/theme/defineTheme.js +4 -1
- package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
- package/dist/theme/derivedVarRegistry.js +4 -0
- package/dist/theme/generateThemeRules.d.ts +15 -7
- package/dist/theme/generateThemeRules.d.ts.map +1 -1
- package/dist/theme/generateThemeRules.js +143 -35
- package/dist/theme/themeAdaptations.d.ts +5 -3
- package/dist/theme/themeAdaptations.d.ts.map +1 -1
- package/dist/theme/themeAdaptations.js +33 -5
- package/dist/utils/inputPresentation.d.ts +55 -0
- package/dist/utils/inputPresentation.d.ts.map +1 -0
- package/dist/utils/inputPresentation.js +108 -0
- 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/Avatar/Avatar.doc.mjs +1 -1
- package/src/Avatar/Avatar.test.tsx +30 -0
- package/src/Avatar/Avatar.tsx +38 -14
- 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/ChatSystemMessage.doc.mjs +115 -12
- package/src/Chat/ChatSystemMessage.spec.md +225 -0
- package/src/Chat/ChatSystemMessage.test.tsx +112 -20
- package/src/Chat/ChatSystemMessage.tsx +4 -6
- package/src/Chat/ChatTokenizedText.doc.mjs +96 -9
- package/src/Chat/ChatTokenizedText.spec.md +190 -0
- package/src/Chat/ChatTokenizedText.test.tsx +60 -1
- package/src/Chat/ChatTokenizedText.tsx +14 -8
- package/src/Chat/ChatToolCalls.doc.mjs +4 -1
- package/src/Chat/ChatToolCalls.spec.md +194 -0
- package/src/Chat/ChatToolCalls.test.tsx +83 -0
- package/src/Chat/ChatToolCalls.tsx +46 -21
- 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/__tests__/ChatSystemMessage.a11y.chromium.spec.ts +1004 -0
- package/src/Chat/__tests__/ChatTokenizedText.a11y.chromium.spec.ts +573 -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.doc.mjs +38 -9
- package/src/DateInput/DateInput.tsx +59 -17
- package/src/DateInput/NativeDateField.tsx +24 -8
- package/src/DateInput/Presentation.test.tsx +121 -0
- package/src/DateInput/TouchDateField.tsx +6 -2
- package/src/DateInput/index.ts +1 -0
- package/src/DateRangeInput/DateRangeInput.tsx +6 -1
- package/src/DateTimeInput/DateTimeInput.doc.mjs +28 -12
- package/src/DateTimeInput/DateTimeInput.tsx +93 -37
- package/src/DateTimeInput/Presentation.test.tsx +89 -0
- package/src/DateTimeInput/TouchDateTimeField.tsx +6 -1
- package/src/DateTimeInput/index.ts +1 -0
- 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/NativeTimeInput.test.tsx +36 -3
- package/src/TimeInput/Presentation.test.tsx +148 -0
- package/src/TimeInput/TimeInput.doc.mjs +21 -5
- package/src/TimeInput/TimeInput.tsx +102 -11
- package/src/TimeInput/TouchTimeField.tsx +572 -0
- package/src/TimeInput/index.ts +1 -0
- 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/defineTheme.ts +4 -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 +231 -50
- package/src/theme/themeAdaptations.test.ts +211 -1
- package/src/theme/themeAdaptations.ts +50 -4
- package/src/theme/tokenValueCompat.test.ts +4 -1
- package/src/utils/inputPresentation.ts +143 -0
- 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,190 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 3
|
|
3
|
+
template_version: 6
|
|
4
|
+
kind: component
|
|
5
|
+
id: component:ChatTokenizedText
|
|
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, layout, theming, accessibility, testing]
|
|
13
|
+
verified_by:
|
|
14
|
+
[
|
|
15
|
+
packages/core/src/Chat/ChatTokenizedText.test.tsx,
|
|
16
|
+
packages/core/src/Chat/__tests__/ChatTokenizedText.a11y.chromium.spec.ts,
|
|
17
|
+
apps/storybook/stories/ChatTokenizedText.stories.tsx,
|
|
18
|
+
apps/storybook/rtl-audit/verified-not-applicable.json,
|
|
19
|
+
packages/core/src/theme/themingTargets.test.ts,
|
|
20
|
+
]
|
|
21
|
+
modules: []
|
|
22
|
+
families: []
|
|
23
|
+
design_specs: []
|
|
24
|
+
architecture:
|
|
25
|
+
[
|
|
26
|
+
architecture:public-component-api,
|
|
27
|
+
architecture:component-theming-surface,
|
|
28
|
+
architecture:component-test-sufficiency,
|
|
29
|
+
architecture:react-component-runtime,
|
|
30
|
+
architecture:theme-tokens,
|
|
31
|
+
architecture:knowledge-contracts,
|
|
32
|
+
]
|
|
33
|
+
contributing: []
|
|
34
|
+
system_specs: [spec:AST-002, spec:AST-020, spec:AST-029]
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
# ChatTokenizedText component contract
|
|
38
|
+
|
|
39
|
+
## Contract at a glance
|
|
40
|
+
|
|
41
|
+
| Area | Contract |
|
|
42
|
+
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
43
|
+
| Public contract | The exported component accepts required plain-text children, optional composer token definitions, and supported root span props and ref. No prop, export, or theme target is added or removed. |
|
|
44
|
+
| Behavior | Unmatched text is preserved. Non-empty token values match literally from left to right. Structured tokens delegate to Badge and custom tokens to callers. |
|
|
45
|
+
| End-user impact | Tokenized messages finish rendering when a caller-supplied token definition has an empty serialized value. |
|
|
46
|
+
| Builder impact | Existing token arrays keep working, and empty serialized values are safely ignored instead of creating a non-advancing match. |
|
|
47
|
+
| Compatibility/readiness | Patch-compatible correctness repair and observational documentation. The pending inline-alignment change remains owned by its separate pull request. |
|
|
48
|
+
| Review checks | Reject zero-width matching, lost unmatched text, execution of custom renderers without a match, dropped root inputs, or claims about caller-owned content. |
|
|
49
|
+
| Governing rules | `architecture:public-component-api/INV1, INV5–INV6, INV8–INV9`; `architecture:component-test-sufficiency/INV1–INV7`; `spec:AST-029/FR3–FR7`; ECMAScript RegExp progress semantics. |
|
|
50
|
+
|
|
51
|
+
This table is a review projection. The draft body records verified current or
|
|
52
|
+
remediated behavior and creates no new token grammar or visual policy.
|
|
53
|
+
|
|
54
|
+
## Intent
|
|
55
|
+
|
|
56
|
+
ChatTokenizedText projects serialized token values embedded in a plain chat message
|
|
57
|
+
into inline structured Badge content or caller-rendered content while preserving the
|
|
58
|
+
surrounding text.
|
|
59
|
+
|
|
60
|
+
## Compatibility and migration
|
|
61
|
+
|
|
62
|
+
- Released default preserved: yes; messages without matching non-empty tokens remain plain text.
|
|
63
|
+
- Compatibility class: patch-compatible correctness repair for invalid zero-width matches.
|
|
64
|
+
- Controlled/uncontrolled behavior: not applicable; the component owns no state.
|
|
65
|
+
- Migration decision: none. No public type, prop, export, default, or theme target changes.
|
|
66
|
+
|
|
67
|
+
Consumer migration instructions belong in consumer docs and release notes.
|
|
68
|
+
|
|
69
|
+
## Ownership boundary
|
|
70
|
+
|
|
71
|
+
**Owns**
|
|
72
|
+
|
|
73
|
+
- Literal matching of serialized token values against the supplied message text.
|
|
74
|
+
- Preserving unmatched text and source order.
|
|
75
|
+
- Choosing the existing structured Badge or custom-render branch for each match.
|
|
76
|
+
- The root span, its `chat-tokenized-text` target, accepted BaseProps composition, and ref.
|
|
77
|
+
|
|
78
|
+
**Does not own / non-goals**
|
|
79
|
+
|
|
80
|
+
- Token value grammar, identity, validation, or product semantics.
|
|
81
|
+
- Badge color, iconography, sizing, or accessibility semantics.
|
|
82
|
+
- Semantics and interaction inside caller-provided custom token content.
|
|
83
|
+
- Composer insertion, serialization, deletion, selection, or token-element alignment.
|
|
84
|
+
- The inline-alignment change proposed independently in pull request #6418.
|
|
85
|
+
|
|
86
|
+
## Public concepts
|
|
87
|
+
|
|
88
|
+
| Concept | Closed values or states | Meaning | Availability by variant/orientation/state | Default | Owner | Stability | Invalid-value behavior |
|
|
89
|
+
| ------------ | ----------------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------- | -------- | ----------------------------------- | ------------------------- | ------------------------------------ |
|
|
90
|
+
| Message text | any string | Plain text whose literal token values may be projected inline. | Every render | required | `component:ChatTokenizedText` | released observed surface | Empty text renders an empty span. |
|
|
91
|
+
| Token set | omitted; empty; non-empty | Candidate serialized values and their structured or custom presentations. | Every render | omitted | caller and component | released observed surface | Empty token values are ignored. |
|
|
92
|
+
| Token form | structured Badge config; custom render function | Selects delegated Badge content or caller-rendered content. | Matching non-empty values | none | caller and delegated component | released observed surface | Type-invalid forms are rejected. |
|
|
93
|
+
| Root surface | ref; supported DOM/data/ARIA/class/style/xstyle | Extends the inline root without replacing its owned target. | Every render | omitted | `architecture:public-component-api` | released observed surface | Unsupported inputs stay unsupported. |
|
|
94
|
+
|
|
95
|
+
## Behavioral and layout contract
|
|
96
|
+
|
|
97
|
+
| ID | Candidate invariant | Basis | Draft review state |
|
|
98
|
+
| --- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | ----------------------- |
|
|
99
|
+
| FR1 | The component MUST preserve unmatched text exactly and replace each matched non-empty serialized value at its original reading-order position. | Released consumer docs and implementation | verified |
|
|
100
|
+
| FR2 | Empty token values MUST be ignored so the renderer always makes progress and never enters a zero-width global-match loop. | Objective ECMAScript RegExp progress semantics and responsive rendering | remediated and verified |
|
|
101
|
+
| FR3 | Structured matches MUST delegate label, variant, and icon rendering to Badge; custom matches MUST invoke the caller renderer only for an actual match. | Released token type, source, docs, and tests | verified |
|
|
102
|
+
| FR4 | Supported ref, DOM/data/ARIA, className, style, and xstyle inputs MUST reach or compose on the root span while the `chat-tokenized-text` target remains intact. | `architecture:public-component-api/INV5–INV6, INV8` | verified |
|
|
103
|
+
| FR5 | The component MUST remain render-only, with no state, Effect, listener, observer, timer, or owned asynchronous resource. | Current source and `architecture:component-test-sufficiency` evidence boundary | verified |
|
|
104
|
+
|
|
105
|
+
### Allowed variation
|
|
106
|
+
|
|
107
|
+
- **AV1 — Caller tokens.** Labels, variants, icons, custom content, and serialized values remain caller supplied.
|
|
108
|
+
- **AV2 — Caller styling.** Supported root styling inputs may extend the component without replacing its public target.
|
|
109
|
+
- **AV3 — Unmatched input.** Text with no matching non-empty value remains unchanged.
|
|
110
|
+
|
|
111
|
+
### Representative states
|
|
112
|
+
|
|
113
|
+
| State | Required invariant | Allowed variation |
|
|
114
|
+
| -------------------- | ----------------------------------------------------------------------- | ------------------------------------- |
|
|
115
|
+
| Plain text | Exact text remains visible. | Any string content. |
|
|
116
|
+
| Structured match | Matching text is replaced by delegated Badge content. | Label, variant, and icon. |
|
|
117
|
+
| Custom match | Matching text is replaced by caller-rendered content. | Any caller-owned React node. |
|
|
118
|
+
| Repeated match | Every occurrence is replaced in reading order. | Number and position of occurrences. |
|
|
119
|
+
| Empty token value | The value is ignored and rendering terminates with text preserved. | Presence beside valid tokens. |
|
|
120
|
+
| Narrow / RTL context | Inline content remains readable and follows surrounding text direction. | Theme, direction, and message length. |
|
|
121
|
+
|
|
122
|
+
### Transformation and precedence order
|
|
123
|
+
|
|
124
|
+
- **ORD1 — Normalize candidates.** Remove empty serialized values while preserving caller order.
|
|
125
|
+
- **ORD2 — Match literally.** Escape values for RegExp syntax and scan the message from left to right.
|
|
126
|
+
- **ORD3 — Render.** Preserve unmatched slices and delegate each matched token to Badge or the caller renderer.
|
|
127
|
+
- **ORD4 — Compose root.** Apply the component target and styles, then combine accepted consumer styling and root props.
|
|
128
|
+
|
|
129
|
+
### Performance and resources
|
|
130
|
+
|
|
131
|
+
- **PR1 — Finite progress.** Every successful match consumes at least one UTF-16 code unit; empty values cannot enter the matcher.
|
|
132
|
+
- **PR2 — Render-only projection.** Matching allocates one candidate list, lookup map, and result list per render and owns no persistent resource.
|
|
133
|
+
|
|
134
|
+
## Accessibility contract
|
|
135
|
+
|
|
136
|
+
- **AR1 — Reading order.** Unmatched text and token content remain in source reading order inside one inline text wrapper.
|
|
137
|
+
- **AR2 — Delegated content.** Structured token semantics remain owned by Badge; custom token semantics remain caller owned.
|
|
138
|
+
- **AR3 — Noninteractive root.** The component introduces no role, focus target, keyboard command, pointer action, or live-region behavior.
|
|
139
|
+
|
|
140
|
+
## Design relationships
|
|
141
|
+
|
|
142
|
+
| Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
|
|
143
|
+
| ---------------- | -------------------------------------------- | -------------------------------- | -------------- | ------------------ |
|
|
144
|
+
| Tokenized text | Inline root preserves surrounding text flow. | Current source and released docs | supporting | FR1, FR5 |
|
|
145
|
+
| Rendered token | Delegates paint to Badge or caller content. | `component:Badge` or caller | supporting | FR4, AR2 |
|
|
146
|
+
|
|
147
|
+
This observational draft does not choose new spacing, alignment, token paint,
|
|
148
|
+
proportion, or state representation.
|
|
149
|
+
|
|
150
|
+
### Theme ownership
|
|
151
|
+
|
|
152
|
+
The Chat family document owns the shared anatomy and target inventory inherited by
|
|
153
|
+
this subcomponent. The existing `chat-tokenized-text` target remains on the inline
|
|
154
|
+
root. Structured token paint delegates to Badge, while custom rendered token content
|
|
155
|
+
remains caller owned. This observational draft does not redefine the family map.
|
|
156
|
+
|
|
157
|
+
## Family and system relationships
|
|
158
|
+
|
|
159
|
+
- `component:Badge` owns structured token paint, variants, iconography, and label semantics.
|
|
160
|
+
- `component:ChatComposerInput` owns token insertion, serialization, deletion, and composer selection behavior.
|
|
161
|
+
- `architecture:public-component-api` owns released exports, BaseProps reachability, styling composition, and refs.
|
|
162
|
+
- `architecture:component-theming-surface` owns the target/anatomy mapping.
|
|
163
|
+
- `architecture:component-test-sufficiency` owns bounded, mutation-sensitive evidence.
|
|
164
|
+
- `spec:AST-029` owns this observational audit backfill and closed evidence receipt.
|
|
165
|
+
|
|
166
|
+
## Verification map
|
|
167
|
+
|
|
168
|
+
| Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
|
|
169
|
+
| -------------- | -------------------------------------------------------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------------- | ------------------------------------- |
|
|
170
|
+
| FR1–FR3, PR1 | `ChatTokenizedText.test.tsx` | plain, structured, custom, repeated, empty | Lost text, zero-width nontermination, or the wrong render branch fails. | `audit:ChatTokenizedText/behavior` |
|
|
171
|
+
| FR4 | focused root passthrough/ref checks, theming target guard | plain and tokenized roots | A supported root input or public target is dropped or replaced. | `audit:ChatTokenizedText/public-api` |
|
|
172
|
+
| FR5 | source inspection and strict lint | every render | Hidden state or an owned external resource triggers runtime review. | `audit:ChatTokenizedText/code-health` |
|
|
173
|
+
| RTL relation | source-hashed verified-N/A record | all existing stories | Component-owned directional behavior invalidates the record. | `audit:ChatTokenizedText/i18n-rtl` |
|
|
174
|
+
| Browser matrix | Storybook stories, exact-head visual gate, and scoped a11y | plain, multiple, mixed, edge, custom, narrow | Missing text/token content, overflow, visual regression, or an a11y violation fails. | `audit:ChatTokenizedText/rendered` |
|
|
175
|
+
| Docs / surface | docs, declarations, exports, `check:knowledge`, docs typecheck | public props, Chat subpath, target, draft record | Missing or stale docs, export, target map, or knowledge shape fails validation or review. | `audit:ChatTokenizedText/docs` |
|
|
176
|
+
|
|
177
|
+
## Decision log
|
|
178
|
+
|
|
179
|
+
No component-local product decision is created by this observational draft. The
|
|
180
|
+
matching repair follows the component's released promise to replace supplied literal
|
|
181
|
+
token values while preserving surrounding text.
|
|
182
|
+
|
|
183
|
+
## Open questions
|
|
184
|
+
|
|
185
|
+
None.
|
|
186
|
+
|
|
187
|
+
## Content boundary
|
|
188
|
+
|
|
189
|
+
This file does not duplicate consumer examples, audit scores, screenshots, Badge
|
|
190
|
+
policy, token grammar, or composer editing behavior.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
|
-
import {describe, it, expect} from 'vitest';
|
|
3
|
+
import {describe, it, expect, vi} from 'vitest';
|
|
4
|
+
import {createRef} from 'react';
|
|
4
5
|
import {render, screen} from '@testing-library/react';
|
|
5
6
|
import {ChatTokenizedText} from './ChatTokenizedText';
|
|
6
7
|
|
|
@@ -79,6 +80,64 @@ describe('ChatTokenizedText', () => {
|
|
|
79
80
|
expect(container.textContent).toContain('@Cindy Zhang');
|
|
80
81
|
});
|
|
81
82
|
|
|
83
|
+
it('ignores empty token values instead of creating zero-width matches', () => {
|
|
84
|
+
render(
|
|
85
|
+
<ChatTokenizedText
|
|
86
|
+
tokens={[
|
|
87
|
+
{value: '', label: 'Empty'},
|
|
88
|
+
{value: '@alice', label: '@Alice'},
|
|
89
|
+
]}>
|
|
90
|
+
Hello @alice
|
|
91
|
+
</ChatTokenizedText>,
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
expect(screen.getByText('@Alice')).toBeInTheDocument();
|
|
95
|
+
expect(screen.queryByText('Empty')).not.toBeInTheDocument();
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('renders plain text when every token value is empty', () => {
|
|
99
|
+
render(
|
|
100
|
+
<ChatTokenizedText
|
|
101
|
+
tokens={[
|
|
102
|
+
{value: '', label: 'First empty'},
|
|
103
|
+
{value: '', label: 'Second empty'},
|
|
104
|
+
]}>
|
|
105
|
+
Hello world
|
|
106
|
+
</ChatTokenizedText>,
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
expect(screen.getByText('Hello world')).toBeInTheDocument();
|
|
110
|
+
expect(screen.queryByText('First empty')).not.toBeInTheDocument();
|
|
111
|
+
expect(screen.queryByText('Second empty')).not.toBeInTheDocument();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('renders custom tokens only for actual matches', () => {
|
|
115
|
+
const renderCustom = vi.fn(() => <span>Custom token</span>);
|
|
116
|
+
|
|
117
|
+
const {rerender} = render(
|
|
118
|
+
<ChatTokenizedText tokens={[{value: '@custom', render: renderCustom}]}>
|
|
119
|
+
Hello @custom
|
|
120
|
+
</ChatTokenizedText>,
|
|
121
|
+
);
|
|
122
|
+
expect(screen.getByText('Custom token')).toBeInTheDocument();
|
|
123
|
+
expect(renderCustom).toHaveBeenCalledTimes(1);
|
|
124
|
+
|
|
125
|
+
rerender(
|
|
126
|
+
<ChatTokenizedText tokens={[{value: '@custom', render: renderCustom}]}>
|
|
127
|
+
Hello world
|
|
128
|
+
</ChatTokenizedText>,
|
|
129
|
+
);
|
|
130
|
+
expect(screen.queryByText('Custom token')).not.toBeInTheDocument();
|
|
131
|
+
expect(renderCustom).toHaveBeenCalledTimes(1);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('forwards refs to the root span', () => {
|
|
135
|
+
const ref = createRef<HTMLSpanElement>();
|
|
136
|
+
render(<ChatTokenizedText ref={ref}>Plain text</ChatTokenizedText>);
|
|
137
|
+
expect(ref.current?.tagName).toBe('SPAN');
|
|
138
|
+
expect(ref.current?.textContent).toBe('Plain text');
|
|
139
|
+
});
|
|
140
|
+
|
|
82
141
|
it('forwards rest props (data-*, id) to the root element', () => {
|
|
83
142
|
render(
|
|
84
143
|
<ChatTokenizedText data-testid="tokenized" data-custom="x" id="tok-1">
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
* @output Exports ChatTokenizedText component
|
|
9
9
|
* @position Utility component for rendering tokenized text in message bubbles
|
|
10
10
|
*
|
|
11
|
-
* Parses a plain text string and replaces token values with inline
|
|
12
|
-
* Accepts the same ChatComposerToken type used by the input
|
|
13
|
-
* so the same token definitions work for both input and display.
|
|
11
|
+
* Parses a plain text string and replaces non-empty token values with inline
|
|
12
|
+
* token content. Accepts the same ChatComposerToken type used by the input
|
|
13
|
+
* triggers, so the same token definitions work for both input and display.
|
|
14
14
|
*
|
|
15
15
|
* SYNC: When modified, update:
|
|
16
16
|
* - /packages/core/src/Chat/index.ts
|
|
@@ -51,8 +51,8 @@ export interface ChatTokenizedTextProps extends BaseProps<HTMLSpanElement> {
|
|
|
51
51
|
children: string;
|
|
52
52
|
/**
|
|
53
53
|
* Token definitions — same type returned by trigger onSelect.
|
|
54
|
-
* Each token
|
|
55
|
-
* with its
|
|
54
|
+
* Each non-empty token `value` is matched literally against the text and
|
|
55
|
+
* replaced with its Badge or custom representation. Empty values are ignored.
|
|
56
56
|
*
|
|
57
57
|
* @example
|
|
58
58
|
* ```
|
|
@@ -88,7 +88,7 @@ function escapeRegExp(str: string): string {
|
|
|
88
88
|
// =============================================================================
|
|
89
89
|
|
|
90
90
|
/**
|
|
91
|
-
* Renders text with token values replaced by inline
|
|
91
|
+
* Renders text with token values replaced by inline token content.
|
|
92
92
|
*
|
|
93
93
|
* Accepts the same `ChatComposerToken` type used by input triggers,
|
|
94
94
|
* so you can share a single token definition between input and display.
|
|
@@ -141,11 +141,17 @@ ChatTokenizedText.displayName = 'ChatTokenizedText';
|
|
|
141
141
|
// =============================================================================
|
|
142
142
|
|
|
143
143
|
function renderTokens(text: string, tokens: ChatComposerToken[]): ReactNode[] {
|
|
144
|
-
const
|
|
144
|
+
const matchableTokens = tokens.filter(token => token.value.length > 0);
|
|
145
|
+
|
|
146
|
+
if (matchableTokens.length === 0) {
|
|
147
|
+
return [text];
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const pattern = matchableTokens.map(t => escapeRegExp(t.value)).join('|');
|
|
145
151
|
const regex = new RegExp(`(${pattern})`, 'g');
|
|
146
152
|
|
|
147
153
|
const tokenMap = new Map<string, ChatComposerToken>();
|
|
148
|
-
for (const t of
|
|
154
|
+
for (const t of matchableTokens) {
|
|
149
155
|
tokenMap.set(t.value, t);
|
|
150
156
|
}
|
|
151
157
|
|
|
@@ -16,6 +16,7 @@ export const docs = {
|
|
|
16
16
|
bestPractices: [
|
|
17
17
|
{guidance: true, description: 'Include a target string on every call so the user can see what the tool acted on: a file path, a shell command, or a search query.'},
|
|
18
18
|
{guidance: true, description: 'Show a duration on completed calls so users can judge which tools are slow and understand why a response took time.'},
|
|
19
|
+
{guidance: true, description: 'Provide a group label when the automatic count does not explain what the calls represent.'},
|
|
19
20
|
{guidance: true, description: 'Provide resultDetail with a code block for calls that produce output (diffs for edits, terminal output for shell commands) so users can inspect results inline.'},
|
|
20
21
|
{guidance: true, description: 'Set a unique key on each call item when streaming so React can animate additions without re-mounting completed rows.'},
|
|
21
22
|
{guidance: false, description: "Don't omit the status field. Without it the call defaults to complete, which is misleading for calls that are still running or have failed."},
|
|
@@ -54,7 +55,7 @@ export const docs = {
|
|
|
54
55
|
name: 'label',
|
|
55
56
|
type: 'string',
|
|
56
57
|
description:
|
|
57
|
-
'Custom summary label for
|
|
58
|
+
'Custom summary label shown for an expanded group. The translated call count is used when omitted.',
|
|
58
59
|
},
|
|
59
60
|
{
|
|
60
61
|
name: 'isExpanded',
|
|
@@ -90,6 +91,7 @@ export const docsZh = {
|
|
|
90
91
|
bestPractices: [
|
|
91
92
|
{guidance: true, description: 'Include a target string on every call so the user can see what the tool acted on: a file path, a shell command, or a search query.'},
|
|
92
93
|
{guidance: true, description: 'Show a duration on completed calls so users can judge which tools are slow and understand why a response took time.'},
|
|
94
|
+
{guidance: true, description: 'Provide a group label when the automatic count does not explain what the calls represent.'},
|
|
93
95
|
{guidance: true, description: 'Provide resultDetail with a code block for calls that produce output (diffs for edits, terminal output for shell commands) so users can inspect results inline.'},
|
|
94
96
|
{guidance: true, description: 'Set a unique key on each call item when streaming so React can animate additions without re-mounting completed rows.'},
|
|
95
97
|
{guidance: false, description: "Don't omit the status field. Without it the call defaults to complete, which is misleading for calls that are still running or have failed."},
|
|
@@ -115,6 +117,7 @@ export const docsDense = {
|
|
|
115
117
|
bestPractices: [
|
|
116
118
|
{guidance: true, description: 'Include target on every call: file path, command, or search query.'},
|
|
117
119
|
{guidance: true, description: 'Show duration on completed calls so users understand timing.'},
|
|
120
|
+
{guidance: true, description: 'Provide group label when count alone is ambiguous.'},
|
|
118
121
|
{guidance: true, description: 'Provide resultDetail with code blocks for calls that produce output.'},
|
|
119
122
|
{guidance: true, description: 'Set unique key on each call item when streaming for stable animations.'},
|
|
120
123
|
{guidance: false, description: "Don't omit status; defaults to complete, misleading for running/failed calls."},
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 3
|
|
3
|
+
template_version: 6
|
|
4
|
+
kind: component
|
|
5
|
+
id: component:ChatToolCalls
|
|
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, layout, theming, accessibility, testing]
|
|
13
|
+
verified_by:
|
|
14
|
+
[
|
|
15
|
+
packages/core/src/Chat/ChatToolCalls.test.tsx,
|
|
16
|
+
apps/storybook/stories/ChatToolCalls.stories.tsx,
|
|
17
|
+
apps/storybook/rtl-audit/verified-not-applicable.json,
|
|
18
|
+
packages/core/src/theme/themingTargets.test.ts,
|
|
19
|
+
]
|
|
20
|
+
modules: []
|
|
21
|
+
families: []
|
|
22
|
+
design_specs: []
|
|
23
|
+
architecture:
|
|
24
|
+
[
|
|
25
|
+
architecture:public-component-api,
|
|
26
|
+
architecture:component-theming-surface,
|
|
27
|
+
architecture:component-test-sufficiency,
|
|
28
|
+
architecture:react-component-runtime,
|
|
29
|
+
architecture:interaction-modality,
|
|
30
|
+
architecture:theme-tokens,
|
|
31
|
+
architecture:knowledge-contracts,
|
|
32
|
+
]
|
|
33
|
+
contributing: []
|
|
34
|
+
system_specs: [spec:AST-009, spec:AST-029]
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
# ChatToolCalls component contract
|
|
38
|
+
|
|
39
|
+
## Contract at a glance
|
|
40
|
+
|
|
41
|
+
| Area | Contract |
|
|
42
|
+
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
43
|
+
| Public contract | The exported component accepts a required call list, optional group label, controlled or uncontrolled expansion, a change callback, and supported root div props and ref. |
|
|
44
|
+
| Behavior | No calls render nothing; one call renders directly; multiple calls expose a disclosure whose collapsed surface shows the latest call and whose expanded surface shows every call. |
|
|
45
|
+
| End-user impact | Group labels appear as supplied, collapsed detail controls leave keyboard and accessibility navigation, and every disclosure has the shared visible focus treatment. |
|
|
46
|
+
| Builder impact | Existing calls keep their shape and defaults. Builders may rely on the released `label` prop and continue to omit it for the translated count. |
|
|
47
|
+
| Compatibility/readiness | Patch-compatible restoration of documented behavior and objective accessibility requirements. No prop, export, default, theme target, call ordering, or caller-content contract changes. |
|
|
48
|
+
| Review checks | Reject ignored labels, focusable descendants inside a collapsed group, lost keyboard activation, unreadable supporting text, dropped root inputs, or changed call ordering/defaults. |
|
|
49
|
+
| Governing rules | `architecture:public-component-api/INV5–INV6, INV8–INV9`; `architecture:interaction-modality`; `spec:AST-009/FR7`; `spec:AST-029/FR3–FR7`; WCAG 2.2 SC 1.4.3 and 2.4.7. |
|
|
50
|
+
|
|
51
|
+
This table is a review projection. The draft body records verified shipped or
|
|
52
|
+
remediated behavior and creates no new tool-call protocol or visual policy.
|
|
53
|
+
|
|
54
|
+
## Intent
|
|
55
|
+
|
|
56
|
+
ChatToolCalls presents tool or function invocations inside an assistant message,
|
|
57
|
+
including execution status, optional metadata, and inspectable result details.
|
|
58
|
+
|
|
59
|
+
## Compatibility and migration
|
|
60
|
+
|
|
61
|
+
- Released default preserved: yes; omitted status means complete and groups start collapsed unless `defaultIsExpanded` is true.
|
|
62
|
+
- Compatibility class: patch-compatible correctness and accessibility repair.
|
|
63
|
+
- Controlled/uncontrolled behavior: `isExpanded` remains authoritative when supplied; otherwise local state starts from `defaultIsExpanded ?? false`.
|
|
64
|
+
- Migration decision: none. No public type, prop, export, default, or theme target changes.
|
|
65
|
+
|
|
66
|
+
Consumer migration instructions belong in consumer docs and release notes.
|
|
67
|
+
|
|
68
|
+
## Ownership boundary
|
|
69
|
+
|
|
70
|
+
**Owns**
|
|
71
|
+
|
|
72
|
+
- Projection of ordered call data into single-call or grouped presentation.
|
|
73
|
+
- Group and per-call disclosures, including keyboard operation and focus treatment.
|
|
74
|
+
- Status, metadata, duration, statistics, and result-detail placement.
|
|
75
|
+
- The root div, `chat-tool-calls` target, supported BaseProps composition, and ref.
|
|
76
|
+
|
|
77
|
+
**Does not own / non-goals**
|
|
78
|
+
|
|
79
|
+
- Tool execution, streaming transport, result parsing, or error recovery.
|
|
80
|
+
- Semantics and interaction inside caller-provided `stats` or `resultDetail` content.
|
|
81
|
+
- Badge, Icon, Spinner, or CodeBlock internals.
|
|
82
|
+
- Product policy for which tool calls may be shown.
|
|
83
|
+
|
|
84
|
+
## Public concepts
|
|
85
|
+
|
|
86
|
+
| Concept | Closed values or states | Meaning | Availability | Default | Owner | Stability | Invalid-value behavior |
|
|
87
|
+
| ------------- | ----------------------------------------------------- | ------------------------------------------------------------ | ------------------- | --------- | ----------------------------------- | ------------------------- | ------------------------------------ |
|
|
88
|
+
| Call list | empty; single; multiple | Selects absent, direct-row, or grouped presentation. | Every render | required | `component:ChatToolCalls` | released observed surface | Empty renders nothing. |
|
|
89
|
+
| Status | pending; running; complete; error | Selects the visible and accessible execution state. | Every call | complete | `component:ChatToolCalls` | released observed surface | Type-invalid values reject. |
|
|
90
|
+
| Group label | omitted; supplied string | Names an expanded group; omission uses the translated count. | Multiple calls | omitted | caller and component | released observed surface | Supplied strings render verbatim. |
|
|
91
|
+
| Group state | controlled; uncontrolled collapsed; uncontrolled open | Controls whether grouped rows are exposed. | Multiple calls | collapsed | caller or component | released observed surface | Conflicting control is avoided. |
|
|
92
|
+
| Result detail | omitted; caller React node | Adds an independently operable per-call disclosure. | Any call | omitted | caller and component | released observed surface | Omitted content adds no control. |
|
|
93
|
+
| Root surface | ref; supported DOM/data/ARIA/class/style/xstyle | Extends the root without replacing its owned target. | Non-empty call list | omitted | `architecture:public-component-api` | released observed surface | Unsupported inputs stay unsupported. |
|
|
94
|
+
|
|
95
|
+
## Behavioral and layout contract
|
|
96
|
+
|
|
97
|
+
| ID | Candidate invariant | Basis | Draft review state |
|
|
98
|
+
| --- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------ |
|
|
99
|
+
| FR1 | An empty call list MUST render no root; one call MUST render directly; multiple calls MUST render one group disclosure and preserve caller order in its full list. | Released implementation, docs, stories, and tests | verified |
|
|
100
|
+
| FR2 | A supplied `label` MUST replace the translated count on the expanded group surface; omission MUST retain the translated count fallback. | Released public prop and consumer docs; public API INV5, INV9 | remediated and verified |
|
|
101
|
+
| FR3 | A collapsed group MUST keep its descendant call disclosures out of keyboard and accessibility navigation; expansion MUST restore them. | HTML `inert`, disclosure semantics, WCAG operability | remediated and verified |
|
|
102
|
+
| FR4 | Every component-owned disclosure MUST activate with Enter, Space, and pointer input, expose expansion state, and draw the shared keyboard focus ring. | Current interaction-modality architecture and WCAG 2.4.7 | remediated and verified |
|
|
103
|
+
| FR5 | Neutral supporting labels, targets, durations, and custom statistics MUST use the readable secondary foreground; signed addition/deletion counts retain their released semantic colors pending OQ2. | WCAG 2.2 SC 1.4.3 and current token architecture | partial remediation; OQ2 |
|
|
104
|
+
| FR6 | Supported root ref, DOM/data/ARIA, className, style, and xstyle inputs MUST reach or compose on the root while the public target remains intact. | `architecture:public-component-api/INV5–INV6, INV8` | verified |
|
|
105
|
+
|
|
106
|
+
### Allowed variation
|
|
107
|
+
|
|
108
|
+
- **AV1 — Call content.** Tool names, targets, node names, durations, statistics, error messages, and result details remain caller supplied.
|
|
109
|
+
- **AV2 — Group control.** Callers may control expansion or supply only its initial uncontrolled value.
|
|
110
|
+
- **AV3 — Styling.** Supported root styling inputs may extend the component without replacing its public target.
|
|
111
|
+
|
|
112
|
+
### Representative states
|
|
113
|
+
|
|
114
|
+
| State | Required invariant | Allowed variation |
|
|
115
|
+
| -------------------- | ------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
|
|
116
|
+
| Empty | No root is rendered. | Empty array identity may vary. |
|
|
117
|
+
| Single | One row appears without group chrome. | Metadata and result detail may be absent. |
|
|
118
|
+
| Multiple, collapsed | Latest call and count appear; full rows are inert. | Call count and latest status may vary. |
|
|
119
|
+
| Multiple, expanded | Every call appears in source order; supplied label or translated count names the group. | Label text and row metadata may vary. |
|
|
120
|
+
| Detail closed/open | The row exposes its state and conditionally mounts the caller-owned detail. | Any caller React node. |
|
|
121
|
+
| Statuses | All statuses expose translated accessible text; complete and error also retain distinct semantic marks. | Theme may change semantic artwork; pending and running share a spinner pending OQ1. |
|
|
122
|
+
| Narrow / RTL context | Rows truncate without horizontal overflow and follow logical inline direction. | Content length, theme, and direction. |
|
|
123
|
+
|
|
124
|
+
### Transformation and precedence order
|
|
125
|
+
|
|
126
|
+
- **ORD1 — Choose presentation.** Empty, single, and grouped branches are selected from list length.
|
|
127
|
+
- **ORD2 — Resolve state.** Controlled expansion wins; otherwise local state starts from the initial default.
|
|
128
|
+
- **ORD3 — Resolve label.** A supplied group label wins; otherwise use the translated count.
|
|
129
|
+
- **ORD4 — Compose rows.** Preserve call order, render status and metadata, then add caller-owned detail disclosure where present.
|
|
130
|
+
- **ORD5 — Compose root.** Apply the component target and styles, then combine supported consumer inputs.
|
|
131
|
+
|
|
132
|
+
### Performance and resources
|
|
133
|
+
|
|
134
|
+
- **PR1 — Local state only.** The component owns disclosure state and no Effect, listener, observer, timer, or external resource.
|
|
135
|
+
- **PR2 — Linear projection.** Group rendering traverses the supplied call list once and does not mutate caller data.
|
|
136
|
+
|
|
137
|
+
## Accessibility contract
|
|
138
|
+
|
|
139
|
+
- **AR1 — Disclosure operation.** Group and detail disclosures expose `aria-expanded`, operate with pointer, Enter, and Space, and use the shared visible focus ring.
|
|
140
|
+
- **AR2 — Collapsed ownership.** Collapsed group content is inert; hidden detail content is unmounted.
|
|
141
|
+
- **AR3 — Status meaning.** Every status exposes translated visually hidden text. Complete and error also use distinct semantic marks; pending and running currently share the same subtle spinner (OQ1). Error messages are exposed to assistive technology and echoed in the status icon's hover tooltip.
|
|
142
|
+
- **AR4 — Static evidence.** Focus appearance, keyboard behavior, inertness, color contrast, and DOM relationships use unit, axe, and real-browser evidence under `spec:AST-009/FR7`; this audit makes no AT-announcement claim.
|
|
143
|
+
|
|
144
|
+
## Design relationships
|
|
145
|
+
|
|
146
|
+
| Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
|
|
147
|
+
| ---------------- | ---------------------------------------------------------------------------------------------- | --------------------------------- | -------------- | ------------------ |
|
|
148
|
+
| Call row | Compact inline status and metadata remain legible. | Current source and WCAG contrast | supporting | FR5, AR3 |
|
|
149
|
+
| Disclosure | Keyboard focus remains visible without changing layout. | Current interaction architecture | supporting | FR4, AR1 |
|
|
150
|
+
| Status | Translated hidden text preserves accessible meaning; complete and error retain semantic marks. | Current source and objective a11y | supporting | FR5, AR3 |
|
|
151
|
+
|
|
152
|
+
This observational draft does not choose new spacing, density, iconography,
|
|
153
|
+
proportion, status vocabulary, or motion.
|
|
154
|
+
|
|
155
|
+
### Theme ownership
|
|
156
|
+
|
|
157
|
+
The existing `chat-tool-calls` target remains on the root. Badge, Icon, and Spinner
|
|
158
|
+
own their nested targets and paint. This observational draft does not add a public
|
|
159
|
+
theme target or redefine inherited Chat-family anatomy.
|
|
160
|
+
|
|
161
|
+
## Family and system relationships
|
|
162
|
+
|
|
163
|
+
- `architecture:public-component-api` owns released exports, accepted inputs, styling composition, and refs.
|
|
164
|
+
- `architecture:component-theming-surface` owns the target and delegated anatomy contract.
|
|
165
|
+
- `architecture:interaction-modality` owns shared keyboard focus treatment.
|
|
166
|
+
- `architecture:component-test-sufficiency` owns bounded, mutation-sensitive evidence.
|
|
167
|
+
- `spec:AST-009` assigns these static semantics, keyboard, focus, and contrast claims to lower evidence layers rather than real AT.
|
|
168
|
+
- `spec:AST-029` owns this observational audit backfill and closed evidence receipt.
|
|
169
|
+
|
|
170
|
+
## Verification map
|
|
171
|
+
|
|
172
|
+
| Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
|
|
173
|
+
| ---------------- | ----------------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | ----------------------------------- |
|
|
174
|
+
| FR1–FR4, AR1–AR2 | `ChatToolCalls.test.tsx` | empty, single, grouped, label, disclosures | Ignored label, wrong state, operable collapsed row, or missing ring fails. | `audit:ChatToolCalls/behavior` |
|
|
175
|
+
| FR5, AR3–AR4 | scoped Chromium axe plus existing-baseline visual comparisons | neutral metadata in light mode; existing visual states in light/dark | Reintroducing disabled-text contrast fails; semantic stats remain baselined under OQ2. | `audit:ChatToolCalls/accessibility` |
|
|
176
|
+
| FR6 | focused root passthrough/ref checks and theming target guard | single root | A supported input, ref, or public target is dropped or replaced. | `audit:ChatToolCalls/public-api` |
|
|
177
|
+
| RTL relation | source-hashed verified-N/A record | all checked-in stories | Component-owned directional behavior invalidates the record. | `audit:ChatToolCalls/i18n-rtl` |
|
|
178
|
+
| Browser matrix | existing visual baselines, scoped a11y, and required real-browser play guards | grouped focus and 320px narrow overflow; existing light/dark states | Missing focus, overflow, visual regressions, or new a11y violations fail. | `audit:ChatToolCalls/rendered` |
|
|
179
|
+
| Docs / surface | docs, declarations, exports, knowledge check, docs typecheck | public props, Chat subpath, draft record | Missing or stale docs, export, target, or knowledge shape fails. | `audit:ChatToolCalls/docs` |
|
|
180
|
+
|
|
181
|
+
## Decision log
|
|
182
|
+
|
|
183
|
+
No component-local product decision is created by this observational draft. The
|
|
184
|
+
repairs restore released API behavior and objective accessibility requirements.
|
|
185
|
+
|
|
186
|
+
## Open questions
|
|
187
|
+
|
|
188
|
+
- **OQ1 — Pending/running visual distinction.** Pending and running currently render the same subtle spinner and differ only in translated accessible text. Which approved visible treatment should distinguish them without inventing component-local status policy?
|
|
189
|
+
- **OQ2 — Semantic statistics contrast.** The released success/error foreground tokens for signed `+N`/`-N` statistics do not reach 4.5:1 in every shipped light/dark surface. Which system-level semantic text token should replace them while preserving addition/deletion meaning? The five affected axe baselines remain until that owner decision lands.
|
|
190
|
+
|
|
191
|
+
## Content boundary
|
|
192
|
+
|
|
193
|
+
This file does not duplicate consumer examples, audit scores, screenshots, tool
|
|
194
|
+
execution policy, or delegated component contracts.
|