@astryxdesign/core 0.7.1-canary.ff40b78 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +116 -0
- package/dist/Button/Button.d.ts +1 -1
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +5 -2
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +191 -32
- package/dist/Chat/ChatComposerInput.d.ts +9 -0
- package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
- package/dist/Chat/ChatComposerInput.js +5 -0
- package/dist/Chat/ChatMessage.d.ts +11 -0
- package/dist/Chat/ChatMessage.d.ts.map +1 -1
- package/dist/Chat/ChatMessage.js +18 -9
- package/dist/Chat/useTriggerMenu.d.ts +9 -2
- package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
- package/dist/Chat/useTriggerMenu.js +222 -50
- package/dist/CodeBlock/CodeBlock.d.ts +10 -1
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +158 -38
- package/dist/CodeBlock/tokenizer.d.ts +39 -0
- package/dist/CodeBlock/tokenizer.d.ts.map +1 -1
- package/dist/CodeBlock/tokenizer.js +108 -0
- package/dist/CommandPalette/CommandPalette.d.ts +9 -5
- package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPalette.js +38 -20
- package/dist/CommandPalette/CommandPaletteEmpty.d.ts +4 -3
- package/dist/CommandPalette/CommandPaletteEmpty.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteEmpty.js +4 -3
- package/dist/CommandPalette/CommandPaletteInput.d.ts +5 -4
- package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteInput.js +35 -18
- package/dist/CommandPalette/CommandPaletteItem.d.ts +11 -6
- package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteItem.js +8 -9
- package/dist/CommandPalette/CommandPaletteList.d.ts +4 -2
- package/dist/CommandPalette/CommandPaletteList.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteList.js +10 -5
- package/dist/ComplexSelector/ComplexSelector.d.ts +8 -5
- package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
- package/dist/ComplexSelector/ComplexSelector.js +12 -3
- package/dist/ContextMenu/ContextMenu.d.ts +3 -3
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +62 -48
- package/dist/DateInput/DateInput.js +1 -1
- package/dist/DateInput/MonthScroller.d.ts.map +1 -1
- package/dist/DateInput/MonthScroller.js +12 -4
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +12 -2
- package/dist/Dialog/Dialog.d.ts +1 -1
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +16 -5
- package/dist/Dialog/DialogHeader.d.ts +1 -1
- package/dist/Dialog/DialogHeader.d.ts.map +1 -1
- package/dist/Dialog/DialogHeader.js +7 -7
- package/dist/Divider/Divider.d.ts +1 -0
- package/dist/Divider/Divider.d.ts.map +1 -1
- package/dist/Divider/Divider.js +5 -4
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +161 -65
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +7 -5
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +12 -5
- package/dist/Field/InputClearButton.d.ts +8 -4
- package/dist/Field/InputClearButton.d.ts.map +1 -1
- package/dist/Field/InputClearButton.js +23 -7
- package/dist/FormLayout/FormLayout.d.ts.map +1 -1
- package/dist/FormLayout/FormLayout.js +1 -0
- package/dist/Grid/Grid.d.ts +13 -4
- package/dist/Grid/Grid.d.ts.map +1 -1
- package/dist/Grid/Grid.js +7 -1
- package/dist/HoverCard/useHoverCard.d.ts +1 -1
- package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
- package/dist/HoverCard/useHoverCard.js +67 -49
- package/dist/InputGroup/InputGroup.d.ts +2 -4
- package/dist/InputGroup/InputGroup.d.ts.map +1 -1
- package/dist/InputGroup/InputGroup.js +2 -4
- package/dist/InputGroup/groupStyles.d.ts +10 -2
- package/dist/InputGroup/groupStyles.d.ts.map +1 -1
- package/dist/InputGroup/groupStyles.js +19 -2
- package/dist/Layer/useLayerDismissal.d.ts +9 -9
- package/dist/Layer/useLayerDismissal.js +9 -9
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.js +25 -4
- package/dist/MobileNav/MobileNav.d.ts +7 -0
- package/dist/MobileNav/MobileNav.d.ts.map +1 -1
- package/dist/MobileNav/MobileNav.js +45 -2
- package/dist/MultiSelector/MultiSelector.d.ts +7 -4
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +24 -3
- package/dist/NumberInput/NumberInput.js +1 -1
- package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchEditPopover.js +6 -0
- package/dist/Resizable/ResizeHandle.d.ts +1 -1
- package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
- package/dist/Resizable/ResizeHandle.js +83 -15
- package/dist/Resizable/useResizable.d.ts +23 -0
- package/dist/Resizable/useResizable.d.ts.map +1 -1
- package/dist/Resizable/useResizable.js +78 -0
- package/dist/Selector/Selector.d.ts +6 -3
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +28 -6
- package/dist/SideNav/SideNav.d.ts.map +1 -1
- package/dist/SideNav/SideNav.js +10 -2
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +18 -7
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +16 -4
- package/dist/Toolbar/Toolbar.d.ts +2 -1
- package/dist/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/Toolbar/Toolbar.js +3 -1
- package/dist/TreeList/TreeList.d.ts.map +1 -1
- package/dist/TreeList/TreeList.js +6 -3
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +7 -1
- package/dist/astryx.css +22 -0
- package/dist/hooks/useScrollOverflow.d.ts.map +1 -1
- package/dist/hooks/useScrollOverflow.js +55 -12
- package/dist/hooks/useTreeFocus.d.ts +21 -0
- package/dist/hooks/useTreeFocus.d.ts.map +1 -1
- package/dist/hooks/useTreeFocus.js +40 -2
- package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/en.generated.js +3 -0
- package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/pseudo.generated.js +3 -0
- package/dist/reset.a11y.chromium.spec.js +6 -1
- package/dist/reset.until-found.a11y.browser.spec.d.ts +2 -0
- package/dist/reset.until-found.a11y.browser.spec.d.ts.map +1 -0
- package/dist/reset.until-found.a11y.browser.spec.js +71 -0
- package/dist/theme/syntax/SyntaxTheme.d.ts.map +1 -1
- package/dist/theme/syntax/SyntaxTheme.js +43 -2
- package/dist/theme/syntax/defineSyntaxTheme.d.ts +18 -5
- package/dist/theme/syntax/defineSyntaxTheme.d.ts.map +1 -1
- package/dist/theme/syntax/defineSyntaxTheme.js +38 -9
- package/dist/theme/syntax/index.d.ts +1 -1
- package/dist/theme/syntax/index.d.ts.map +1 -1
- package/dist/theme/syntax/tokens.d.ts +12 -2
- package/dist/theme/syntax/tokens.d.ts.map +1 -1
- package/dist/theme/syntax/tokens.js +25 -4
- package/dist/utils/plainDate.d.ts +12 -0
- package/dist/utils/plainDate.d.ts.map +1 -1
- package/dist/utils/plainDate.js +63 -10
- package/locales/en.json +13 -1
- package/locales/pseudo.json +9 -0
- package/package.json +4 -4
- package/src/AlertDialog/AlertDialog.doc.mjs +6 -0
- package/src/AlertDialog/AlertDialog.spec.md +205 -0
- package/src/AlertDialog/AlertDialog.test.tsx +3 -14
- package/src/AlertDialog/__tests__/AlertDialog.a11y.chromium.spec.ts +115 -0
- package/src/AlertDialog/__tests__/AlertDialog.a11y.renders.tsx +52 -0
- package/src/AlertDialog/__tests__/AlertDialog.a11y.states.ts +68 -0
- package/src/AlertDialog/__tests__/AlertDialog.a11y.test.tsx +144 -0
- package/src/Button/Button.test.tsx +37 -0
- package/src/Button/Button.tsx +5 -1
- package/src/Calendar/Calendar.doc.mjs +234 -60
- package/src/Calendar/Calendar.spec.md +209 -0
- package/src/Calendar/Calendar.test.tsx +559 -20
- package/src/Calendar/Calendar.tsx +258 -41
- package/src/Calendar/__tests__/Calendar.a11y.chromium.spec.ts +126 -0
- package/src/Calendar/__tests__/Calendar.a11y.known-failures.ts +12 -0
- package/src/Calendar/__tests__/Calendar.a11y.renders.tsx +57 -0
- package/src/Calendar/__tests__/Calendar.a11y.states.ts +139 -0
- package/src/Calendar/__tests__/Calendar.a11y.test.tsx +137 -0
- package/src/Carousel/Carousel.test.tsx +54 -71
- package/src/Carousel/__tests__/Carousel.a11y.chromium.spec.ts +192 -0
- package/src/Carousel/__tests__/Carousel.a11y.known-failures.ts +27 -0
- package/src/Carousel/__tests__/Carousel.a11y.renders.tsx +39 -0
- package/src/Carousel/__tests__/Carousel.a11y.states.ts +139 -0
- package/src/Carousel/__tests__/Carousel.a11y.test.tsx +127 -0
- package/src/Chat/ChatComposerInput.doc.mjs +1 -1
- package/src/Chat/ChatComposerInput.spec.md +94 -55
- package/src/Chat/ChatComposerInput.test.tsx +202 -1
- package/src/Chat/ChatComposerInput.tsx +13 -0
- package/src/Chat/ChatMessage.doc.mjs +31 -16
- package/src/Chat/ChatMessage.spec.md +265 -0
- package/src/Chat/ChatMessage.test.tsx +246 -0
- package/src/Chat/ChatMessage.tsx +30 -7
- package/src/Chat/ChatSystemMessage.spec.md +36 -37
- package/src/Chat/ChatSystemMessage.test.tsx +4 -4
- package/src/Chat/useTriggerMenu.test.tsx +994 -0
- package/src/Chat/useTriggerMenu.tsx +278 -46
- package/src/CodeBlock/CodeBlock.doc.mjs +7 -0
- package/src/CodeBlock/CodeBlock.spec.md +40 -41
- package/src/CodeBlock/CodeBlock.test.tsx +89 -9
- package/src/CodeBlock/CodeBlock.tsx +205 -25
- package/src/CodeBlock/__tests__/CodeBlockOverflowStop.a11y.chromium.spec.ts +125 -0
- package/src/CodeBlock/__tests__/DiffRowPaint.a11y.chromium.spec.ts +93 -0
- package/src/CodeBlock/tokenizer.test.ts +112 -0
- package/src/CodeBlock/tokenizer.ts +106 -0
- package/src/Collapsible/CollapsibleGroup.spec.md +17 -8
- package/src/Collapsible/__tests__/CollapsibleGroup.a11y.renders.tsx +45 -0
- package/src/Collapsible/__tests__/CollapsibleGroup.a11y.states.ts +139 -0
- package/src/Collapsible/__tests__/CollapsibleGroup.a11y.test.tsx +135 -0
- package/src/Collapsible/__tests__/CollapsibleGroupAccordion.a11y.chromium.spec.ts +128 -0
- package/src/CommandPalette/CommandPalette.doc.mjs +126 -23
- package/src/CommandPalette/CommandPalette.spec.md +100 -49
- package/src/CommandPalette/CommandPalette.test.tsx +241 -2
- package/src/CommandPalette/CommandPalette.tsx +47 -21
- package/src/CommandPalette/CommandPaletteEmpty.tsx +4 -3
- package/src/CommandPalette/CommandPaletteInput.doc.mjs +61 -4
- package/src/CommandPalette/CommandPaletteInput.spec.md +215 -0
- package/src/CommandPalette/CommandPaletteInput.test.tsx +375 -51
- package/src/CommandPalette/CommandPaletteInput.tsx +74 -21
- package/src/CommandPalette/CommandPaletteItem.doc.mjs +73 -22
- package/src/CommandPalette/CommandPaletteItem.spec.md +223 -0
- package/src/CommandPalette/CommandPaletteItem.test.tsx +200 -5
- package/src/CommandPalette/CommandPaletteItem.tsx +16 -11
- package/src/CommandPalette/CommandPaletteList.doc.mjs +3 -3
- package/src/CommandPalette/CommandPaletteList.spec.md +41 -36
- package/src/CommandPalette/CommandPaletteList.test.tsx +80 -0
- package/src/CommandPalette/CommandPaletteList.tsx +10 -5
- package/src/CommandPalette/__tests__/CommandPalette.a11y.chromium.spec.ts +599 -0
- package/src/ComplexSelector/ComplexSelector.doc.mjs +10 -8
- package/src/ComplexSelector/ComplexSelector.spec.md +14 -9
- package/src/ComplexSelector/ComplexSelector.test.tsx +64 -16
- package/src/ComplexSelector/ComplexSelector.tsx +37 -8
- package/src/ContextMenu/ContextMenu.doc.mjs +6 -0
- package/src/ContextMenu/ContextMenu.spec.md +51 -53
- package/src/ContextMenu/ContextMenu.test.tsx +132 -1
- package/src/ContextMenu/ContextMenu.tsx +78 -48
- package/src/DateInput/DateInput.doc.mjs +52 -0
- package/src/DateInput/DateInput.spec.md +27 -15
- package/src/DateInput/DateInput.test.tsx +38 -0
- package/src/DateInput/DateInput.tsx +1 -1
- package/src/DateInput/DateInputTouch.test.tsx +22 -0
- package/src/DateInput/MonthScroller.tsx +12 -4
- package/src/DateRangeInput/DateRangeInput.test.tsx +49 -0
- package/src/DateRangeInput/DateRangeInput.tsx +20 -2
- package/src/Dialog/Dialog.test.tsx +27 -1
- package/src/Dialog/Dialog.tsx +16 -5
- package/src/Dialog/DialogHeader.test.tsx +27 -2
- package/src/Dialog/DialogHeader.tsx +7 -8
- package/src/Dialog/__tests__/Dialog.a11y.chromium.spec.ts +21 -14
- package/src/Divider/Divider.doc.mjs +5 -3
- package/src/Divider/Divider.spec.md +140 -54
- package/src/Divider/Divider.test.tsx +15 -0
- package/src/Divider/Divider.tsx +6 -4
- package/src/DropdownMenu/DropdownMenu.doc.mjs +2 -2
- package/src/DropdownMenu/DropdownMenu.spec.md +121 -45
- package/src/DropdownMenu/DropdownMenu.test.tsx +288 -23
- package/src/DropdownMenu/DropdownMenu.tsx +212 -81
- package/src/DropdownMenu/DropdownMenuCheckboxItem.doc.mjs +38 -2
- package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +32 -18
- package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +146 -1
- package/src/DropdownMenu/__tests__/MenuButton.a11y.chromium.spec.ts +136 -0
- package/src/DropdownMenu/__tests__/MenuButton.a11y.known-failures.ts +12 -0
- package/src/DropdownMenu/__tests__/MenuButton.a11y.renders.tsx +67 -0
- package/src/DropdownMenu/__tests__/MenuButton.a11y.states.ts +141 -0
- package/src/DropdownMenu/__tests__/MenuButton.a11y.test.tsx +138 -0
- package/src/DropdownMenu/__tests__/MenuHeaderFooter.a11y.chromium.spec.ts +40 -5
- package/src/Field/InputClearButton.test.tsx +29 -4
- package/src/Field/InputClearButton.tsx +26 -8
- package/src/FieldStatus/__tests__/StatusMessage.a11y.chromium.spec.ts +21 -14
- package/src/FormLayout/FormLayout.tsx +1 -0
- package/src/FormLayout/__snapshots__/FormLayout.test.tsx.snap +1 -1
- package/src/Grid/Grid.doc.mjs +14 -11
- package/src/Grid/Grid.spec.md +50 -32
- package/src/Grid/Grid.tsx +13 -4
- package/src/HoverCard/HoverCard.test.tsx +46 -1
- package/src/HoverCard/useHoverCard.tsx +68 -48
- package/src/InputGroup/InputGroup.doc.mjs +11 -1
- package/src/InputGroup/InputGroup.tsx +2 -4
- package/src/InputGroup/groupStyles.ts +40 -2
- package/src/Layer/useLayerDismissal.ts +9 -9
- package/src/Link/__tests__/Link.a11y.chromium.spec.ts +142 -0
- package/src/Link/__tests__/Link.a11y.renders.tsx +97 -0
- package/src/Link/__tests__/Link.a11y.states.ts +104 -0
- package/src/Link/__tests__/Link.a11y.test.tsx +127 -0
- package/src/Markdown/Markdown.doc.mjs +1 -1
- package/src/Markdown/Markdown.fr23.perf.test.ts +161 -40
- package/src/Markdown/Markdown.spec.md +45 -23
- package/src/Markdown/Markdown.test.tsx +38 -0
- package/src/Markdown/Markdown.tsx +24 -2
- package/src/Markdown/plugins/semanticFence.test.tsx +3 -2
- package/src/MobileNav/MobileNav.tsx +50 -2
- package/src/MobileNav/MobileNavFocus.test.tsx +553 -0
- package/src/MoreMenu/MoreMenu.spec.md +18 -7
- package/src/MoreMenu/MoreMenu.test.tsx +38 -0
- package/src/MultiSelector/MultiSelector.doc.mjs +8 -8
- package/src/MultiSelector/MultiSelector.spec.md +1 -1
- package/src/MultiSelector/MultiSelector.test.tsx +188 -21
- package/src/MultiSelector/MultiSelector.tsx +50 -11
- package/src/NumberInput/NumberInput.test.tsx +24 -0
- package/src/NumberInput/NumberInput.tsx +1 -1
- package/src/NumberInput/__tests__/NumberInput.a11y.chromium.spec.ts +22 -15
- package/src/PowerSearch/PowerSearchEditPopover.test.tsx +78 -0
- package/src/PowerSearch/PowerSearchEditPopover.tsx +6 -0
- package/src/Resizable/Resizable.spec.md +41 -9
- package/src/Resizable/ResizeHandle.test.tsx +565 -2
- package/src/Resizable/ResizeHandle.tsx +126 -21
- package/src/Resizable/__tests__/ResizeHandle.a11y.chromium.spec.ts +119 -0
- package/src/Resizable/__tests__/ResizeHandle.a11y.known-failures.ts +39 -0
- package/src/Resizable/__tests__/ResizeHandle.a11y.renders.tsx +80 -0
- package/src/Resizable/__tests__/ResizeHandle.a11y.states.ts +197 -0
- package/src/Resizable/__tests__/ResizeHandle.a11y.test.tsx +123 -0
- package/src/Resizable/useResizable.ts +95 -0
- package/src/Selector/Selector.doc.mjs +7 -6
- package/src/Selector/Selector.spec.md +37 -24
- package/src/Selector/Selector.test.tsx +176 -10
- package/src/Selector/Selector.tsx +59 -14
- package/src/Selector/__tests__/Combobox.a11y.known-failures.ts +27 -0
- package/src/Selector/__tests__/Combobox.a11y.states.ts +145 -0
- package/src/Selector/__tests__/Selector.combobox.a11y.chromium.spec.ts +108 -0
- package/src/Selector/__tests__/Selector.combobox.a11y.test.tsx +126 -0
- package/src/SideNav/SideNav.test.tsx +35 -0
- package/src/SideNav/SideNav.tsx +16 -2
- package/src/Slider/Slider.spec.md +43 -17
- package/src/Slider/Slider.test.tsx +134 -0
- package/src/Slider/Slider.tsx +29 -6
- package/src/Slider/__tests__/Slider.a11y.chromium.spec.ts +112 -0
- package/src/Slider/__tests__/Slider.a11y.known-failures.ts +12 -0
- package/src/Slider/__tests__/Slider.a11y.renders.tsx +42 -0
- package/src/Slider/__tests__/Slider.a11y.states.ts +106 -0
- package/src/Slider/__tests__/Slider.a11y.test.tsx +105 -0
- package/src/Switch/__tests__/Switch.a11y.chromium.spec.ts +25 -18
- package/src/TabList/__tests__/Tabs.a11y.chromium.spec.ts +19 -12
- package/src/TextInput/__tests__/TextInput.a11y.chromium.spec.ts +21 -14
- package/src/ToggleButton/__tests__/ToggleButton.a11y.chromium.spec.ts +18 -11
- package/src/Tokenizer/Tokenizer.test.tsx +87 -0
- package/src/Tokenizer/Tokenizer.tsx +31 -3
- package/src/Toolbar/Toolbar.test.tsx +131 -4
- package/src/Toolbar/Toolbar.tsx +3 -1
- package/src/TreeList/TreeList.spec.md +33 -8
- package/src/TreeList/TreeList.test.tsx +72 -0
- package/src/TreeList/TreeList.tsx +10 -6
- package/src/TreeList/TreeListItem.tsx +5 -0
- package/src/TreeList/__tests__/TreeList.a11y.chromium.spec.ts +125 -0
- package/src/TreeList/__tests__/TreeList.a11y.renders.tsx +44 -0
- package/src/TreeList/__tests__/TreeList.a11y.states.ts +164 -0
- package/src/TreeList/__tests__/TreeList.a11y.test.tsx +138 -0
- package/src/TreeList/__tests__/TreeListRowNames.a11y.chromium.spec.ts +82 -0
- package/src/hooks/useScrollOverflow.test.tsx +222 -0
- package/src/hooks/useScrollOverflow.ts +55 -13
- package/src/hooks/useTreeFocus.test.tsx +37 -0
- package/src/hooks/useTreeFocus.ts +55 -2
- package/src/i18n/generated-locales/en.generated.ts +3 -0
- package/src/i18n/generated-locales/pseudo.generated.ts +3 -0
- package/src/reset.a11y.chromium.spec.ts +9 -1
- package/src/reset.css +8 -3
- package/src/reset.until-found.a11y.browser.spec.ts +75 -0
- package/src/reset.until-found.test.ts +32 -0
- package/src/stylexValidation.source-build.test.mjs +42 -0
- package/src/theme/syntax/SyntaxTheme.tsx +46 -5
- package/src/theme/syntax/defineSyntaxTheme.diff.test.ts +91 -0
- package/src/theme/syntax/defineSyntaxTheme.ts +75 -15
- package/src/theme/syntax/index.ts +5 -1
- package/src/theme/syntax/tokens.ts +32 -2
- package/src/theme/syntax/useSyntaxTheme.diff.test.tsx +40 -0
- package/src/utils/plainDate.test.ts +147 -0
- package/src/utils/plainDate.ts +75 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatMessage.d.ts","sourceRoot":"","sources":["../../src/Chat/ChatMessage.tsx"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"ChatMessage.d.ts","sourceRoot":"","sources":["../../src/Chat/ChatMessage.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAC,KAAK,SAAS,EAAiB,MAAM,OAAO,CAAC;AAQrD,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,WAAW,EACjB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAI5C,MAAM,WAAW,gBAAiB,SAAQ,SAAS,CAAC,WAAW,CAAC;IAC9D,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC7B,MAAM,EAAE,iBAAiB,CAAC;IAC1B;;;;;;OAMG;IACH,QAAQ,EAAE,SAAS,CAAC;IACpB;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AA4FD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,OAAO,EAAE,WAAW,EACpB,MAAM,EACN,SAAS,EACT,KAAK,EAAE,SAAS,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,EACH,GAAG,IAAI,EACR,EAAE,gBAAgB,+BA+FlB;yBA5Ge,WAAW"}
|
package/dist/Chat/ChatMessage.js
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* SYNC: When modified, update these files to stay in sync:
|
|
17
17
|
* - /packages/core/src/Chat/index.ts (exports)
|
|
18
18
|
* - /apps/storybook/stories/Chat.stories.tsx
|
|
19
|
+
* - /apps/storybook/stories/ChatMessage.stories.tsx
|
|
19
20
|
* - /packages/cli/assets/templates/blocks/components/ChatMessage/ (block examples)
|
|
20
21
|
*/
|
|
21
22
|
import { useMemo, useId } from 'react';
|
|
@@ -23,7 +24,7 @@ import * as stylex from '@stylexjs/stylex';
|
|
|
23
24
|
import "../theme/tokens.stylex.js";
|
|
24
25
|
import { colorVars, spacingVars, typeScaleVars, fontWeightVars } from "../theme/tokens.stylex.js";
|
|
25
26
|
import { ChatMessageContext, useChatListContext } from "./ChatContext.js";
|
|
26
|
-
import { mergeProps } from "../utils/index.js";
|
|
27
|
+
import { isRenderable, mergeProps } from "../utils/index.js";
|
|
27
28
|
import { themeProps } from "../utils/themeProps.js";
|
|
28
29
|
import { useTranslator } from "../i18n/index.js";
|
|
29
30
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
@@ -155,18 +156,23 @@ export function ChatMessage({
|
|
|
155
156
|
const columnAlignment = sender === 'system' ? styles.contentColumnSystem : sender === 'user' ? styles.contentColumnUser : styles.contentColumnAssistant;
|
|
156
157
|
const childrenAlignment = sender === 'system' ? styles.childrenSystem : sender === 'user' ? styles.childrenUser : styles.childrenAssistant;
|
|
157
158
|
const isSystem = sender === 'system';
|
|
158
|
-
const hasAvatar =
|
|
159
|
-
const hasName =
|
|
159
|
+
const hasAvatar = !isSystem && isRenderable(avatar);
|
|
160
|
+
const hasName = !isSystem && isRenderable(name);
|
|
161
|
+
const hasMetadata = !isSystem && isRenderable(metadata);
|
|
160
162
|
const nameId = useId();
|
|
161
163
|
return /*#__PURE__*/_jsx(ChatMessageContext, {
|
|
162
164
|
value: contextValue,
|
|
163
165
|
children: /*#__PURE__*/_jsxs("article", {
|
|
164
166
|
...rest,
|
|
165
167
|
ref: ref,
|
|
166
|
-
"data-testid": testId
|
|
167
|
-
|
|
168
|
+
"data-testid": testId
|
|
169
|
+
// The visible name labels the article. When it renders no text, the
|
|
170
|
+
// label reference resolves to nothing and the accessible name falls
|
|
171
|
+
// back to aria-label (accessible name computation 1.2, step 2B).
|
|
172
|
+
,
|
|
173
|
+
"aria-label": t('@astryx.chatMessage.messageFrom', {
|
|
168
174
|
sender
|
|
169
|
-
})
|
|
175
|
+
}),
|
|
170
176
|
"aria-labelledby": hasName ? nameId : undefined,
|
|
171
177
|
...mergeProps(themeProps('chat-message', {
|
|
172
178
|
sender,
|
|
@@ -174,7 +180,7 @@ export function ChatMessage({
|
|
|
174
180
|
}), stylex.props(styles.root, rootAlignment, hasAvatar && rootGap, xstyle), className, styleProp),
|
|
175
181
|
children: [hasAvatar && /*#__PURE__*/_jsx("div", {
|
|
176
182
|
...{
|
|
177
|
-
className: "x2lah0s x5du68j"
|
|
183
|
+
className: "xjl7jj x2lah0s x5du68j"
|
|
178
184
|
},
|
|
179
185
|
children: avatar
|
|
180
186
|
}), /*#__PURE__*/_jsxs("div", {
|
|
@@ -182,13 +188,16 @@ export function ChatMessage({
|
|
|
182
188
|
children: [hasName && /*#__PURE__*/_jsx("div", {
|
|
183
189
|
id: nameId,
|
|
184
190
|
...{
|
|
185
|
-
className: "x141an7d x2mo6ok xv1l7n4 x1ltkj2j x14cgwvg"
|
|
191
|
+
className: "xjl7jj x141an7d x2mo6ok xv1l7n4 x1ltkj2j x14cgwvg"
|
|
186
192
|
},
|
|
187
193
|
children: name
|
|
188
194
|
}), /*#__PURE__*/_jsx("div", {
|
|
189
195
|
...stylex.props(styles.childrenWrap, childrenAlignment, childrenGap),
|
|
190
196
|
children: children
|
|
191
|
-
}),
|
|
197
|
+
}), hasMetadata && /*#__PURE__*/_jsx("div", {
|
|
198
|
+
...{
|
|
199
|
+
className: "xjl7jj"
|
|
200
|
+
},
|
|
192
201
|
children: metadata
|
|
193
202
|
})]
|
|
194
203
|
})]
|
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Detects trigger characters (@ / etc.) typed inside a contentEditable,
|
|
8
8
|
* opens a popover at the cursor position with filtered items, handles
|
|
9
|
-
* keyboard navigation, and inserts tokens or text on selection.
|
|
9
|
+
* keyboard navigation, and inserts tokens or text on selection. Triggers
|
|
10
|
+
* opt into multi-word queries with hasMultiWordQuery; results apply only
|
|
11
|
+
* while their query is current (component:ChatComposerInput FR10–FR16).
|
|
10
12
|
*
|
|
11
13
|
* Reuses SearchSource from Typeahead for async/sync search with
|
|
12
14
|
* cancel() support and debounce.
|
|
@@ -25,6 +27,11 @@ export interface TriggerMenuState {
|
|
|
25
27
|
items: SearchableItem[];
|
|
26
28
|
highlightedIndex: number;
|
|
27
29
|
isLoading: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* The last settled results were an unmatched multi-word query, so the menu
|
|
32
|
+
* is closed. It stays closed while a newer search for the same query runs.
|
|
33
|
+
*/
|
|
34
|
+
isHidden: boolean;
|
|
28
35
|
}
|
|
29
36
|
export interface UseTriggerMenuOptions {
|
|
30
37
|
triggers?: ChatComposerTrigger[];
|
|
@@ -42,7 +49,7 @@ export interface UseTriggerMenuReturn {
|
|
|
42
49
|
state: TriggerMenuState;
|
|
43
50
|
/** Call on every input event to check for trigger activation */
|
|
44
51
|
handleInput: () => void;
|
|
45
|
-
/** Call on keydown
|
|
52
|
+
/** Call on keydown — returns true if the event was consumed */
|
|
46
53
|
handleKeyDown: (e: React.KeyboardEvent) => boolean;
|
|
47
54
|
/** Render the trigger menu popover */
|
|
48
55
|
renderMenu: () => ReactNode;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTriggerMenu.d.ts","sourceRoot":"","sources":["../../src/Chat/useTriggerMenu.tsx"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"useTriggerMenu.d.ts","sourceRoot":"","sources":["../../src/Chat/useTriggerMenu.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAYf,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAGvD,OAAO,KAAK,EAAC,mBAAmB,EAAE,iBAAiB,EAAC,MAAM,qBAAqB,CAAC;AAMhF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACjC,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACpD,aAAa,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAClD,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,gBAAgB,CAAC;IACxB,gEAAgE;IAChE,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,+DAA+D;IAC/D,aAAa,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,aAAa,KAAK,OAAO,CAAC;IACnD,sCAAsC;IACtC,UAAU,EAAE,MAAM,SAAS,CAAC;IAC5B,mCAAmC;IACnC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB;;;;;OAKG;IACH,SAAS,EAAE;QACT,IAAI,EAAE,UAAU,GAAG,SAAS,CAAC;QAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,uBAAuB,CAAC,EAAE,MAAM,CAAC;QACjC,eAAe,CAAC,EAAE,SAAS,CAAC;KAC7B,CAAC;CACH;AAoOD,wBAAgB,cAAc,CAC5B,OAAO,EAAE,qBAAqB,GAC7B,oBAAoB,CAsnBtB"}
|
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
*
|
|
11
11
|
* Detects trigger characters (@ / etc.) typed inside a contentEditable,
|
|
12
12
|
* opens a popover at the cursor position with filtered items, handles
|
|
13
|
-
* keyboard navigation, and inserts tokens or text on selection.
|
|
13
|
+
* keyboard navigation, and inserts tokens or text on selection. Triggers
|
|
14
|
+
* opt into multi-word queries with hasMultiWordQuery; results apply only
|
|
15
|
+
* while their query is current (component:ChatComposerInput FR10–FR16).
|
|
14
16
|
*
|
|
15
17
|
* Reuses SearchSource from Typeahead for async/sync search with
|
|
16
18
|
* cancel() support and debounce.
|
|
@@ -25,7 +27,7 @@ import { usePopover } from "../Popover/usePopover.js";
|
|
|
25
27
|
import { useHighlightedOptionScroll } from "../hooks/useHighlightedOptionScroll.js";
|
|
26
28
|
import "../theme/tokens.stylex.js";
|
|
27
29
|
import { colorVars, spacingVars, radiusVars, typeScaleVars, typographyVars } from "../theme/tokens.stylex.js";
|
|
28
|
-
import { mergeProps, groupItems } from "../utils/index.js";
|
|
30
|
+
import { mergeProps, groupItems, isImeKeyEvent } from "../utils/index.js";
|
|
29
31
|
import { themeProps } from "../utils/themeProps.js";
|
|
30
32
|
import { useTranslator } from "../i18n/index.js";
|
|
31
33
|
|
|
@@ -48,6 +50,15 @@ const styles = {
|
|
|
48
50
|
// Helpers
|
|
49
51
|
// =============================================================================
|
|
50
52
|
|
|
53
|
+
/** The text node holding a collapsed caret inside `editable`, if any. */
|
|
54
|
+
function getCaretTextNode(editable) {
|
|
55
|
+
const selection = window.getSelection();
|
|
56
|
+
if (!selection || selection.rangeCount === 0) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
const node = selection.getRangeAt(0).startContainer;
|
|
60
|
+
return node.nodeType === Node.TEXT_NODE && editable.contains(node) ? node : null;
|
|
61
|
+
}
|
|
51
62
|
function getTextBeforeCursor(editable) {
|
|
52
63
|
const selection = window.getSelection();
|
|
53
64
|
if (!selection || selection.rangeCount === 0) {
|
|
@@ -66,27 +77,73 @@ function getTextBeforeCursor(editable) {
|
|
|
66
77
|
}
|
|
67
78
|
return null;
|
|
68
79
|
}
|
|
80
|
+
const MAX_MULTI_WORD_QUERY_LENGTH = 64;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* An unmatched multi-word query hides the menu instead of covering prose with
|
|
84
|
+
* an empty panel, unless the trigger supplies its own empty message.
|
|
85
|
+
*/
|
|
86
|
+
function isUnmatchedMultiWordQuery(trigger, items, isLoading) {
|
|
87
|
+
return trigger?.hasMultiWordQuery === true &&
|
|
88
|
+
// `null` means "not given", exactly as `undefined` does.
|
|
89
|
+
trigger.emptySearchText == null && items.length === 0 && !isLoading;
|
|
90
|
+
}
|
|
91
|
+
function isTriggerBoundary(char) {
|
|
92
|
+
return char === null || char === ' ' || char === '\t' || char === '\n';
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Finds the trigger query the caret is in (component:ChatComposerInput FR10,
|
|
97
|
+
* FR11). A trigger character activates at the start of the text or after a
|
|
98
|
+
* space, tab, or line break. A single-token query ends at whitespace. A
|
|
99
|
+
* multi-word query ends at a line break, past the length bound, or where the
|
|
100
|
+
* same trigger's character starts a new query; another trigger's character
|
|
101
|
+
* inside it is ordinary text.
|
|
102
|
+
*/
|
|
69
103
|
function findActiveTrigger(textBeforeCursor, triggers) {
|
|
70
|
-
|
|
104
|
+
let active = null;
|
|
105
|
+
for (let i = 0; i < textBeforeCursor.length; i++) {
|
|
71
106
|
const char = textBeforeCursor[i];
|
|
72
|
-
if (char === '
|
|
73
|
-
|
|
107
|
+
if (char === '\n') {
|
|
108
|
+
active = null;
|
|
109
|
+
continue;
|
|
74
110
|
}
|
|
75
|
-
|
|
76
|
-
if (char ===
|
|
77
|
-
|
|
78
|
-
if (prevChar === null || prevChar === ' ' || prevChar === '\n') {
|
|
79
|
-
const query = textBeforeCursor.slice(i + 1);
|
|
80
|
-
return {
|
|
81
|
-
trigger,
|
|
82
|
-
query,
|
|
83
|
-
triggerStart: i
|
|
84
|
-
};
|
|
85
|
-
}
|
|
111
|
+
if (active && !active.trigger.hasMultiWordQuery) {
|
|
112
|
+
if (char === ' ' || char === '\t') {
|
|
113
|
+
active = null;
|
|
86
114
|
}
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (active && i - active.triggerStart > MAX_MULTI_WORD_QUERY_LENGTH) {
|
|
118
|
+
active = null;
|
|
119
|
+
}
|
|
120
|
+
if (!isTriggerBoundary(i > 0 ? textBeforeCursor[i - 1] : null)) {
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
const trigger = triggers.find(t => t.character === char);
|
|
124
|
+
if (!trigger) {
|
|
125
|
+
continue;
|
|
87
126
|
}
|
|
127
|
+
if (active && trigger.character !== active.trigger.character) {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
active = {
|
|
131
|
+
trigger,
|
|
132
|
+
triggerStart: i
|
|
133
|
+
};
|
|
88
134
|
}
|
|
89
|
-
|
|
135
|
+
if (!active) {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
const query = textBeforeCursor.slice(active.triggerStart + 1);
|
|
139
|
+
if (active.trigger.hasMultiWordQuery && query.length > MAX_MULTI_WORD_QUERY_LENGTH) {
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
trigger: active.trigger,
|
|
144
|
+
query,
|
|
145
|
+
triggerStart: active.triggerStart
|
|
146
|
+
};
|
|
90
147
|
}
|
|
91
148
|
function deleteTriggerText(editable, triggerStart) {
|
|
92
149
|
const selection = window.getSelection();
|
|
@@ -131,11 +188,17 @@ export function useTriggerMenu(options) {
|
|
|
131
188
|
query: '',
|
|
132
189
|
items: [],
|
|
133
190
|
highlightedIndex: 0,
|
|
134
|
-
isLoading: false
|
|
191
|
+
isLoading: false,
|
|
192
|
+
isHidden: false
|
|
135
193
|
});
|
|
136
194
|
const triggerStartRef = useRef(-1);
|
|
137
195
|
const searchTimeoutRef = useRef(null);
|
|
196
|
+
const searchRequestIdRef = useRef(0);
|
|
197
|
+
const dismissedRef = useRef(null);
|
|
138
198
|
const anchorSpanRef = useRef(null);
|
|
199
|
+
// True while the popover is closed only because the query is unmatched; the
|
|
200
|
+
// trigger query itself is still active.
|
|
201
|
+
const isMenuSuppressedRef = useRef(false);
|
|
139
202
|
const removeAnchorSpan = useCallback(() => {
|
|
140
203
|
if (anchorSpanRef.current) {
|
|
141
204
|
anchorSpanRef.current.remove();
|
|
@@ -144,6 +207,10 @@ export function useTriggerMenu(options) {
|
|
|
144
207
|
}, []);
|
|
145
208
|
const popover = usePopover({
|
|
146
209
|
onHide: useCallback(() => {
|
|
210
|
+
if (isMenuSuppressedRef.current) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
searchRequestIdRef.current++;
|
|
147
214
|
removeAnchorSpan();
|
|
148
215
|
setState(prev => ({
|
|
149
216
|
...prev,
|
|
@@ -152,7 +219,8 @@ export function useTriggerMenu(options) {
|
|
|
152
219
|
query: '',
|
|
153
220
|
items: [],
|
|
154
221
|
highlightedIndex: 0,
|
|
155
|
-
isLoading: false
|
|
222
|
+
isLoading: false,
|
|
223
|
+
isHidden: false
|
|
156
224
|
}));
|
|
157
225
|
}, [removeAnchorSpan]),
|
|
158
226
|
hasLightDismiss: true,
|
|
@@ -162,6 +230,10 @@ export function useTriggerMenu(options) {
|
|
|
162
230
|
// the contenteditable composer, so a modal dialog wrapper is incorrect.
|
|
163
231
|
role: 'none'
|
|
164
232
|
});
|
|
233
|
+
const {
|
|
234
|
+
show: showPopover,
|
|
235
|
+
hide: hidePopover
|
|
236
|
+
} = popover;
|
|
165
237
|
|
|
166
238
|
// Cleanup on unmount
|
|
167
239
|
useEffect(() => {
|
|
@@ -177,14 +249,29 @@ export function useTriggerMenu(options) {
|
|
|
177
249
|
clearTimeout(searchTimeoutRef.current);
|
|
178
250
|
searchTimeoutRef.current = null;
|
|
179
251
|
}
|
|
252
|
+
searchRequestIdRef.current++;
|
|
180
253
|
// Cancel any in-flight search on the active trigger's searchSource
|
|
181
254
|
const trigger = state.activeTrigger;
|
|
182
255
|
if (trigger?.searchSource) {
|
|
183
256
|
trigger.searchSource.cancel?.();
|
|
184
257
|
}
|
|
185
258
|
removeAnchorSpan();
|
|
259
|
+
isMenuSuppressedRef.current = false;
|
|
260
|
+
// Ending the query also forgets an Escape on it; a send or clear must not
|
|
261
|
+
// leave the next message's mention at the same offset suppressed.
|
|
262
|
+
dismissedRef.current = null;
|
|
186
263
|
popover.hide();
|
|
187
264
|
triggerStartRef.current = -1;
|
|
265
|
+
setState(prev => ({
|
|
266
|
+
...prev,
|
|
267
|
+
isActive: false,
|
|
268
|
+
activeTrigger: null,
|
|
269
|
+
query: '',
|
|
270
|
+
items: [],
|
|
271
|
+
highlightedIndex: 0,
|
|
272
|
+
isLoading: false,
|
|
273
|
+
isHidden: false
|
|
274
|
+
}));
|
|
188
275
|
}, [popover, state.activeTrigger, removeAnchorSpan]);
|
|
189
276
|
|
|
190
277
|
// Anchor the popover to the cursor position (not the entire input).
|
|
@@ -232,9 +319,46 @@ export function useTriggerMenu(options) {
|
|
|
232
319
|
clearTimeout(searchTimeoutRef.current);
|
|
233
320
|
searchTimeoutRef.current = null;
|
|
234
321
|
}
|
|
322
|
+
const requestId = ++searchRequestIdRef.current;
|
|
323
|
+
// A result applies only while its request is the latest one and the
|
|
324
|
+
// caret is still inside the same trigger query. Submitting or clearing
|
|
325
|
+
// the editor ends the query without an input event, so check the DOM.
|
|
326
|
+
const isCurrent = () => {
|
|
327
|
+
if (requestId !== searchRequestIdRef.current) {
|
|
328
|
+
return false;
|
|
329
|
+
}
|
|
330
|
+
const editable = editableRef.current;
|
|
331
|
+
const textBefore = editable ? getTextBeforeCursor(editable) : null;
|
|
332
|
+
const found = textBefore === null || !triggers ? null : findActiveTrigger(textBefore, triggers);
|
|
333
|
+
if (found?.trigger.character !== trigger.character || found.triggerStart !== triggerStartRef.current) {
|
|
334
|
+
reset();
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
337
|
+
return true;
|
|
338
|
+
};
|
|
339
|
+
const applyResults = items => {
|
|
340
|
+
const isHidden = isUnmatchedMultiWordQuery(trigger, items, false);
|
|
341
|
+
setState(prev => ({
|
|
342
|
+
...prev,
|
|
343
|
+
items,
|
|
344
|
+
highlightedIndex: items.length > 0 ? 0 : -1,
|
|
345
|
+
isLoading: false,
|
|
346
|
+
isHidden
|
|
347
|
+
}));
|
|
348
|
+
// A hidden menu closes its popover, which also releases the popover's
|
|
349
|
+
// Escape and light-dismiss handling; matches reopen it at the caret.
|
|
350
|
+
if (isHidden && !isMenuSuppressedRef.current) {
|
|
351
|
+
isMenuSuppressedRef.current = true;
|
|
352
|
+
hidePopover();
|
|
353
|
+
} else if (!isHidden && isMenuSuppressedRef.current) {
|
|
354
|
+
isMenuSuppressedRef.current = false;
|
|
355
|
+
setAnchor();
|
|
356
|
+
showPopover();
|
|
357
|
+
}
|
|
358
|
+
};
|
|
235
359
|
const doSearch = () => {
|
|
236
360
|
if (trigger.searchSource) {
|
|
237
|
-
// Use SearchSource
|
|
361
|
+
// Use SearchSource — cancel previous, then search
|
|
238
362
|
trigger.searchSource.cancel?.();
|
|
239
363
|
setState(prev => ({
|
|
240
364
|
...prev,
|
|
@@ -242,19 +366,15 @@ export function useTriggerMenu(options) {
|
|
|
242
366
|
}));
|
|
243
367
|
const result = trigger.searchSource.search(query);
|
|
244
368
|
Promise.resolve(result).then(items => {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
isLoading: false
|
|
250
|
-
}));
|
|
369
|
+
if (!isCurrent()) {
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
applyResults(items);
|
|
251
373
|
}, () => {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
isLoading: false
|
|
257
|
-
}));
|
|
374
|
+
if (!isCurrent()) {
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
applyResults([]);
|
|
258
378
|
});
|
|
259
379
|
}
|
|
260
380
|
};
|
|
@@ -274,7 +394,7 @@ export function useTriggerMenu(options) {
|
|
|
274
394
|
doSearch();
|
|
275
395
|
}
|
|
276
396
|
}
|
|
277
|
-
}, [debounceMs]);
|
|
397
|
+
}, [debounceMs, editableRef, triggers, reset, setAnchor, hidePopover, showPopover]);
|
|
278
398
|
const selectItem = useCallback(item => {
|
|
279
399
|
const trigger = state.activeTrigger;
|
|
280
400
|
if (!trigger) {
|
|
@@ -309,6 +429,7 @@ export function useTriggerMenu(options) {
|
|
|
309
429
|
}
|
|
310
430
|
const textBefore = getTextBeforeCursor(editable);
|
|
311
431
|
if (textBefore === null) {
|
|
432
|
+
dismissedRef.current = null;
|
|
312
433
|
if (state.isActive) {
|
|
313
434
|
reset();
|
|
314
435
|
}
|
|
@@ -316,6 +437,7 @@ export function useTriggerMenu(options) {
|
|
|
316
437
|
}
|
|
317
438
|
const found = findActiveTrigger(textBefore, triggers);
|
|
318
439
|
if (!found) {
|
|
440
|
+
dismissedRef.current = null;
|
|
319
441
|
if (state.isActive) {
|
|
320
442
|
reset();
|
|
321
443
|
}
|
|
@@ -326,14 +448,27 @@ export function useTriggerMenu(options) {
|
|
|
326
448
|
query,
|
|
327
449
|
triggerStart
|
|
328
450
|
} = found;
|
|
329
|
-
|
|
451
|
+
|
|
452
|
+
// After Escape, keep the menu hidden while that same query keeps growing
|
|
453
|
+
const dismissed = dismissedRef.current;
|
|
454
|
+
if (dismissed && dismissed.character === trigger.character && dismissed.triggerStart === triggerStart && dismissed.textNode !== null && dismissed.textNode.isConnected && dismissed.textNode === getCaretTextNode(editable)) {
|
|
455
|
+
if (query.startsWith(dismissed.dismissedQuery)) {
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
dismissedRef.current = null;
|
|
459
|
+
} else {
|
|
460
|
+
dismissedRef.current = null;
|
|
461
|
+
}
|
|
462
|
+
if (!state.isActive || state.activeTrigger?.character !== trigger.character || triggerStartRef.current !== triggerStart) {
|
|
330
463
|
triggerStartRef.current = triggerStart;
|
|
464
|
+
isMenuSuppressedRef.current = false;
|
|
331
465
|
setState(prev => ({
|
|
332
466
|
...prev,
|
|
333
467
|
isActive: true,
|
|
334
468
|
activeTrigger: trigger,
|
|
335
469
|
query,
|
|
336
|
-
highlightedIndex: 0
|
|
470
|
+
highlightedIndex: 0,
|
|
471
|
+
isHidden: false
|
|
337
472
|
}));
|
|
338
473
|
setAnchor();
|
|
339
474
|
searchItems(trigger, query);
|
|
@@ -341,13 +476,50 @@ export function useTriggerMenu(options) {
|
|
|
341
476
|
} else if (state.query !== query) {
|
|
342
477
|
setState(prev => ({
|
|
343
478
|
...prev,
|
|
344
|
-
query
|
|
479
|
+
query,
|
|
480
|
+
activeTrigger: trigger
|
|
345
481
|
}));
|
|
346
482
|
searchItems(trigger, query);
|
|
347
483
|
}
|
|
348
484
|
}, [triggers, editableRef, state.isActive, state.activeTrigger, state.query, reset, setAnchor, searchItems, popover]);
|
|
485
|
+
const isMenuVisible = state.isActive && !state.isHidden;
|
|
349
486
|
const handleKeyDown = useCallback(e => {
|
|
350
|
-
|
|
487
|
+
// Never intercept IME composition keystrokes (e.g. Enter committing candidates)
|
|
488
|
+
if (isImeKeyEvent(e.nativeEvent)) {
|
|
489
|
+
return false;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// A hidden menu consumes nothing: arrows move the caret, Enter submits,
|
|
493
|
+
// and Escape reaches the surrounding surface.
|
|
494
|
+
if (!isMenuVisible) {
|
|
495
|
+
return false;
|
|
496
|
+
}
|
|
497
|
+
if (e.key === 'Escape') {
|
|
498
|
+
e.preventDefault();
|
|
499
|
+
const editable = editableRef.current;
|
|
500
|
+
const dismissed = state.activeTrigger ? {
|
|
501
|
+
character: state.activeTrigger.character,
|
|
502
|
+
triggerStart: triggerStartRef.current,
|
|
503
|
+
dismissedQuery: state.query,
|
|
504
|
+
textNode: editable ? getCaretTextNode(editable) : null
|
|
505
|
+
} : null;
|
|
506
|
+
reset();
|
|
507
|
+
// Remembered after reset, which clears it: the menu stays hidden while
|
|
508
|
+
// this same query keeps growing.
|
|
509
|
+
dismissedRef.current = dismissed;
|
|
510
|
+
return true;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
// A visible menu keeps the arrows even when it has nothing to pick (rows
|
|
514
|
+
// still loading, or the empty message), so they never recall history
|
|
515
|
+
// under an open panel. Enter and Tab pick only a settled row; otherwise
|
|
516
|
+
// they keep their editor meaning, so Enter sends the message as typed.
|
|
517
|
+
const hasPickableRows = !state.isLoading && state.items.length > 0;
|
|
518
|
+
if (!hasPickableRows && (e.key === 'ArrowDown' || e.key === 'ArrowUp')) {
|
|
519
|
+
e.preventDefault();
|
|
520
|
+
return true;
|
|
521
|
+
}
|
|
522
|
+
if (!hasPickableRows) {
|
|
351
523
|
return false;
|
|
352
524
|
}
|
|
353
525
|
switch (e.key) {
|
|
@@ -379,16 +551,10 @@ export function useTriggerMenu(options) {
|
|
|
379
551
|
}
|
|
380
552
|
return false;
|
|
381
553
|
}
|
|
382
|
-
case 'Escape':
|
|
383
|
-
{
|
|
384
|
-
e.preventDefault();
|
|
385
|
-
reset();
|
|
386
|
-
return true;
|
|
387
|
-
}
|
|
388
554
|
default:
|
|
389
555
|
return false;
|
|
390
556
|
}
|
|
391
|
-
}, [state.
|
|
557
|
+
}, [isMenuVisible, editableRef, state.activeTrigger, state.query, state.isLoading, state.highlightedIndex, state.items, selectItem, reset]);
|
|
392
558
|
const getItemId = useCallback(index => `${listboxId}-option-${index}`, [listboxId]);
|
|
393
559
|
|
|
394
560
|
// Keep the highlighted option visible during keyboard navigation; hover
|
|
@@ -416,7 +582,7 @@ export function useTriggerMenu(options) {
|
|
|
416
582
|
const ariaProps = !hasTriggers ? {
|
|
417
583
|
role: 'textbox',
|
|
418
584
|
'aria-multiline': 'true'
|
|
419
|
-
} :
|
|
585
|
+
} : isMenuVisible ? {
|
|
420
586
|
role: 'combobox',
|
|
421
587
|
'aria-expanded': true,
|
|
422
588
|
'aria-controls': listboxId,
|
|
@@ -428,9 +594,15 @@ export function useTriggerMenu(options) {
|
|
|
428
594
|
'aria-haspopup': 'listbox'
|
|
429
595
|
};
|
|
430
596
|
const renderMenu = useCallback(() => {
|
|
431
|
-
const
|
|
432
|
-
|
|
433
|
-
|
|
597
|
+
const activeTrigger = state.activeTrigger;
|
|
598
|
+
if (!activeTrigger) {
|
|
599
|
+
return null;
|
|
600
|
+
}
|
|
601
|
+
if (state.isHidden) {
|
|
602
|
+
return null;
|
|
603
|
+
}
|
|
604
|
+
const emptyText = activeTrigger.emptySearchText ?? 'No results';
|
|
605
|
+
const loadingText = activeTrigger.loadingText ?? 'Searching\u2026';
|
|
434
606
|
let listContent;
|
|
435
607
|
if (state.isLoading) {
|
|
436
608
|
listContent = /*#__PURE__*/_jsx("div", {
|
|
@@ -471,7 +643,7 @@ export function useTriggerMenu(options) {
|
|
|
471
643
|
className: "x9f619 x78zum5 x6s0dn4 xh8yej3 xlsj2fj xh6dtrn x1ypdohk x16khyan x1a2a7pz xc342km xng3xce x1yc453h x9ynric xjm74w1 xw6l6zx x1tgivj0 x1lmrjuc"
|
|
472
644
|
}
|
|
473
645
|
}[!!(idx === state.highlightedIndex) << 0],
|
|
474
|
-
children:
|
|
646
|
+
children: activeTrigger.renderItem ? activeTrigger.renderItem(item) : /*#__PURE__*/_jsx("span", {
|
|
475
647
|
...{
|
|
476
648
|
className: "x98rzlu xeuugli xb3r6kr xlyipyv xuxw1ft"
|
|
477
649
|
},
|
|
@@ -498,7 +670,7 @@ export function useTriggerMenu(options) {
|
|
|
498
670
|
return popover.render(/*#__PURE__*/_jsx("div", {
|
|
499
671
|
id: listboxId,
|
|
500
672
|
role: "listbox",
|
|
501
|
-
"aria-label":
|
|
673
|
+
"aria-label": activeTrigger.menuLabel ?? t('@astryx.chatTriggerMenu.suggestions'),
|
|
502
674
|
...mergeProps(themeProps('trigger-menu'), {
|
|
503
675
|
className: "x9f619 x1xiyphd x1odjw0f x9epnlk xfb3i0g"
|
|
504
676
|
}),
|
|
@@ -9,6 +9,15 @@ export interface CodeBlockProps extends BaseProps<HTMLPreElement> {
|
|
|
9
9
|
hasLanguageLabel?: boolean;
|
|
10
10
|
hasLineNumbers?: boolean;
|
|
11
11
|
highlightLines?: number[];
|
|
12
|
+
/**
|
|
13
|
+
* Render the code as a unified diff over `language`: lines starting with
|
|
14
|
+
* `+` are added, `-` removed, `@@` is a hunk header (a `--- `/`+++ ` pair
|
|
15
|
+
* directly before one is a file header), anything else is context; the
|
|
16
|
+
* label reads `diff` or `<language> diff`. The glyph sits in its own column and the rest of every line
|
|
17
|
+
* keeps the language's syntax highlighting. Copy still returns the exact
|
|
18
|
+
* source, glyphs included.
|
|
19
|
+
*/
|
|
20
|
+
isDiff?: boolean;
|
|
12
21
|
hasCopyButton?: boolean;
|
|
13
22
|
onCopy?: () => void;
|
|
14
23
|
isWrapped?: boolean;
|
|
@@ -58,7 +67,7 @@ export interface CodeBlockProps extends BaseProps<HTMLPreElement> {
|
|
|
58
67
|
* <CodeBlock code="const x = 42;" language="javascript" />
|
|
59
68
|
* ```
|
|
60
69
|
*/
|
|
61
|
-
export declare function CodeBlock({ code, language, title, hasLanguageLabel, hasLineNumbers, highlightLines, hasCopyButton, onCopy, isWrapped, maxHeight, isCollapsible, collapsibleThreshold, size, width: widthProp, container, tokenizer: customTokenizer, highlightMode, syntaxTheme, xstyle, className, style, ref, ...props }: CodeBlockProps): React.JSX.Element;
|
|
70
|
+
export declare function CodeBlock({ code, language, title, hasLanguageLabel, hasLineNumbers, highlightLines, isDiff, hasCopyButton, onCopy, isWrapped, maxHeight, isCollapsible, collapsibleThreshold, size, width: widthProp, container, tokenizer: customTokenizer, highlightMode, syntaxTheme, xstyle, className, style, ref, ...props }: CodeBlockProps): React.JSX.Element;
|
|
62
71
|
export declare namespace CodeBlock {
|
|
63
72
|
var displayName: string;
|
|
64
73
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeBlock.d.ts","sourceRoot":"","sources":["../../src/CodeBlock/CodeBlock.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"CodeBlock.d.ts","sourceRoot":"","sources":["../../src/CodeBlock/CodeBlock.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAgC5C,OAAO,EAAc,KAAK,qBAAqB,EAAC,MAAM,iBAAiB,CAAC;AAwcxE,MAAM,WAAW,cAAe,SAAQ,SAAS,CAAC,cAAc,CAAC;IAC/D,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,SAAS,CAAC,EAAE,CACV,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,KACb;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAC,EAAE,CAAC;IAClD,aAAa,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;IAC5C;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,qBAAqB,CAAC;CACrC;AAgSD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,EACxB,IAAI,EACJ,QAAsB,EACtB,KAAK,EACL,gBAAuB,EACvB,cAAsB,EACtB,cAAc,EACd,MAAc,EACd,aAAoB,EACpB,MAAM,EACN,SAAiB,EACjB,SAAS,EACT,aAAqB,EACrB,oBAAyB,EACzB,IAAW,EACX,KAAK,EAAE,SAAyB,EAChC,SAAkB,EAClB,SAAS,EAAE,eAAe,EAC1B,aAAsB,EACtB,WAAW,EACX,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,cAAc,qBAmRhB;yBA5Se,SAAS"}
|