@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
|
@@ -7,22 +7,79 @@ export const docs = {
|
|
|
7
7
|
subComponentOf: 'Chat',
|
|
8
8
|
displayName: 'Chat Composer Input',
|
|
9
9
|
isHiddenFromOverview: true,
|
|
10
|
-
description:
|
|
10
|
+
description:
|
|
11
|
+
"Rich text input for the chat composer. Supports trigger menus (type @ or / to open a typeahead), inline tokens rendered as badges, message history recall with ArrowUp/Down, paste/drop file handling, and a 16px iOS font-size floor to prevent input zoom. Pass it to ChatComposer's input slot when you need more than a plain textarea.",
|
|
12
|
+
usage: {
|
|
13
|
+
description:
|
|
14
|
+
"Pass ChatComposerInput to ChatComposer's input slot when the draft needs trigger menus, inline tokens, history recall, dictation insertion, or file intake.",
|
|
15
|
+
bestPractices: [
|
|
16
|
+
{
|
|
17
|
+
guidance: true,
|
|
18
|
+
description:
|
|
19
|
+
'Use handleRef for programmatic text or token insertion; inserted text follows the same onChange pipeline as typing.',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
guidance: true,
|
|
23
|
+
description:
|
|
24
|
+
'Use onFiles for files pasted or dropped onto the editor, and keep file validation and upload progress in the product layer.',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
guidance: false,
|
|
28
|
+
description:
|
|
29
|
+
'Use custom token rendering for ordinary mentions or commands; prefer the structured badge form so tokens remain predictable and themeable.',
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
anatomy: [
|
|
33
|
+
{
|
|
34
|
+
name: 'Input root',
|
|
35
|
+
required: true,
|
|
36
|
+
description:
|
|
37
|
+
'The themed container that forwards the root ref and BaseProps styling seams.',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'Editable surface',
|
|
41
|
+
required: true,
|
|
42
|
+
description:
|
|
43
|
+
'The labeled contenteditable textbox or combobox that owns text, selection, keyboard, paste, and drop behavior.',
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'Placeholder',
|
|
47
|
+
required: false,
|
|
48
|
+
description:
|
|
49
|
+
'Visual guidance shown only while the serialized draft is empty.',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: 'Trigger menu',
|
|
53
|
+
required: false,
|
|
54
|
+
description:
|
|
55
|
+
'The suggestion popup rendered while a configured trigger is active.',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: 'Inline token',
|
|
59
|
+
required: false,
|
|
60
|
+
description:
|
|
61
|
+
'A non-editable badge or custom rendering with a stable serialized value.',
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
},
|
|
11
65
|
props: [
|
|
12
66
|
{
|
|
13
67
|
name: 'handleRef',
|
|
14
68
|
type: 'React.Ref<ChatComposerInputHandle>',
|
|
15
|
-
description:
|
|
69
|
+
description:
|
|
70
|
+
'Imperative handle for programmatic control: insertToken, expandToken, insertText, focus, and getValue.',
|
|
16
71
|
},
|
|
17
72
|
{
|
|
18
73
|
name: 'value',
|
|
19
74
|
type: 'string',
|
|
20
|
-
description:
|
|
75
|
+
description:
|
|
76
|
+
'Controlled input value. Pair with onChange for two-way binding.',
|
|
21
77
|
},
|
|
22
78
|
{
|
|
23
79
|
name: 'onChange',
|
|
24
80
|
type: '(value: string) => void',
|
|
25
|
-
description:
|
|
81
|
+
description:
|
|
82
|
+
'Called when the input value changes. The serialized string includes token placeholders.',
|
|
26
83
|
},
|
|
27
84
|
{
|
|
28
85
|
name: 'placeholder',
|
|
@@ -33,24 +90,28 @@ export const docs = {
|
|
|
33
90
|
{
|
|
34
91
|
name: 'maxRows',
|
|
35
92
|
type: 'number',
|
|
36
|
-
description:
|
|
93
|
+
description:
|
|
94
|
+
'Maximum visible rows before the input scrolls. Use a lower value in compact layouts.',
|
|
37
95
|
default: '8',
|
|
38
96
|
},
|
|
39
97
|
{
|
|
40
98
|
name: 'triggers',
|
|
41
99
|
type: 'ChatComposerTrigger[]',
|
|
42
|
-
description:
|
|
100
|
+
description:
|
|
101
|
+
'Trigger definitions for typeahead menus. Each trigger specifies a character (@ or /), a search source, and an onSelect handler that returns the token to insert.',
|
|
43
102
|
},
|
|
44
103
|
{
|
|
45
104
|
name: 'debounceMs',
|
|
46
105
|
type: 'number',
|
|
47
|
-
description:
|
|
106
|
+
description:
|
|
107
|
+
'Debounce delay for async search sources to avoid excessive network requests.',
|
|
48
108
|
default: '150',
|
|
49
109
|
},
|
|
50
110
|
{
|
|
51
111
|
name: 'hasHistory',
|
|
52
112
|
type: 'boolean',
|
|
53
|
-
description:
|
|
113
|
+
description:
|
|
114
|
+
'Enable ArrowUp/Down to recall previously submitted messages.',
|
|
54
115
|
default: 'true',
|
|
55
116
|
},
|
|
56
117
|
{
|
|
@@ -62,28 +123,39 @@ export const docs = {
|
|
|
62
123
|
{
|
|
63
124
|
name: 'isDisabled',
|
|
64
125
|
type: 'boolean',
|
|
65
|
-
description:
|
|
126
|
+
description:
|
|
127
|
+
'Disables the input. Use during streaming or when a prerequisite is unmet.',
|
|
66
128
|
default: 'false',
|
|
67
129
|
},
|
|
68
130
|
{
|
|
69
131
|
name: 'onPaste',
|
|
70
|
-
type: '(event, text) => void',
|
|
71
|
-
description:
|
|
132
|
+
type: '(event, text) => boolean | void',
|
|
133
|
+
description:
|
|
134
|
+
'Called when plain text is pasted. Return true after handling the text yourself; otherwise ChatComposerInput inserts it or applies paste-as-token behavior.',
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
name: 'pasteAsToken',
|
|
138
|
+
type: 'UseChatPasteAsTokenReturn | false',
|
|
139
|
+
description:
|
|
140
|
+
'Paste-as-token behavior. By default, plain-text pastes over 200 characters become expandable tokens. Pass false to keep every text paste inline, or provide useChatPasteAsToken() to customize the conversion.',
|
|
72
141
|
},
|
|
73
142
|
{
|
|
74
143
|
name: 'onFiles',
|
|
75
144
|
type: '(files: File[]) => void',
|
|
76
|
-
description:
|
|
145
|
+
description:
|
|
146
|
+
'Called when files are pasted or dropped onto the input. Use to handle attachments.',
|
|
77
147
|
},
|
|
78
148
|
{
|
|
79
149
|
name: 'onSubmit',
|
|
80
150
|
type: '(value: string) => void',
|
|
81
|
-
description:
|
|
151
|
+
description:
|
|
152
|
+
'Called when the user presses Enter without Shift. The serialized value includes token placeholders.',
|
|
82
153
|
},
|
|
83
154
|
{
|
|
84
155
|
name: 'onKeyDown',
|
|
85
156
|
type: '(event) => void',
|
|
86
|
-
description:
|
|
157
|
+
description:
|
|
158
|
+
'Key-down handler invoked before the built-in Enter/history behavior (after any open trigger menu). The seam for platform-specific keys: call event.preventDefault() to suppress the default submit (e.g. newline on a touch keyboard), or act on the event yourself to add behavior (e.g. submit on Cmd/Ctrl+Enter). IME composition is always respected; Enter never submits mid-composition.',
|
|
87
159
|
},
|
|
88
160
|
],
|
|
89
161
|
};
|
|
@@ -92,22 +164,29 @@ export const docsZh = {
|
|
|
92
164
|
name: 'ChatComposerInput',
|
|
93
165
|
isHiddenFromOverview: true,
|
|
94
166
|
displayName: 'Chat Composer Input',
|
|
95
|
-
description:
|
|
167
|
+
description:
|
|
168
|
+
'聊天编写器的富文本输入。支持触发菜单(输入 @ 或 / 打开 typeahead)、内联标记徽章、ArrowUp/Down 消息历史回溯、粘贴/拖放文件处理,并在 iOS 上将字体大小保持至少 16px 以避免输入缩放。当需要普通文本区域以外的功能时,传入 ChatComposer 的 input 插槽。',
|
|
96
169
|
propDescriptions: {
|
|
97
|
-
handleRef:
|
|
170
|
+
handleRef:
|
|
171
|
+
'命令式句柄,用于编程式控制:insertToken、expandToken、insertText、focus 和 getValue。',
|
|
98
172
|
value: '受控输入值。与 onChange 配对实现双向绑定。',
|
|
99
173
|
onChange: '输入值变更时调用。序列化字符串包含标记占位符。',
|
|
100
174
|
placeholder: '输入为空时显示的占位文本。',
|
|
101
175
|
maxRows: '滚动前的最大可见行数。紧凑布局中使用较小值。',
|
|
102
|
-
triggers:
|
|
176
|
+
triggers:
|
|
177
|
+
'菜单的触发定义。每个触发器指定字符(@ 或 /)、搜索源和返回要插入标记的 onSelect 处理器。',
|
|
103
178
|
debounceMs: '异步搜索源的去抖动延迟,避免过多网络请求。',
|
|
104
179
|
hasHistory: '启用 ArrowUp/Down 回溯之前提交的消息。',
|
|
105
180
|
label: '屏幕阅读器播报的无障碍标签。',
|
|
106
181
|
isDisabled: '禁用输入。在流式输出期间或前置条件未满足时使用。',
|
|
107
|
-
onPaste:
|
|
182
|
+
onPaste:
|
|
183
|
+
'粘贴纯文本时调用。自行处理后返回 true;否则由 ChatComposerInput 插入文本或应用粘贴转标记行为。',
|
|
184
|
+
pasteAsToken:
|
|
185
|
+
'粘贴转标记行为。默认将超过 200 个字符的纯文本粘贴转为可展开标记;传入 false 可始终内联粘贴,或传入 useChatPasteAsToken() 结果来自定义转换。',
|
|
108
186
|
onFiles: '粘贴或拖放文件到输入时调用。用于处理附件。',
|
|
109
187
|
onSubmit: '用户不按 Shift 按 Enter 时调用。序列化值包含标记占位符。',
|
|
110
|
-
onKeyDown:
|
|
188
|
+
onKeyDown:
|
|
189
|
+
'在内置 Enter/历史处理之前(在打开的触发菜单之后)调用的按键处理器。平台特定按键的接缝:调用 event.preventDefault() 可抑制默认提交(例如触控键盘上插入换行),或自行处理事件以添加行为(例如 Cmd/Ctrl+Enter 提交)。始终尊重输入法组字状态——组字过程中 Enter 永不提交。',
|
|
111
190
|
},
|
|
112
191
|
};
|
|
113
192
|
|
|
@@ -115,21 +194,30 @@ export const docsDense = {
|
|
|
115
194
|
name: 'ChatComposerInput',
|
|
116
195
|
isHiddenFromOverview: true,
|
|
117
196
|
displayName: 'Chat Composer Input',
|
|
118
|
-
description:
|
|
197
|
+
description:
|
|
198
|
+
'rich input for composer; trigger menus (@/commands), inline tokens, msg history, paste/drop files, 16px iOS font-size floor to prevent zoom. Use in ChatComposer input slot when you need more than plain textarea.',
|
|
119
199
|
propDescriptions: {
|
|
120
|
-
handleRef:
|
|
200
|
+
handleRef:
|
|
201
|
+
'imperative handle (insertToken/expandToken/insertText/focus/getValue)',
|
|
121
202
|
value: 'controlled value; pair w/ onChange for two-way binding',
|
|
122
|
-
onChange:
|
|
203
|
+
onChange:
|
|
204
|
+
'value change handler; serialized string includes token placeholders',
|
|
123
205
|
placeholder: 'placeholder when empty',
|
|
124
206
|
maxRows: 'max visible rows before scroll; lower for compact layouts',
|
|
125
|
-
triggers:
|
|
207
|
+
triggers:
|
|
208
|
+
'typeahead trigger defs; character(@/)+searchSource+onSelect returning token',
|
|
126
209
|
debounceMs: 'debounce for async search to avoid excess requests',
|
|
127
210
|
hasHistory: 'ArrowUp/Down to recall previous submissions',
|
|
128
211
|
label: 'a11y label for screen readers',
|
|
129
212
|
isDisabled: 'disabled; use during streaming or unmet prereqs',
|
|
130
|
-
onPaste:
|
|
213
|
+
onPaste:
|
|
214
|
+
'plain-text paste callback; return true when handled, otherwise built-in token/plain insertion runs',
|
|
215
|
+
pasteAsToken:
|
|
216
|
+
'paste-as-token behavior; >200 chars by default, false for inline-only, or custom useChatPasteAsToken() result',
|
|
131
217
|
onFiles: 'file paste/drop handler; use for attachments',
|
|
132
|
-
onSubmit:
|
|
133
|
-
|
|
218
|
+
onSubmit:
|
|
219
|
+
'Enter w/o Shift handler; serialized value includes token placeholders',
|
|
220
|
+
onKeyDown:
|
|
221
|
+
'keydown handler before built-in Enter/history (after trigger menu); preventDefault() to suppress default submit (touch newline) or act on event to add behavior (Cmd/Ctrl+Enter). IME composition always respected',
|
|
134
222
|
},
|
|
135
223
|
};
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 3
|
|
3
|
+
template_version: 5
|
|
4
|
+
kind: component
|
|
5
|
+
id: component:ChatComposerInput
|
|
6
|
+
authority: draft
|
|
7
|
+
archive_reason: null
|
|
8
|
+
superseded_by: null
|
|
9
|
+
approved_by: null
|
|
10
|
+
approved_at: null
|
|
11
|
+
owners: [cixzhang]
|
|
12
|
+
review_triggers: [public-api, behavior, accessibility, interaction, theming]
|
|
13
|
+
verified_by:
|
|
14
|
+
[
|
|
15
|
+
packages/core/src/Chat/ChatComposerInput.test.tsx,
|
|
16
|
+
apps/storybook/stories/ChatComposerInput.stories.tsx,
|
|
17
|
+
apps/storybook/rtl-audit/verified-not-applicable.json,
|
|
18
|
+
]
|
|
19
|
+
modules: []
|
|
20
|
+
families: []
|
|
21
|
+
design_specs: []
|
|
22
|
+
architecture:
|
|
23
|
+
[
|
|
24
|
+
architecture:interaction-modality,
|
|
25
|
+
architecture:public-component-api,
|
|
26
|
+
architecture:knowledge-contracts,
|
|
27
|
+
]
|
|
28
|
+
contributing: []
|
|
29
|
+
system_specs: [spec:AST-002, spec:AST-029]
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
# ChatComposerInput component contract
|
|
33
|
+
|
|
34
|
+
## Contract at a glance
|
|
35
|
+
|
|
36
|
+
| Area | Contract |
|
|
37
|
+
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
38
|
+
| Public contract | No API or default change. ChatComposerInput remains the optional rich editing surface for ChatComposer, with controlled draft, trigger, history, paste, file, and imperative seams. |
|
|
39
|
+
| Behavior | Every edit path keeps the serialized draft observable. Files pasted or dropped reach `onFiles`; consumer `onPaste` receives first refusal over plain text before optional paste-as-token conversion. |
|
|
40
|
+
| End-user impact | Dictated or otherwise programmatically inserted text becomes sendable and does not remain hidden behind the empty placeholder; dropped files reach the product attachment flow. |
|
|
41
|
+
| Builder impact | Existing props, callback signatures, defaults, exports, and token serialization stay unchanged. Builders relying on the documented `onPaste` and `onFiles` paths now receive those callbacks consistently. |
|
|
42
|
+
| Compatibility/readiness | Patch-compatible correction to released behavior. This observational record adds no public concept or visual decision. |
|
|
43
|
+
| Review checks | Reject an edit path that mutates the DOM without updating the serialized draft, a file drop that can navigate away or bypass `onFiles`, a text paste that bypasses consumer interception, or changed submit/token semantics. |
|
|
44
|
+
| Governing rules | `architecture:public-component-api/INV1`; `architecture:interaction-modality/INV1–INV4`; `architecture:knowledge-contracts/INV11, INV16`; `spec:AST-002`; `spec:AST-029`; rubric B15. |
|
|
45
|
+
|
|
46
|
+
This table is a review projection; the body below is authoritative.
|
|
47
|
+
|
|
48
|
+
## Intent
|
|
49
|
+
|
|
50
|
+
ChatComposerInput supplies ChatComposer's rich editing surface when a plain custom
|
|
51
|
+
textarea is insufficient. It owns contenteditable text and selection, serialized
|
|
52
|
+
inline tokens, trigger menus, history recall, paste and file intake, and the
|
|
53
|
+
imperative editing handle.
|
|
54
|
+
|
|
55
|
+
## Compatibility and migration
|
|
56
|
+
|
|
57
|
+
- Released default preserved: yes
|
|
58
|
+
- Compatibility class: patch-compatible behavior correction; no public type or default changes
|
|
59
|
+
- Controlled and composition behavior: unchanged
|
|
60
|
+
- Migration decision: none
|
|
61
|
+
|
|
62
|
+
## Ownership boundary
|
|
63
|
+
|
|
64
|
+
**Owns**
|
|
65
|
+
|
|
66
|
+
- The contenteditable surface, its accessible editing semantics, and serialization.
|
|
67
|
+
- Trigger-menu invocation and token insertion inside the editor.
|
|
68
|
+
- Enter submission, history navigation, paste precedence, file intake, and imperative edit observability.
|
|
69
|
+
- Registration of the editing focus control with ChatComposer.
|
|
70
|
+
|
|
71
|
+
**Does not own / non-goals**
|
|
72
|
+
|
|
73
|
+
- ChatComposer layout, send-button state, status placement, or shell elevation.
|
|
74
|
+
- Product validation, upload, progress, or error handling for files.
|
|
75
|
+
- Search result data, custom token meaning, or custom token interaction semantics supplied by callers.
|
|
76
|
+
- A new visual representation for the editor, token, menu, or drop target.
|
|
77
|
+
|
|
78
|
+
## Public concepts
|
|
79
|
+
|
|
80
|
+
| Concept | Closed values or states | Meaning | Availability by state | Default | Owner | Stability | Invalid-value behavior |
|
|
81
|
+
| ------------------ | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ------------------------------- | --------------------------- | ----------------------------- | --------- | --------------------------------------------------------------------- |
|
|
82
|
+
| draft storage | DOM-owned; `value` controlled; ChatComposer context controlled | Selects the serialized draft source and observable change channel. | every editor | context or empty DOM | `component:ChatComposerInput` | stable | Explicit `value` wins; unsupported values are rejected by TypeScript. |
|
|
83
|
+
| submission | Enter; Shift+Enter; IME Enter; consumer-cancelled Enter | Submits one trimmed non-empty draft only on uncancelled Enter without Shift or composition. | enabled editor | Enter submits | `component:ChatComposerInput` | stable | Empty or composing submission is ignored. |
|
|
84
|
+
| trigger menu | omitted; one or more trigger definitions | Opens suggestions at a configured character and inserts text or a serialized token. | when triggers are configured | omitted | `component:ChatComposerInput` | stable | Unknown trigger characters remain ordinary text. |
|
|
85
|
+
| history | enabled; disabled | Recalls submitted drafts at text boundaries with ArrowUp and ArrowDown. | when enabled and history exists | enabled | `component:ChatComposerInput` | stable | Mid-text arrow keys retain native caret behavior. |
|
|
86
|
+
| text paste | consumer-handled; paste-as-token; plain text | Gives `onPaste` first refusal, then optional token conversion, then inserts plain text. | enabled editor | long-paste token conversion | `component:ChatComposerInput` | stable | A handled callback stops later insertion paths. |
|
|
87
|
+
| file intake | pasted; dropped | Prevents browser navigation and passes the files to `onFiles`. | when files are supplied | no callback | `component:ChatComposerInput` | stable | Empty drops do nothing; disabled input does not emit files. |
|
|
88
|
+
| imperative editing | insert token; expand token; insert text; focus; get value | Lets composing features such as dictation operate through the editor's owned behavior. | while mounted | none | `component:ChatComposerInput` | stable | Calls without a mounted editor are no-ops or return an empty value. |
|
|
89
|
+
|
|
90
|
+
## Behavioral and layout contract
|
|
91
|
+
|
|
92
|
+
| ID | Candidate invariant | Basis | Draft review state |
|
|
93
|
+
| --- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | ------------------ |
|
|
94
|
+
| FR1 | Every user or imperative edit that changes serialized content MUST update empty state and emit the effective value through the active `onChange` channel. | Shipped `onChange` contract, imperative handle, and ChatDictation callsite. | settled |
|
|
95
|
+
| FR2 | Enter without Shift MUST submit one trimmed non-empty draft and clear it unless the event is composing, the trigger menu consumes it, or a consumer prevents default. | Shipped implementation and consumer docs. | verify |
|
|
96
|
+
| FR3 | Shift+Enter and mid-text history arrows MUST retain native multiline editing behavior. | Shipped implementation and focused tests. | verify |
|
|
97
|
+
| FR4 | `value` supplied directly on ChatComposerInput MUST win over ChatComposer context, while an emitted echo MUST NOT rebuild the DOM or move the caret. | Shipped controlled precedence and regression tests. | verify |
|
|
98
|
+
| FR5 | Plain-text paste precedence MUST be consumer `onPaste` → configured/default paste-as-token → plain insertion. | Public callback meaning and objective callback composition. | settled |
|
|
99
|
+
| FR6 | File paste and file drop MUST prevent native insertion/navigation and deliver the same ordered `File[]` to `onFiles`; disabled editors MUST NOT emit file callbacks. | Shipped public `onFiles` contract and consumer docs. | settled |
|
|
100
|
+
| FR7 | Trigger-menu keyboard handling MUST run before consumer and built-in editor handling; IME composition MUST never submit. | Shipped interaction contract and tests. | verify |
|
|
101
|
+
| FR8 | History recall MUST operate only at the draft boundaries and MUST restore the pending draft after stepping past the newest item. | Shipped behavior and tests. | verify |
|
|
102
|
+
| FR9 | The root MUST keep forwarding its ref, BaseProps attributes, and styling seams; the imperative handle remains separate in `handleRef`. | Released public API and `architecture:public-component-api`. | verify |
|
|
103
|
+
|
|
104
|
+
### Allowed variation
|
|
105
|
+
|
|
106
|
+
- **AV1 — Search content.** Builders own trigger characters, search sources, item rendering, and inserted values.
|
|
107
|
+
- **AV2 — Token content.** Builders may use the structured Badge form or the custom render escape hatch and own custom semantics.
|
|
108
|
+
- **AV3 — Product file workflow.** Builders own accepted types, validation, upload, progress, and errors after `onFiles` receives the files.
|
|
109
|
+
|
|
110
|
+
### Representative states
|
|
111
|
+
|
|
112
|
+
| State | Required invariant | Allowed variation |
|
|
113
|
+
| ----------------------------------- | ------------------------------------------------------------------------------------------------------ | -------------------------------------- |
|
|
114
|
+
| empty | Placeholder is visible and the serialized value is empty. | Placeholder copy. |
|
|
115
|
+
| typed or imperatively inserted text | Placeholder is absent and the same serialized value is observable to ChatComposer and callbacks. | Draft content. |
|
|
116
|
+
| controlled update | External value is reflected without corrupting a live caret or treating a stale echo as authoritative. | Parent update timing. |
|
|
117
|
+
| trigger menu open | Combobox semantics and active option wiring are exposed; menu interaction owns its keys. | Search source and item rendering. |
|
|
118
|
+
| file paste or drop | Native insertion/navigation is prevented and files reach `onFiles` once. | File types and product handling. |
|
|
119
|
+
| disabled | Editing and file callbacks are unavailable and disabled state is exposed. | Product reason and surrounding status. |
|
|
120
|
+
|
|
121
|
+
### Transformation and precedence order
|
|
122
|
+
|
|
123
|
+
- **ORD1 — Draft source.** Explicit `value` → ChatComposer context value → editor DOM.
|
|
124
|
+
- **ORD2 — Change channel.** Explicit controlled input callback when `value` is explicit → ChatComposer context callback → distinct local callback.
|
|
125
|
+
- **ORD3 — Key handling.** Trigger menu → consumer `onKeyDown` → IME/submit/history behavior.
|
|
126
|
+
- **ORD4 — Plain paste.** Consumer `onPaste` → paste-as-token behavior → plain insertion.
|
|
127
|
+
- **ORD5 — File intake.** Files on clipboard or data transfer → prevent native behavior → emit `onFiles` when enabled.
|
|
128
|
+
|
|
129
|
+
### Performance and resources
|
|
130
|
+
|
|
131
|
+
- **PR1 — Selection work.** Selection reads and writes are scoped to the mounted editable and run only for direct editing actions or controlled synchronization.
|
|
132
|
+
- **PR2 — Async trigger work.** Search cancellation and debounce ownership remain in `useTriggerMenu` and the supplied `SearchSource`.
|
|
133
|
+
- **PR3 — Portal cleanup.** Token portals are cleaned through the existing token hook when content changes or unmounts.
|
|
134
|
+
|
|
135
|
+
## Accessibility contract
|
|
136
|
+
|
|
137
|
+
- **AR1 — Editing semantics.** Without triggers, the surface is a named multiline textbox; with triggers, it exposes the adopted combobox semantics without invalid multiline ARIA.
|
|
138
|
+
- **AR2 — Disabled state.** Disabled editing is exposed with `aria-disabled` and cannot accept content or file callbacks.
|
|
139
|
+
- **AR3 — Keyboard ownership.** IME, trigger-menu keys, consumer cancellation, Enter submission, and boundary-only history do not steal one another's keys.
|
|
140
|
+
- **AR4 — Focus visibility.** When composed in ChatComposer, the semantic editor focus owner drives the shell's shared keyboard focus indicator.
|
|
141
|
+
|
|
142
|
+
## Design relationships
|
|
143
|
+
|
|
144
|
+
| Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
|
|
145
|
+
| ---------------- | ---------------------------------- | ------------------------ | -------------- | ------------------ |
|
|
146
|
+
| input root | existing themed target | observed implementation | supporting | FR9 |
|
|
147
|
+
| editable surface | ordinary composer editing surface | ChatComposer family | prominent | FR1–FR4, AR1–AR4 |
|
|
148
|
+
| placeholder | secondary text while empty | current token role | supporting | FR1 |
|
|
149
|
+
| trigger menu | delegated Typeahead behavior | Typeahead owner | floating | FR7 |
|
|
150
|
+
| inline token | structured Badge or caller content | Badge or caller owner | supporting | AV2 |
|
|
151
|
+
|
|
152
|
+
The existing `chat-composer-input` target remains on the root. This observational
|
|
153
|
+
draft does not add a theming target or decide a new visual state.
|
|
154
|
+
|
|
155
|
+
## Family and system relationships
|
|
156
|
+
|
|
157
|
+
- `component:ChatComposer` owns layout, submission orchestration, send state, and the shell focus ring; this component owns the editing surface and its change channel.
|
|
158
|
+
- Typeahead and SearchSource own result collection behavior; ChatComposerInput owns when the trigger menu participates in editor key precedence.
|
|
159
|
+
- `architecture:interaction-modality` owns the shared focus-visibility mechanics.
|
|
160
|
+
- `spec:AST-029` owns the observational audit-backfill boundary.
|
|
161
|
+
|
|
162
|
+
## Verification map
|
|
163
|
+
|
|
164
|
+
| Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
|
|
165
|
+
| --------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | --------------------------------------- |
|
|
166
|
+
| FR1, ORD1–ORD2 | focused imperative insertion and controlled-sync tests; `ImperativeInsertion` play | empty → inserted text; controlled echo; external override | Text appears only in the DOM, placeholder remains, callback is stale, or the caret jumps. | `audit:ChatComposerInput/behavior` |
|
|
167
|
+
| FR2–FR3, FR7–FR8, AR3 | focused keyboard, IME, trigger, and history tests | Enter; Shift+Enter; composition; cancelled key; boundary and mid-text arrows | A key submits twice, submits during composition, or steals native editing. | `audit:ChatComposerInput/interaction` |
|
|
168
|
+
| FR5, ORD4 | focused long-paste interception tests | consumer handled; token conversion; plain insertion | Consumer interception is skipped or multiple insertion paths run. | `audit:ChatComposerInput/behavior` |
|
|
169
|
+
| FR6, ORD5, AR2 | focused paste/drop tests and `FileDrop` play | paste; drop; disabled | Files navigate away, insert into the editor, bypass `onFiles`, or emit while disabled. | `audit:ChatComposerInput/behavior` |
|
|
170
|
+
| AR1, AR4 | role/name/ARIA tests plus exact-head accessibility and visual gates | textbox; combobox; disabled; keyboard focus | Name, role, multiline, expanded, disabled, or visible focus semantics regress. | `audit:ChatComposerInput/accessibility` |
|
|
171
|
+
| FR9 | ref, target, package, and repository checks | ref; BaseProps; xstyle; className; style | Root ownership or a styling seam moves or disappears. | `audit:ChatComposerInput/api` |
|
|
172
|
+
|
|
173
|
+
## Decision log
|
|
174
|
+
|
|
175
|
+
No component-local policy decision is created by this observational draft.
|
|
176
|
+
|
|
177
|
+
## Open questions
|
|
178
|
+
|
|
179
|
+
None.
|
|
180
|
+
|
|
181
|
+
## Content boundary
|
|
182
|
+
|
|
183
|
+
This file does not duplicate consumer prop tables, examples, current audit scores,
|
|
184
|
+
or visual design rationale. It records shipped behavior and objective corrections
|
|
185
|
+
without expanding the public API or deciding a new visual representation.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
3
|
import {describe, it, expect, vi, afterEach} from 'vitest';
|
|
4
|
-
import {render, screen, fireEvent, waitFor} from '@testing-library/react';
|
|
4
|
+
import {render, screen, fireEvent, waitFor, act} from '@testing-library/react';
|
|
5
5
|
import userEvent from '@testing-library/user-event';
|
|
6
6
|
import {ChatComposer} from './ChatComposer';
|
|
7
7
|
import {useChatComposerContext} from './ChatContext';
|
|
@@ -570,6 +570,33 @@ describe('ChatComposerInput', () => {
|
|
|
570
570
|
});
|
|
571
571
|
expect(onFiles).toHaveBeenCalledWith([file]);
|
|
572
572
|
});
|
|
573
|
+
|
|
574
|
+
it('calls onFiles when files are dropped onto the editor', () => {
|
|
575
|
+
const onFiles = vi.fn();
|
|
576
|
+
render(<ChatComposerInput onFiles={onFiles} />);
|
|
577
|
+
const textbox = screen.getByRole('textbox');
|
|
578
|
+
const file = new File(['content'], 'dropped.txt', {type: 'text/plain'});
|
|
579
|
+
|
|
580
|
+
const allowed = fireEvent.drop(textbox, {
|
|
581
|
+
dataTransfer: {files: [file], types: ['Files']},
|
|
582
|
+
});
|
|
583
|
+
expect(allowed).toBe(false);
|
|
584
|
+
expect(onFiles).toHaveBeenCalledWith([file]);
|
|
585
|
+
});
|
|
586
|
+
|
|
587
|
+
it('does not emit dropped files while disabled', () => {
|
|
588
|
+
const onFiles = vi.fn();
|
|
589
|
+
render(<ChatComposerInput isDisabled onFiles={onFiles} />);
|
|
590
|
+
const textbox = screen.getByRole('textbox');
|
|
591
|
+
const file = new File(['content'], 'blocked.txt', {type: 'text/plain'});
|
|
592
|
+
|
|
593
|
+
const allowed = fireEvent.drop(textbox, {
|
|
594
|
+
dataTransfer: {files: [file], types: ['Files']},
|
|
595
|
+
});
|
|
596
|
+
|
|
597
|
+
expect(allowed).toBe(false);
|
|
598
|
+
expect(onFiles).not.toHaveBeenCalled();
|
|
599
|
+
});
|
|
573
600
|
});
|
|
574
601
|
|
|
575
602
|
// Paste / insert paths used to bail silently when the contenteditable
|
|
@@ -651,10 +678,13 @@ describe('ChatComposerInput', () => {
|
|
|
651
678
|
expect(textbox.querySelector('[data-astryx-token]')).toBeInTheDocument();
|
|
652
679
|
});
|
|
653
680
|
|
|
654
|
-
it('imperative insertText
|
|
681
|
+
it('imperative insertText updates the observable draft after a focus() with no selection range', () => {
|
|
655
682
|
let handle: ChatComposerInputHandle | null = null;
|
|
683
|
+
const onChange = vi.fn();
|
|
656
684
|
render(
|
|
657
685
|
<ChatComposerInput
|
|
686
|
+
placeholder="Write a message"
|
|
687
|
+
onChange={onChange}
|
|
658
688
|
handleRef={h => {
|
|
659
689
|
handle = h;
|
|
660
690
|
}}
|
|
@@ -665,8 +695,12 @@ describe('ChatComposerInput', () => {
|
|
|
665
695
|
textbox.focus();
|
|
666
696
|
clearSelection();
|
|
667
697
|
|
|
668
|
-
handle!.insertText('hello');
|
|
698
|
+
act(() => handle!.insertText('hello'));
|
|
699
|
+
|
|
669
700
|
expect(textbox.textContent).toContain('hello');
|
|
701
|
+
expect(onChange).toHaveBeenCalledTimes(1);
|
|
702
|
+
expect(onChange).toHaveBeenLastCalledWith('hello');
|
|
703
|
+
expect(screen.queryByText('Write a message')).not.toBeInTheDocument();
|
|
670
704
|
});
|
|
671
705
|
|
|
672
706
|
// History recall reads where the caret sits, so where a programmatic
|
|
@@ -976,6 +1010,60 @@ describe('ChatComposerInput', () => {
|
|
|
976
1010
|
});
|
|
977
1011
|
});
|
|
978
1012
|
|
|
1013
|
+
it('lets onPaste intercept long text before default token conversion', () => {
|
|
1014
|
+
const onPaste = vi.fn(() => true);
|
|
1015
|
+
render(<ChatComposerInput onPaste={onPaste} />);
|
|
1016
|
+
const textbox = screen.getByRole('textbox');
|
|
1017
|
+
textbox.focus();
|
|
1018
|
+
clearSelection();
|
|
1019
|
+
const long = 'c'.repeat(250);
|
|
1020
|
+
|
|
1021
|
+
fireEvent.paste(textbox, {
|
|
1022
|
+
clipboardData: {
|
|
1023
|
+
files: [],
|
|
1024
|
+
getData: (type: string) => (type === 'text/plain' ? long : ''),
|
|
1025
|
+
},
|
|
1026
|
+
});
|
|
1027
|
+
|
|
1028
|
+
expect(onPaste).toHaveBeenCalledWith(expect.anything(), long);
|
|
1029
|
+
expect(
|
|
1030
|
+
textbox.querySelector('[data-astryx-token]'),
|
|
1031
|
+
).not.toBeInTheDocument();
|
|
1032
|
+
expect(textbox.textContent).toBe('');
|
|
1033
|
+
});
|
|
1034
|
+
|
|
1035
|
+
it('emits once when onPaste inserts through the imperative handle', () => {
|
|
1036
|
+
let handle: ChatComposerInputHandle | null = null;
|
|
1037
|
+
const onChange = vi.fn();
|
|
1038
|
+
const onPaste = vi.fn((_event: unknown, text: string) => {
|
|
1039
|
+
handle!.insertText(text);
|
|
1040
|
+
return true;
|
|
1041
|
+
});
|
|
1042
|
+
render(
|
|
1043
|
+
<ChatComposerInput
|
|
1044
|
+
handleRef={next => {
|
|
1045
|
+
handle = next;
|
|
1046
|
+
}}
|
|
1047
|
+
onChange={onChange}
|
|
1048
|
+
onPaste={onPaste}
|
|
1049
|
+
/>,
|
|
1050
|
+
);
|
|
1051
|
+
const textbox = screen.getByRole('textbox');
|
|
1052
|
+
textbox.focus();
|
|
1053
|
+
clearSelection();
|
|
1054
|
+
|
|
1055
|
+
fireEvent.paste(textbox, {
|
|
1056
|
+
clipboardData: {
|
|
1057
|
+
files: [],
|
|
1058
|
+
getData: (type: string) => (type === 'text/plain' ? 'hello' : ''),
|
|
1059
|
+
},
|
|
1060
|
+
});
|
|
1061
|
+
|
|
1062
|
+
expect(textbox.textContent).toBe('hello');
|
|
1063
|
+
expect(onChange).toHaveBeenCalledTimes(1);
|
|
1064
|
+
expect(onChange).toHaveBeenCalledWith('hello');
|
|
1065
|
+
});
|
|
1066
|
+
|
|
979
1067
|
it('paste falls through to plain-text path when pasteAsToken={false}', () => {
|
|
980
1068
|
const onChange = vi.fn();
|
|
981
1069
|
render(<ChatComposerInput pasteAsToken={false} onChange={onChange} />);
|
|
@@ -1394,6 +1482,28 @@ describe('ChatComposerInput', () => {
|
|
|
1394
1482
|
|
|
1395
1483
|
expect(textbox.getAttribute('aria-expanded')).toBe('true');
|
|
1396
1484
|
});
|
|
1485
|
+
|
|
1486
|
+
it('emits once when a string trigger result is selected', async () => {
|
|
1487
|
+
const {textbox, onChange} = setupTriggerInput([createCommandTrigger()]);
|
|
1488
|
+
|
|
1489
|
+
setCursorAfterText(textbox, '/');
|
|
1490
|
+
fireEvent.input(textbox);
|
|
1491
|
+
await waitFor(() => {
|
|
1492
|
+
const menu = document.getElementById(
|
|
1493
|
+
textbox.getAttribute('aria-controls')!,
|
|
1494
|
+
);
|
|
1495
|
+
expect(
|
|
1496
|
+
menu?.querySelectorAll('[role="option"]').length ?? 0,
|
|
1497
|
+
).toBeGreaterThan(0);
|
|
1498
|
+
});
|
|
1499
|
+
onChange.mockClear();
|
|
1500
|
+
|
|
1501
|
+
fireEvent.keyDown(textbox, {key: 'Enter'});
|
|
1502
|
+
|
|
1503
|
+
expect(textbox.textContent).toBe('/summarize ');
|
|
1504
|
+
expect(onChange).toHaveBeenCalledTimes(1);
|
|
1505
|
+
expect(onChange).toHaveBeenCalledWith('/summarize ');
|
|
1506
|
+
});
|
|
1397
1507
|
});
|
|
1398
1508
|
|
|
1399
1509
|
describe('trigger menu hover scrolling', () => {
|