@astryxdesign/core 0.6.2 → 0.6.3-canary.0899f21
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.js +1 -1
- 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 +716 -167
- 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/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.test.tsx +1 -4
- package/src/Chat/ChatSendButton.tsx +1 -1
- 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/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 +203 -45
- package/src/Markdown/Markdown.test.tsx +63 -0
- 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 +12 -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 +20 -0
- package/src/Markdown/parser.ts +1180 -235
- 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 +31 -0
- package/src/SegmentedControl/SegmentedControlItem.tsx +6 -9
- package/src/Selector/Selector.doc.mjs +2 -2
- 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
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* @file ChatMessageList.test.tsx
|
|
5
|
+
* @input React Testing Library, Vitest, and the public ChatMessageList surface
|
|
6
|
+
* @output Observable log, empty-state, alignment, and async-loading regressions
|
|
7
|
+
* @position Colocated component behavior tests
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import {describe, it, expect, vi} from 'vitest';
|
|
11
|
+
import {act, render, screen} from '@testing-library/react';
|
|
5
12
|
import {ChatMessageList} from './ChatMessageList';
|
|
6
13
|
import {ChatMessage} from './ChatMessage';
|
|
7
14
|
import {ChatMessageBubble} from './ChatMessageBubble';
|
|
@@ -55,6 +62,11 @@ describe('ChatMessageList', () => {
|
|
|
55
62
|
expect(screen.getByText('No messages yet')).toBeTruthy();
|
|
56
63
|
});
|
|
57
64
|
|
|
65
|
+
it('renders an accepted numeric empty state', () => {
|
|
66
|
+
render(<ChatMessageList emptyState={0}>{[]}</ChatMessageList>);
|
|
67
|
+
expect(screen.getByRole('log')).toHaveTextContent('0');
|
|
68
|
+
});
|
|
69
|
+
|
|
58
70
|
it('applies density class', () => {
|
|
59
71
|
render(
|
|
60
72
|
<ChatMessageList density="compact" data-testid="list">
|
|
@@ -129,4 +141,54 @@ describe('ChatMessageList', () => {
|
|
|
129
141
|
);
|
|
130
142
|
expect(screen.getByText('Hello')).toBeTruthy();
|
|
131
143
|
});
|
|
144
|
+
|
|
145
|
+
it('loads older messages through the top sentinel and exposes pending status', async () => {
|
|
146
|
+
let notify!: IntersectionObserverCallback;
|
|
147
|
+
let complete!: () => void;
|
|
148
|
+
const observeSentinel = vi.fn();
|
|
149
|
+
const disconnect = vi.fn();
|
|
150
|
+
const action = vi.fn(
|
|
151
|
+
async () =>
|
|
152
|
+
new Promise<void>(resolve => {
|
|
153
|
+
complete = resolve;
|
|
154
|
+
}),
|
|
155
|
+
);
|
|
156
|
+
class Observer {
|
|
157
|
+
constructor(callback: IntersectionObserverCallback) {
|
|
158
|
+
notify = callback;
|
|
159
|
+
}
|
|
160
|
+
observe = observeSentinel;
|
|
161
|
+
disconnect = disconnect;
|
|
162
|
+
}
|
|
163
|
+
vi.stubGlobal('IntersectionObserver', Observer);
|
|
164
|
+
try {
|
|
165
|
+
const {unmount} = render(
|
|
166
|
+
<ChatMessageList scrollToTopAction={action}>
|
|
167
|
+
<div>Earlier message</div>
|
|
168
|
+
</ChatMessageList>,
|
|
169
|
+
);
|
|
170
|
+
expect(observeSentinel).toHaveBeenCalledTimes(1);
|
|
171
|
+
act(() => {
|
|
172
|
+
notify(
|
|
173
|
+
[{isIntersecting: false} as IntersectionObserverEntry],
|
|
174
|
+
{} as IntersectionObserver,
|
|
175
|
+
);
|
|
176
|
+
});
|
|
177
|
+
expect(action).not.toHaveBeenCalled();
|
|
178
|
+
act(() => {
|
|
179
|
+
notify(
|
|
180
|
+
[{isIntersecting: true} as IntersectionObserverEntry],
|
|
181
|
+
{} as IntersectionObserver,
|
|
182
|
+
);
|
|
183
|
+
});
|
|
184
|
+
expect(action).toHaveBeenCalledTimes(1);
|
|
185
|
+
expect(screen.getByRole('status', {name: 'Loading'})).toBeTruthy();
|
|
186
|
+
await act(async () => complete());
|
|
187
|
+
expect(screen.queryByRole('status', {name: 'Loading'})).toBeNull();
|
|
188
|
+
unmount();
|
|
189
|
+
expect(disconnect).toHaveBeenCalledTimes(1);
|
|
190
|
+
} finally {
|
|
191
|
+
vi.unstubAllGlobals();
|
|
192
|
+
}
|
|
193
|
+
});
|
|
132
194
|
});
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @file ChatMessageList.tsx
|
|
7
|
-
* @input Uses React, StyleX, ChatListContext, theme tokens, spacing step utilities
|
|
7
|
+
* @input Uses React, StyleX, ChatListContext, theme tokens, spacing step utilities,
|
|
8
|
+
* and isRenderable to preserve accepted empty-state content
|
|
8
9
|
* @output Exports ChatMessageList component and ChatMessageListProps
|
|
9
10
|
* @position Presentational message container — holds ChatMessage children
|
|
10
11
|
*
|
|
@@ -31,7 +32,7 @@ import {
|
|
|
31
32
|
type ChatDensity,
|
|
32
33
|
useChatLayoutContext,
|
|
33
34
|
} from './ChatContext';
|
|
34
|
-
import {mergeProps} from '../utils';
|
|
35
|
+
import {isRenderable, mergeProps} from '../utils';
|
|
35
36
|
import {Spinner} from '../Spinner';
|
|
36
37
|
import type {BaseProps} from '../BaseProps';
|
|
37
38
|
import type {SpacingStep} from '../utils/types';
|
|
@@ -321,7 +322,7 @@ export function ChatMessageList({
|
|
|
321
322
|
{/* Messages or empty state */}
|
|
322
323
|
{hasChildren ? (
|
|
323
324
|
children
|
|
324
|
-
) : emptyState ? (
|
|
325
|
+
) : isRenderable(emptyState) ? (
|
|
325
326
|
<div {...stylex.props(styles.emptyState)}>{emptyState}</div>
|
|
326
327
|
) : null}
|
|
327
328
|
</div>
|
|
@@ -6,7 +6,8 @@ export const docs = {
|
|
|
6
6
|
name: 'ChatMessageMetadata',
|
|
7
7
|
subComponentOf: 'Chat',
|
|
8
8
|
displayName: 'Chat Message Metadata',
|
|
9
|
-
description:
|
|
9
|
+
description:
|
|
10
|
+
'Composable metadata row for chat messages. Renders timestamp, footer content, and delivery status in a single row. Direction reverses for user sender. Omits the row when both slots are omitted or non-rendering scalars and status is omitted.',
|
|
10
11
|
props: [
|
|
11
12
|
{
|
|
12
13
|
name: 'timestamp',
|
|
@@ -42,12 +43,64 @@ export const docs = {
|
|
|
42
43
|
description: 'Message delivery status. Shows icon + label.',
|
|
43
44
|
},
|
|
44
45
|
],
|
|
46
|
+
usage: {
|
|
47
|
+
description:
|
|
48
|
+
'Place ChatMessageMetadata below a message or in the last ChatMessageBubble metadata slot to show a timestamp, footer content, and optional delivery status. Non-rendering scalar slots (booleans and empty strings) create no separator; numeric zero remains visible. Composite React content remains caller-owned.',
|
|
49
|
+
bestPractices: [
|
|
50
|
+
{
|
|
51
|
+
guidance: true,
|
|
52
|
+
description:
|
|
53
|
+
'Put metadata in the last bubble metadata slot when the message uses bubbles, so it follows the bubble content.',
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
guidance: true,
|
|
57
|
+
description:
|
|
58
|
+
'Pass timestamp and footer content independently; separators are omitted for non-rendering scalar slots. Composite React nodes are used as supplied.',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
guidance: false,
|
|
62
|
+
description:
|
|
63
|
+
'Do not supply footer actions without their own accessible names and interaction behavior; the metadata row does not own those controls.',
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
guidance: false,
|
|
67
|
+
description:
|
|
68
|
+
'Do not put the same metadata on both a bubble and its enclosing message.',
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
anatomy: [
|
|
72
|
+
{
|
|
73
|
+
name: 'Metadata row',
|
|
74
|
+
required: true,
|
|
75
|
+
description: 'Sender-aware line containing the visible metadata items.',
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'Timestamp',
|
|
79
|
+
required: false,
|
|
80
|
+
description:
|
|
81
|
+
'Caller-supplied time content at the start of the logical sequence.',
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: 'Footer',
|
|
85
|
+
required: false,
|
|
86
|
+
description:
|
|
87
|
+
'Caller-supplied information or actions between time and status.',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
name: 'Status',
|
|
91
|
+
required: false,
|
|
92
|
+
description:
|
|
93
|
+
'Localized delivery icon and text when a status is supplied.',
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
},
|
|
45
97
|
};
|
|
46
98
|
|
|
47
99
|
export const docsZh = {
|
|
48
100
|
name: 'ChatMessageMetadata',
|
|
49
101
|
displayName: 'Chat Message Metadata',
|
|
50
|
-
description:
|
|
102
|
+
description:
|
|
103
|
+
'可组合的消息元数据行。渲染时间戳、页脚内容和发送状态。用户消息方向反转。',
|
|
51
104
|
propDescriptions: {
|
|
52
105
|
timestamp: '时间戳内容,字符串或 Timestamp 组件。',
|
|
53
106
|
footer: '页脚内容:模型信息、反应按钮、复制按钮。',
|
|
@@ -58,7 +111,8 @@ export const docsZh = {
|
|
|
58
111
|
export const docsDense = {
|
|
59
112
|
name: 'ChatMessageMetadata',
|
|
60
113
|
displayName: 'Chat Message Metadata',
|
|
61
|
-
description:
|
|
114
|
+
description:
|
|
115
|
+
'composable metadata row; renders timestamp · footer · status; reverses for user sender',
|
|
62
116
|
propDescriptions: {
|
|
63
117
|
timestamp: 'timestamp content; string or Timestamp',
|
|
64
118
|
footer: 'footer content; model info, reaction btns, copy btn',
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 3
|
|
3
|
+
template_version: 6
|
|
4
|
+
kind: component
|
|
5
|
+
id: component:ChatMessageMetadata
|
|
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, accessibility, theming, testing]
|
|
13
|
+
verified_by:
|
|
14
|
+
[
|
|
15
|
+
packages/core/src/Chat/ChatMessageMetadata.test.tsx,
|
|
16
|
+
packages/core/src/Chat/__tests__/ChatMessageMetadata.a11y.chromium.spec.ts,
|
|
17
|
+
apps/storybook/stories/ChatMessageMetadata.stories.tsx,
|
|
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-test-sufficiency,
|
|
27
|
+
architecture:component-theming-surface,
|
|
28
|
+
architecture:component-style-authoring,
|
|
29
|
+
architecture:react-component-runtime,
|
|
30
|
+
architecture:knowledge-contracts,
|
|
31
|
+
]
|
|
32
|
+
contributing: []
|
|
33
|
+
system_specs: [spec:AST-029]
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
# ChatMessageMetadata component contract
|
|
37
|
+
|
|
38
|
+
This is an observational draft of the existing Core chat metadata surface and
|
|
39
|
+
its tested empty-scalar correction. It creates no new prop, status meaning,
|
|
40
|
+
announcement guarantee, or visual policy. Current shared records govern their
|
|
41
|
+
own scopes independently of this draft.
|
|
42
|
+
|
|
43
|
+
## Contract at a glance
|
|
44
|
+
|
|
45
|
+
| Area | Contract |
|
|
46
|
+
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
47
|
+
| Public contract | Optional `timestamp` and `footer` ReactNode slots, optional closed `status` union, root `BaseProps<HTMLDivElement>` and `ref`, exported through `./Chat`. |
|
|
48
|
+
| Behavior | The row renders its present slots in timestamp, footer, status order, with a separator only between present slots; user sender reverses the flex row. Five delivery statuses have localized icon-and-text displays. |
|
|
49
|
+
| End-user impact | Non-rendering scalar slot values no longer leave a standalone dot, a blank metadata row, or a separator without adjacent content. Visible numeric zero remains. |
|
|
50
|
+
| Builder impact | No new inputs, defaults, or migration. Caller-supplied footer controls remain caller-owned. |
|
|
51
|
+
| Compatibility/readiness | Patch-compatible scalar correction to a released `./Chat` subpath; draft pending exact-head observational verification and owner review. |
|
|
52
|
+
| Review checks | Reject a lost visible zero, stranded separator, omitted translated status label, dropped root passthrough, or claim that a static DOM attribute proves an AT announcement. |
|
|
53
|
+
| Governing rules | `architecture:public-component-api/INV1, INV3, INV5–INV9`; `architecture:component-test-sufficiency/INV1–INV7`; `spec:AST-029/FR2–FR5`. |
|
|
54
|
+
|
|
55
|
+
The table is a review projection. Consumer syntax belongs in
|
|
56
|
+
`ChatMessageMetadata.doc.mjs` and the Chat family consumer documentation.
|
|
57
|
+
|
|
58
|
+
## Intent
|
|
59
|
+
|
|
60
|
+
ChatMessageMetadata is the optional compact line below a chat message. It
|
|
61
|
+
projects caller-owned timestamp/footer content and an optional delivery status
|
|
62
|
+
inside the sender-aware Chat composition. It is not the message article, the
|
|
63
|
+
bubble surface, the transcript, or the footer control owner.
|
|
64
|
+
|
|
65
|
+
## Compatibility and migration
|
|
66
|
+
|
|
67
|
+
- Released default preserved: yes. Core `0.6.3` exports `./Chat` with this
|
|
68
|
+
component, props, and status type.
|
|
69
|
+
- Compatibility class: patch correction for non-rendering scalar ReactNode
|
|
70
|
+
values, preserving numeric `0` and the published props.
|
|
71
|
+
- Controlled/uncontrolled behavior: not applicable; the component stores no
|
|
72
|
+
delivery state.
|
|
73
|
+
- Migration decision: none. Existing callers need no new option.
|
|
74
|
+
|
|
75
|
+
Consumer migration instructions, when needed, belong in release notes rather
|
|
76
|
+
than this record.
|
|
77
|
+
|
|
78
|
+
## Ownership boundary
|
|
79
|
+
|
|
80
|
+
**Owns**
|
|
81
|
+
|
|
82
|
+
- The optional metadata root, its `chat-message-metadata` painting target,
|
|
83
|
+
ref, neutral DOM passthrough, and composed styling inputs.
|
|
84
|
+
- Presence checks and separators among timestamp, footer, and status.
|
|
85
|
+
- Sender-relative row order from the nearest Chat message context, with an
|
|
86
|
+
assistant fallback outside that context.
|
|
87
|
+
- Status-to-glyph and translated-caption selection and the local sending/error
|
|
88
|
+
paint path.
|
|
89
|
+
|
|
90
|
+
**Does not own / non-goals**
|
|
91
|
+
|
|
92
|
+
- Sender identity, article semantics, avatar, name, and body alignment:
|
|
93
|
+
`ChatMessage` owns these.
|
|
94
|
+
- Bubble inset and placement: `ChatMessageBubble` owns these.
|
|
95
|
+
- Footer action semantics, button focus, and callback behavior: the caller's
|
|
96
|
+
supplied content owns them.
|
|
97
|
+
- Transcript scrolling, loading, or delivery-state transitions: the surrounding
|
|
98
|
+
composition owns these.
|
|
99
|
+
- A new public rule for inspecting composite, lazy, or asynchronous ReactNode
|
|
100
|
+
values, or a screen-reader announcement-timing guarantee.
|
|
101
|
+
|
|
102
|
+
## Public concepts
|
|
103
|
+
|
|
104
|
+
| Concept | Closed values or states | Observed meaning | Availability | Default | Owner | Stability | Invalid-value behavior |
|
|
105
|
+
| -------------- | ------------------------------------------------------------------ | ----------------------------------------------------------------- | --------------------------------------------------- | ------------------------------------------- | ----------------------------------- | ------------- | ---------------------------------------------------------------------------------------------------- |
|
|
106
|
+
| `timestamp` | Omitted or caller ReactNode | Optional first item, normally a time | Any composition | Omitted | Caller | Released | Null, booleans, and empty string do not render a scalar slot; `0` renders; non-scalars remain opaque |
|
|
107
|
+
| `footer` | Omitted or caller ReactNode | Optional middle item such as model information or caller controls | Any composition | Omitted | Caller | Released | Same scalar treatment as timestamp |
|
|
108
|
+
| `status` | `sending`, `sent`, `delivered`, `read`, `error`, omitted | Optional delivery caption and glyph | Any composition | Omitted | Component/caller input | Released | Closed type union; omitted contributes no item |
|
|
109
|
+
| Sender context | `user`, `assistant`, `system`, absent | Selects user-reversed or other forward row order | Within `ChatMessage` or standalone | Assistant when absent | `ChatMessage` / local fallback | Observational | Non-user values share the forward path |
|
|
110
|
+
| Root surface | `BaseProps<HTMLDivElement>`, `ref`, `xstyle`, `className`, `style` | Extends the metadata row when it exists | Slot passes scalar-presence check or status present | Absent for empty scalar slots and no status | `architecture:public-component-api` | Released | Non-scalar values remain opaque; target and consumer styles combine |
|
|
111
|
+
|
|
112
|
+
## Behavioral and layout contract
|
|
113
|
+
|
|
114
|
+
The following candidate invariants name their evidence. They are observations
|
|
115
|
+
for review, not current product policy created by this draft.
|
|
116
|
+
|
|
117
|
+
| ID | Candidate invariant | Basis | Draft review state |
|
|
118
|
+
| --- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | ------------------ |
|
|
119
|
+
| FR1 | The root appears when at least one slot passes the shared scalar-presence predicate or `status` is present. Non-scalar values are treated as present without inspecting their inner content. | Public ReactNode seam, shared `isRenderable` scalar utility, focused red/green and browser evidence | Verify correction |
|
|
120
|
+
| FR2 | Accepted slot values render in timestamp, footer, status order with dots between values considered present; numeric `0` is visible in either slot, and non-scalar nodes remain opaque. | Shipped ordering, shared scalar utility, focused tests, light/dark browser cases | Verify correction |
|
|
121
|
+
| FR3 | A `user` message reverses row direction; `assistant`, `system`, and absent context use the forward path. | Source, Chat context, sender and RTL browser fixtures | Verify observation |
|
|
122
|
+
| FR4 | Status selects one of five registry icons and localized labels; failure uses the error text token, and sending has a CSS pulse suppressed under reduced motion. | Source, locale catalog, owned browser status matrix | Verify observation |
|
|
123
|
+
| FR5 | The root merges the target, default StyleX output, and consumer `xstyle`, `className`, and `style`; accepted neutral DOM/ARIA inputs and `ref` reach that root. | Source, public API authority, existing passthrough test | Verify observation |
|
|
124
|
+
| FR6 | A status item has a translated title and author-supplied `aria-label`, an icon and visible localized text. The row declares no live-region role or imperative announcement. | Source, DOM tests and axe fixtures; no real-AT timing claim | Verify observation |
|
|
125
|
+
|
|
126
|
+
### Allowed variation
|
|
127
|
+
|
|
128
|
+
- **AV1 - Slot content.** The caller decides the structure and semantics inside
|
|
129
|
+
timestamp and footer slots. This component does not inspect non-scalar nodes.
|
|
130
|
+
- **AV2 - Theme.** Semantic colors, typography, and spacing resolve through the
|
|
131
|
+
active Theme; the root remains the public metadata painting target.
|
|
132
|
+
- **AV3 - Context.** Standalone use takes the assistant ordering fallback.
|
|
133
|
+
|
|
134
|
+
### Representative states
|
|
135
|
+
|
|
136
|
+
| State | Observed result | Allowed variation |
|
|
137
|
+
| --------------------------- | --------------------------------------------------------------------------- | -------------------------------------- |
|
|
138
|
+
| Standalone timestamp | One root and one visible item | Caller content |
|
|
139
|
+
| User or assistant message | Sender-relative row order | Text direction inherited from the page |
|
|
140
|
+
| Timestamp + footer + status | Items separated according to scalar presence; composite nodes remain opaque | Caller footer content |
|
|
141
|
+
| Each delivery status | Distinct localized caption and mapped icon | Active translation and theme tokens |
|
|
142
|
+
| Non-rendering scalar slots | No stranded dot; no row when all items are empty | Composite nodes remain opaque |
|
|
143
|
+
| Numeric `0` | Visible content, not an empty marker | Either slot |
|
|
144
|
+
| Long footer at narrow width | Content reflows within its container | Caller text may wrap |
|
|
145
|
+
|
|
146
|
+
### Transformation and precedence order
|
|
147
|
+
|
|
148
|
+
- **ORD1 - Presence before separators.** Decide scalar presence with the shared
|
|
149
|
+
predicate while treating non-scalar caller nodes as opaque, then place
|
|
150
|
+
punctuation between values considered present. The status check remains
|
|
151
|
+
independent of the slot checks.
|
|
152
|
+
- **ORD2 - Composition.** Resolve sender context, select flex order, and compose
|
|
153
|
+
component StyleX and theme target with consumer styling inputs on one root.
|
|
154
|
+
|
|
155
|
+
### Performance and resources
|
|
156
|
+
|
|
157
|
+
- **PR1 - Render derivation.** The component creates no local React state,
|
|
158
|
+
Effects, timers, observer, or event listeners. Its local animation is CSS and
|
|
159
|
+
suppressed for reduced motion.
|
|
160
|
+
|
|
161
|
+
## Accessibility contract
|
|
162
|
+
|
|
163
|
+
- **AR1 - Display semantics.** The metadata line does not add a button, focus
|
|
164
|
+
target, list role, or live region of its own. Interactive footer content retains
|
|
165
|
+
its own semantics and keyboard behavior.
|
|
166
|
+
- **AR2 - Visible delivery state.** The status caption accompanies the glyph so
|
|
167
|
+
state identification does not rely on color or the icon alone.
|
|
168
|
+
- **AR3 - Evidence boundary.** Browser-exposed markup and axe coverage do not
|
|
169
|
+
establish spoken output or announcement timing; any such future claim follows
|
|
170
|
+
`spec:AST-009` and its named AT evidence rule.
|
|
171
|
+
|
|
172
|
+
## Design relationships
|
|
173
|
+
|
|
174
|
+
| Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
|
|
175
|
+
| ---------------- | ---------------------------------------------------------------- | -------------------------------------------- | -------------- | ------------------ |
|
|
176
|
+
| Metadata row | Semantic supporting typography and sender-relative reading order | Local representation unsettled | Supporting | FR2–FR3 |
|
|
177
|
+
| Delivery status | Registry glyph, caption, and semantic error token | Local prominence and motion choice unsettled | Supporting | FR4, AR2 |
|
|
178
|
+
|
|
179
|
+
No current component-local ChatMessageMetadata design decision is introduced.
|
|
180
|
+
The draft `design:motion` and `design:system-states` records are not adopted as
|
|
181
|
+
current authority by this record.
|
|
182
|
+
|
|
183
|
+
## Family and system relationships
|
|
184
|
+
|
|
185
|
+
- There is no current `family:chat` product-authority record. `Chat.doc.mjs` is
|
|
186
|
+
consumer composition guidance, not a family contract.
|
|
187
|
+
- `architecture:public-component-api` owns root export and passthrough;
|
|
188
|
+
`architecture:component-theming-surface` owns the public painting target;
|
|
189
|
+
`architecture:component-test-sufficiency` owns bounded evidence coverage.
|
|
190
|
+
- `spec:AST-029` keeps the closed audit inventory and score outside this
|
|
191
|
+
component draft.
|
|
192
|
+
|
|
193
|
+
## Verification map
|
|
194
|
+
|
|
195
|
+
| Contract | Evidence | Representative states | Mutation or failure expectation | Audit section |
|
|
196
|
+
| ------------ | ------------------------------------------------------ | ------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------- |
|
|
197
|
+
| FR1–FR2 | `ChatMessageMetadata.test.tsx`; Chromium receipts | empty scalar, zero, timestamp/footer/status | A nullish-only guard reintroduces a stray separator or blank row | `audit:ChatMessageMetadata/behavior` |
|
|
198
|
+
| FR3 | Storybook sender fixtures and Chromium RTL frames | user, assistant, standalone in LTR/RTL | Wrong relative ordering becomes visible | `audit:ChatMessageMetadata/rtl` |
|
|
199
|
+
| FR4, AR2 | Status fixtures, locale catalog, Chromium/axe receipts | five statuses, light/dark, reduced motion | A dropped status label or failed theme paint is visible | `audit:ChatMessageMetadata/accessibility` |
|
|
200
|
+
| FR5 | Existing passthrough test and theming-target guard | DOM/data/ARIA and styling | Root drops accepted caller inputs or target | `audit:ChatMessageMetadata/public-api` |
|
|
201
|
+
| FR6, AR1–AR3 | Axe and browser semantic receipts | static status and caller button | Missing text/icon or falsely claimed AT timing remains detectable | `audit:ChatMessageMetadata/testing` |
|
|
202
|
+
|
|
203
|
+
## Decision log
|
|
204
|
+
|
|
205
|
+
None. This draft makes no new component-local product decision.
|
|
206
|
+
|
|
207
|
+
## Open questions
|
|
208
|
+
|
|
209
|
+
- **OQ1 - Should non-scalar ReactNode slots ever be normalized for emptiness?**
|
|
210
|
+
(`human-api`) Arrays, Fragments, lazy content, and promises remain opaque under
|
|
211
|
+
the existing scalar predicate; this audit does not consume or inspect them.
|
|
212
|
+
- **OQ2 - Should standalone delivery-status changes be announced, and if so by
|
|
213
|
+
which owner?** (`human-api`) The current row is display-only. No spoken-timing
|
|
214
|
+
claim is made without a current owner and applicable AT evidence.
|
|
215
|
+
|
|
216
|
+
## Content boundary
|
|
217
|
+
|
|
218
|
+
This record does not store an audit score, screenshot manifest, CI transcript,
|
|
219
|
+
consumer prop example, new public API, or shared visual policy. Those remain in
|
|
220
|
+
the audit PR evidence, consumer docs, and their canonical owners.
|
|
@@ -29,4 +29,38 @@ describe('ChatMessageMetadata', () => {
|
|
|
29
29
|
expect(root).toHaveAttribute('data-custom', 'x');
|
|
30
30
|
expect(root).toHaveAttribute('id', 'meta-1');
|
|
31
31
|
});
|
|
32
|
+
|
|
33
|
+
it('omits separators when a footer slot has no rendered content', () => {
|
|
34
|
+
render(
|
|
35
|
+
<ChatMessageMetadata
|
|
36
|
+
timestamp="10:32"
|
|
37
|
+
footer={false}
|
|
38
|
+
data-testid="meta"
|
|
39
|
+
/>,
|
|
40
|
+
);
|
|
41
|
+
expect(screen.getByTestId('meta')).toHaveTextContent('10:32');
|
|
42
|
+
expect(screen.getByTestId('meta')).not.toHaveTextContent('·');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('omits an empty timestamp and the row when both slots are empty', () => {
|
|
46
|
+
const {rerender} = render(
|
|
47
|
+
<ChatMessageMetadata
|
|
48
|
+
timestamp={false}
|
|
49
|
+
footer="Model info"
|
|
50
|
+
data-testid="meta"
|
|
51
|
+
/>,
|
|
52
|
+
);
|
|
53
|
+
expect(screen.getByTestId('meta')).toHaveTextContent('Model info');
|
|
54
|
+
expect(screen.getByTestId('meta')).not.toHaveTextContent('·');
|
|
55
|
+
|
|
56
|
+
rerender(
|
|
57
|
+
<ChatMessageMetadata timestamp="" footer={false} data-testid="meta" />,
|
|
58
|
+
);
|
|
59
|
+
expect(screen.queryByTestId('meta')).not.toBeInTheDocument();
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('keeps numeric zero in both visible slots', () => {
|
|
63
|
+
render(<ChatMessageMetadata timestamp={0} footer={0} data-testid="meta" />);
|
|
64
|
+
expect(screen.getByTestId('meta')).toHaveTextContent('0·0');
|
|
65
|
+
});
|
|
32
66
|
});
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @file ChatMessageMetadata.tsx
|
|
7
|
-
* @input Uses React, StyleX, ChatContext, Icon, theme tokens
|
|
7
|
+
* @input Uses React, StyleX, ChatContext, Icon, theme tokens, and isRenderable
|
|
8
8
|
* @output Exports ChatMessageMetadata component
|
|
9
9
|
* @position Shared metadata row used by composing inside ChatMessage
|
|
10
10
|
*
|
|
11
|
-
* Renders
|
|
12
|
-
* Direction reverses for user sender.
|
|
11
|
+
* Renders timestamp, footer, and status values with separators determined by
|
|
12
|
+
* scalar presence. Direction reverses for user sender.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import React, {type ReactNode} from 'react';
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
import {useChatMessageContext} from './ChatContext';
|
|
24
24
|
import {Icon} from '../Icon';
|
|
25
25
|
import type {IconName} from '../Icon/globalIconRegistry';
|
|
26
|
-
import {mergeProps} from '../utils';
|
|
26
|
+
import {isRenderable, mergeProps} from '../utils';
|
|
27
27
|
import type {BaseProps} from '../BaseProps';
|
|
28
28
|
import {themeProps} from '../utils/themeProps';
|
|
29
29
|
import {useTranslator} from '../i18n';
|
|
@@ -97,7 +97,8 @@ export interface ChatMessageMetadataProps extends BaseProps<HTMLDivElement> {
|
|
|
97
97
|
* Composable metadata row for chat messages.
|
|
98
98
|
*
|
|
99
99
|
* Renders: timestamp · footer · status
|
|
100
|
-
* Renders nothing
|
|
100
|
+
* Renders nothing when neither slot passes the scalar-presence check and no
|
|
101
|
+
* status is set. Composite React nodes remain caller-owned.
|
|
101
102
|
*
|
|
102
103
|
* @example
|
|
103
104
|
* ```
|
|
@@ -124,8 +125,9 @@ export function ChatMessageMetadata({
|
|
|
124
125
|
const statusConfig = status != null ? STATUS_CONFIG[status] : null;
|
|
125
126
|
const statusLabel = statusConfig != null ? t(statusConfig.i18nKey) : '';
|
|
126
127
|
|
|
127
|
-
const
|
|
128
|
-
|
|
128
|
+
const hasTimestamp = isRenderable(timestamp);
|
|
129
|
+
const hasFooter = isRenderable(footer);
|
|
130
|
+
const hasContent = hasTimestamp || hasFooter || statusConfig != null;
|
|
129
131
|
if (!hasContent) {
|
|
130
132
|
return null;
|
|
131
133
|
}
|
|
@@ -144,12 +146,10 @@ export function ChatMessageMetadata({
|
|
|
144
146
|
style,
|
|
145
147
|
)}
|
|
146
148
|
{...rest}>
|
|
147
|
-
{
|
|
148
|
-
{
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
{footer != null && footer}
|
|
152
|
-
{footer != null && statusConfig != null && <span>·</span>}
|
|
149
|
+
{hasTimestamp && <span>{timestamp}</span>}
|
|
150
|
+
{hasTimestamp && (hasFooter || statusConfig != null) && <span>·</span>}
|
|
151
|
+
{hasFooter && footer}
|
|
152
|
+
{hasFooter && statusConfig != null && <span>·</span>}
|
|
153
153
|
{statusConfig != null && (
|
|
154
154
|
<span
|
|
155
155
|
title={statusLabel}
|
|
@@ -180,10 +180,7 @@ describe('ChatSendButton', () => {
|
|
|
180
180
|
expect(send).toBeEnabled();
|
|
181
181
|
|
|
182
182
|
fireEvent.click(send);
|
|
183
|
-
|
|
184
|
-
// button's behavior. The submitted value comes from the composer's own
|
|
185
|
-
// state, not from here, so asserting it would pin ChatComposer instead.
|
|
186
|
-
expect(onSubmit).toHaveBeenCalledTimes(1);
|
|
183
|
+
expect(onSubmit).toHaveBeenCalledWith('hello');
|
|
187
184
|
});
|
|
188
185
|
});
|
|
189
186
|
});
|
|
@@ -95,7 +95,7 @@ export function ChatSendButton(props: ChatSendButtonProps): ReactNode {
|
|
|
95
95
|
...rest
|
|
96
96
|
} = props;
|
|
97
97
|
|
|
98
|
-
const handleSend = onSend ?? (() => context?.onSubmit(
|
|
98
|
+
const handleSend = onSend ?? (() => context?.onSubmit(context.value));
|
|
99
99
|
const defaultStopIcon = useIcon('stop');
|
|
100
100
|
const defaultSendIcon = useIcon('arrowUp');
|
|
101
101
|
|