@k2b/ui 0.26.0 → 0.28.0

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.
Files changed (231) hide show
  1. package/README.md +1 -1
  2. package/dist/base.css +147 -2
  3. package/dist/browser/actions/ContextMenu.js +30 -4
  4. package/dist/browser/actions/ContextMenu.js.map +1 -1
  5. package/dist/browser/actions/Dropdown.js +184 -158
  6. package/dist/browser/actions/Dropdown.js.map +1 -1
  7. package/dist/browser/actions/GestureMenu.js +71 -138
  8. package/dist/browser/actions/GestureMenu.js.map +1 -1
  9. package/dist/browser/actions/Toolbar.js +379 -48
  10. package/dist/browser/actions/Toolbar.js.map +1 -1
  11. package/dist/browser/actions/index.js.map +1 -1
  12. package/dist/browser/actions/menu-rows.js +15 -0
  13. package/dist/browser/actions/menu-rows.js.map +1 -0
  14. package/dist/browser/actions/menu-sheet.js +154 -0
  15. package/dist/browser/actions/menu-sheet.js.map +1 -0
  16. package/dist/browser/actions/toolbar-messages.js +20 -0
  17. package/dist/browser/actions/toolbar-messages.js.map +1 -0
  18. package/dist/browser/chart-inspection.js +3 -0
  19. package/dist/browser/chart-inspection.js.map +1 -0
  20. package/dist/browser/chat/ChatComposer.js +1020 -431
  21. package/dist/browser/chat/ChatComposer.js.map +1 -1
  22. package/dist/browser/chat/chat-behavior.js +4 -0
  23. package/dist/browser/chat/chat-behavior.js.map +1 -1
  24. package/dist/browser/chat/chat-messages.js +33 -1
  25. package/dist/browser/chat/chat-messages.js.map +1 -1
  26. package/dist/browser/chat/command-search.js +173 -0
  27. package/dist/browser/chat/command-search.js.map +1 -0
  28. package/dist/browser/chat/composer-document.js +1 -1
  29. package/dist/browser/chat/composer-document.js.map +1 -1
  30. package/dist/browser/chat/index.js +2 -0
  31. package/dist/browser/chat/index.js.map +1 -1
  32. package/dist/browser/chat/reaction-people.js +15 -0
  33. package/dist/browser/chat/reaction-people.js.map +1 -0
  34. package/dist/browser/content/CalendarDayView.js +28 -3
  35. package/dist/browser/content/CalendarDayView.js.map +1 -1
  36. package/dist/browser/content/Chart.js +6 -15
  37. package/dist/browser/content/Chart.js.map +1 -1
  38. package/dist/browser/content/ChartSnapshotView.js +7 -10
  39. package/dist/browser/content/ChartSnapshotView.js.map +1 -1
  40. package/dist/browser/content/MessageRow.js +330 -448
  41. package/dist/browser/content/MessageRow.js.map +1 -1
  42. package/dist/browser/content/ReactionBar.js +419 -0
  43. package/dist/browser/content/ReactionBar.js.map +1 -0
  44. package/dist/browser/content/chart-inspection-core.js +557 -0
  45. package/dist/browser/content/chart-inspection-core.js.map +1 -0
  46. package/dist/browser/content/chart-inspection.js +10 -445
  47. package/dist/browser/content/chart-inspection.js.map +1 -1
  48. package/dist/browser/content/chart-line-gaps.js +1 -1
  49. package/dist/browser/content/chart-line-gaps.js.map +1 -1
  50. package/dist/browser/content/chart-snapshot.js +1 -1
  51. package/dist/browser/content/chart-snapshot.js.map +1 -1
  52. package/dist/browser/content/index.js +1 -0
  53. package/dist/browser/content/index.js.map +1 -1
  54. package/dist/browser/feedback/dialog-core.js +135 -23
  55. package/dist/browser/feedback/dialog-core.js.map +1 -1
  56. package/dist/browser/index.js +1 -0
  57. package/dist/browser/index.js.map +1 -1
  58. package/dist/browser/input-mode.js +40 -0
  59. package/dist/browser/input-mode.js.map +1 -0
  60. package/dist/browser/inputs/Combobox.js +4 -2
  61. package/dist/browser/inputs/Combobox.js.map +1 -1
  62. package/dist/browser/inputs/FileDropTarget.js +24 -9
  63. package/dist/browser/inputs/FileDropTarget.js.map +1 -1
  64. package/dist/browser/inputs/FileInputs.js +2 -2
  65. package/dist/browser/inputs/FileInputs.js.map +1 -1
  66. package/dist/browser/inputs/SelectChip.js +52 -12
  67. package/dist/browser/inputs/SelectChip.js.map +1 -1
  68. package/dist/browser/inputs/emoji/EmojiPicker.js +13 -0
  69. package/dist/browser/inputs/emoji/EmojiPicker.js.map +1 -1
  70. package/dist/browser/inputs/file-drop.js.map +1 -1
  71. package/dist/browser/layout/AppWorkspace.js +708 -515
  72. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  73. package/dist/browser/layout/BottomSheet.js +8 -0
  74. package/dist/browser/layout/BottomSheet.js.map +1 -1
  75. package/dist/browser/layout/DetailPanel.js +283 -197
  76. package/dist/browser/layout/DetailPanel.js.map +1 -1
  77. package/dist/browser/layout/Discussion.js +233 -185
  78. package/dist/browser/layout/Discussion.js.map +1 -1
  79. package/dist/browser/layout/TableOfContents.js +10 -2
  80. package/dist/browser/layout/TableOfContents.js.map +1 -1
  81. package/dist/browser/layout/app-workspace-controller.js +155 -23
  82. package/dist/browser/layout/app-workspace-controller.js.map +1 -1
  83. package/dist/browser/layout/app-workspace-state.js +5 -1
  84. package/dist/browser/layout/app-workspace-state.js.map +1 -1
  85. package/dist/browser/layout/detail-panel-messages.js +35 -0
  86. package/dist/browser/layout/detail-panel-messages.js.map +1 -0
  87. package/dist/browser/layout/index.js +1 -1
  88. package/dist/browser/layout/index.js.map +1 -1
  89. package/dist/browser/surfaces/Avatar.js +50 -20
  90. package/dist/browser/surfaces/Avatar.js.map +1 -1
  91. package/dist/browser/surfaces/AvatarStack.js +406 -0
  92. package/dist/browser/surfaces/AvatarStack.js.map +1 -0
  93. package/dist/browser/surfaces/avatar-messages.js +8 -2
  94. package/dist/browser/surfaces/avatar-messages.js.map +1 -1
  95. package/dist/browser/surfaces/index.js +1 -0
  96. package/dist/browser/surfaces/index.js.map +1 -1
  97. package/dist/ssr/actions/ContextMenu.js +21 -3
  98. package/dist/ssr/actions/ContextMenu.js.map +1 -1
  99. package/dist/ssr/actions/Dropdown.js +140 -72
  100. package/dist/ssr/actions/Dropdown.js.map +1 -1
  101. package/dist/ssr/actions/GestureMenu.js +52 -106
  102. package/dist/ssr/actions/GestureMenu.js.map +1 -1
  103. package/dist/ssr/actions/Toolbar.js +294 -14
  104. package/dist/ssr/actions/Toolbar.js.map +1 -1
  105. package/dist/ssr/actions/index.js.map +1 -1
  106. package/dist/ssr/actions/menu-rows.js +15 -0
  107. package/dist/ssr/actions/menu-rows.js.map +1 -0
  108. package/dist/ssr/actions/menu-sheet.js +138 -0
  109. package/dist/ssr/actions/menu-sheet.js.map +1 -0
  110. package/dist/ssr/actions/toolbar-messages.js +20 -0
  111. package/dist/ssr/actions/toolbar-messages.js.map +1 -0
  112. package/dist/ssr/chart-inspection.js +3 -0
  113. package/dist/ssr/chart-inspection.js.map +1 -0
  114. package/dist/ssr/chat/ChatComposer.js +604 -113
  115. package/dist/ssr/chat/ChatComposer.js.map +1 -1
  116. package/dist/ssr/chat/chat-behavior.js +4 -0
  117. package/dist/ssr/chat/chat-behavior.js.map +1 -1
  118. package/dist/ssr/chat/chat-messages.js +33 -1
  119. package/dist/ssr/chat/chat-messages.js.map +1 -1
  120. package/dist/ssr/chat/command-search.js +173 -0
  121. package/dist/ssr/chat/command-search.js.map +1 -0
  122. package/dist/ssr/chat/composer-document.js +1 -1
  123. package/dist/ssr/chat/composer-document.js.map +1 -1
  124. package/dist/ssr/chat/index.js +2 -0
  125. package/dist/ssr/chat/index.js.map +1 -1
  126. package/dist/ssr/chat/reaction-people.js +15 -0
  127. package/dist/ssr/chat/reaction-people.js.map +1 -0
  128. package/dist/ssr/content/CalendarDayView.js +28 -3
  129. package/dist/ssr/content/CalendarDayView.js.map +1 -1
  130. package/dist/ssr/content/Chart.js +6 -15
  131. package/dist/ssr/content/Chart.js.map +1 -1
  132. package/dist/ssr/content/ChartSnapshotView.js +7 -10
  133. package/dist/ssr/content/ChartSnapshotView.js.map +1 -1
  134. package/dist/ssr/content/MessageRow.js +98 -152
  135. package/dist/ssr/content/MessageRow.js.map +1 -1
  136. package/dist/ssr/content/ReactionBar.js +304 -0
  137. package/dist/ssr/content/ReactionBar.js.map +1 -0
  138. package/dist/ssr/content/chart-inspection-core.js +557 -0
  139. package/dist/ssr/content/chart-inspection-core.js.map +1 -0
  140. package/dist/ssr/content/chart-inspection.js +10 -445
  141. package/dist/ssr/content/chart-inspection.js.map +1 -1
  142. package/dist/ssr/content/chart-line-gaps.js +1 -1
  143. package/dist/ssr/content/chart-line-gaps.js.map +1 -1
  144. package/dist/ssr/content/chart-snapshot.js +1 -1
  145. package/dist/ssr/content/chart-snapshot.js.map +1 -1
  146. package/dist/ssr/content/index.js +1 -0
  147. package/dist/ssr/content/index.js.map +1 -1
  148. package/dist/ssr/feedback/dialog-core.js +135 -23
  149. package/dist/ssr/feedback/dialog-core.js.map +1 -1
  150. package/dist/ssr/index.js +1 -0
  151. package/dist/ssr/index.js.map +1 -1
  152. package/dist/ssr/input-mode.js +40 -0
  153. package/dist/ssr/input-mode.js.map +1 -0
  154. package/dist/ssr/inputs/Combobox.js +4 -2
  155. package/dist/ssr/inputs/Combobox.js.map +1 -1
  156. package/dist/ssr/inputs/FileDropTarget.js +17 -5
  157. package/dist/ssr/inputs/FileDropTarget.js.map +1 -1
  158. package/dist/ssr/inputs/FileInputs.js +2 -2
  159. package/dist/ssr/inputs/FileInputs.js.map +1 -1
  160. package/dist/ssr/inputs/SelectChip.js +44 -11
  161. package/dist/ssr/inputs/SelectChip.js.map +1 -1
  162. package/dist/ssr/inputs/emoji/EmojiPicker.js +12 -0
  163. package/dist/ssr/inputs/emoji/EmojiPicker.js.map +1 -1
  164. package/dist/ssr/inputs/file-drop.js.map +1 -1
  165. package/dist/ssr/layout/AppWorkspace.js +242 -105
  166. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  167. package/dist/ssr/layout/BottomSheet.js +8 -0
  168. package/dist/ssr/layout/BottomSheet.js.map +1 -1
  169. package/dist/ssr/layout/DetailPanel.js +112 -58
  170. package/dist/ssr/layout/DetailPanel.js.map +1 -1
  171. package/dist/ssr/layout/Discussion.js +63 -36
  172. package/dist/ssr/layout/Discussion.js.map +1 -1
  173. package/dist/ssr/layout/TableOfContents.js +10 -2
  174. package/dist/ssr/layout/TableOfContents.js.map +1 -1
  175. package/dist/ssr/layout/app-workspace-controller.js +155 -23
  176. package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
  177. package/dist/ssr/layout/app-workspace-state.js +5 -1
  178. package/dist/ssr/layout/app-workspace-state.js.map +1 -1
  179. package/dist/ssr/layout/detail-panel-messages.js +35 -0
  180. package/dist/ssr/layout/detail-panel-messages.js.map +1 -0
  181. package/dist/ssr/layout/index.js +1 -1
  182. package/dist/ssr/layout/index.js.map +1 -1
  183. package/dist/ssr/surfaces/Avatar.js +20 -2
  184. package/dist/ssr/surfaces/Avatar.js.map +1 -1
  185. package/dist/ssr/surfaces/AvatarStack.js +286 -0
  186. package/dist/ssr/surfaces/AvatarStack.js.map +1 -0
  187. package/dist/ssr/surfaces/avatar-messages.js +8 -2
  188. package/dist/ssr/surfaces/avatar-messages.js.map +1 -1
  189. package/dist/ssr/surfaces/index.js +1 -0
  190. package/dist/ssr/surfaces/index.js.map +1 -1
  191. package/dist/styles.css +1 -1
  192. package/dist/types/actions/ContextMenu.d.ts +8 -0
  193. package/dist/types/actions/Dropdown.d.ts +12 -5
  194. package/dist/types/actions/GestureMenu.d.ts +6 -4
  195. package/dist/types/actions/Toolbar.d.ts +20 -0
  196. package/dist/types/actions/index.d.ts +1 -1
  197. package/dist/types/actions/menu-rows.d.ts +5 -0
  198. package/dist/types/actions/menu-sheet.d.ts +22 -0
  199. package/dist/types/actions/toolbar-messages.d.ts +8 -0
  200. package/dist/types/chart-inspection.d.ts +2 -0
  201. package/dist/types/chat/ChatComposer.d.ts +51 -2
  202. package/dist/types/chat/chat-behavior.d.ts +4 -0
  203. package/dist/types/chat/chat-messages.d.ts +17 -2
  204. package/dist/types/chat/command-search.d.ts +41 -0
  205. package/dist/types/chat/index.d.ts +3 -1
  206. package/dist/types/chat/reaction-people.d.ts +9 -0
  207. package/dist/types/content/Chart.d.ts +2 -2
  208. package/dist/types/content/MessageRow.d.ts +3 -10
  209. package/dist/types/content/ReactionBar.d.ts +32 -0
  210. package/dist/types/content/chart-inspection-core.d.ts +61 -0
  211. package/dist/types/content/chart-inspection.d.ts +4 -20
  212. package/dist/types/content/chart-snapshot.d.ts +1 -1
  213. package/dist/types/content/index.d.ts +2 -1
  214. package/dist/types/feedback/dialog-core.d.ts +16 -1
  215. package/dist/types/index.d.ts +1 -0
  216. package/dist/types/input-mode.d.ts +7 -0
  217. package/dist/types/inputs/FileDropTarget.d.ts +6 -3
  218. package/dist/types/inputs/SelectChip.d.ts +6 -0
  219. package/dist/types/inputs/file-drop.d.ts +2 -0
  220. package/dist/types/layout/AppWorkspace.d.ts +13 -1
  221. package/dist/types/layout/BottomSheet.d.ts +8 -0
  222. package/dist/types/layout/DetailPanel.d.ts +11 -0
  223. package/dist/types/layout/Discussion.d.ts +8 -0
  224. package/dist/types/layout/TableOfContents.d.ts +2 -0
  225. package/dist/types/layout/detail-panel-messages.d.ts +15 -0
  226. package/dist/types/layout/index.d.ts +1 -1
  227. package/dist/types/surfaces/Avatar.d.ts +12 -0
  228. package/dist/types/surfaces/AvatarStack.d.ts +41 -0
  229. package/dist/types/surfaces/avatar-messages.d.ts +3 -0
  230. package/dist/types/surfaces/index.d.ts +3 -1
  231. package/package.json +9 -4
@@ -25,34 +25,43 @@ var _tmpl$ = /*#__PURE__*/_$template(`<span><strong>`),
25
25
  _tmpl$0 = /*#__PURE__*/_$template(`<textarea class=k2b-chat-composer__measure rows=1 tabindex=-1 aria-hidden=true readonly>`),
26
26
  _tmpl$1 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__input role=group><!$><!/><textarea rows=1></textarea><!$><!/>`),
27
27
  _tmpl$10 = /*#__PURE__*/_$template(`<span>`),
28
- _tmpl$11 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer-accessory><div class=k2b-chat-composer__commands role=listbox>`),
29
- _tmpl$12 = /*#__PURE__*/_$template(`<div role=status class=k2b-chat-composer__loading><i class="ti ti-loader-2 k2b-spin"aria-hidden=true></i><strong>`),
30
- _tmpl$13 = /*#__PURE__*/_$template(`<div role=status><i class="ti ti-alert-circle"></i> <!$><!/>`),
31
- _tmpl$14 = /*#__PURE__*/_$template(`<div role=status>`),
32
- _tmpl$15 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer-accessory><div class=k2b-chat-composer__commands role=listbox><!$><!/><!$><!/><!$><!/><!$><!/>`),
33
- _tmpl$16 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer-slot><div></div><!$><!/><!$><!/>`),
34
- _tmpl$17 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__hint aria-live=polite>`),
35
- _tmpl$18 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__attachments role=list tabindex=0>`),
36
- _tmpl$19 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__error role=alert><i class="ti ti-alert-circle"aria-hidden=true></i><!$><!/>`),
37
- _tmpl$20 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__row><!$><!/><!$><!/><div class=k2b-chat-composer__field><!$><!/><div class=k2b-chat-composer__field-tools><!$><!/><!$><!/><!$><!/></div></div><!$><!/>`),
38
- _tmpl$21 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer-shell><!$><!/><section role=group><!$><!/><!$><!/><!$><!/><!$><!/>`),
39
- _tmpl$22 = /*#__PURE__*/_$template(`<button type=button role=option tabindex=-1><span class=k2b-chat-composer__emoji-glyph aria-hidden=true></span><strong></strong><!$><!/>`),
40
- _tmpl$23 = /*#__PURE__*/_$template(`<small>:<!$><!/>:`),
41
- _tmpl$24 = /*#__PURE__*/_$template(`<button type=button role=option tabindex=-1><i aria-hidden=true></i><strong></strong><small>`),
42
- _tmpl$25 = /*#__PURE__*/_$template(`<span class=k2b-chat-composer__hint-text>`),
43
- _tmpl$26 = /*#__PURE__*/_$template(`<span class=k2b-chat-composer__dictation><i aria-hidden=true></i><span>`),
44
- _tmpl$27 = /*#__PURE__*/_$template(`<button type=button class=k2b-chat-composer__hint-action>`),
45
- _tmpl$28 = /*#__PURE__*/_$template(`<button type=button class=k2b-chat-composer__attachment-remove><i class="ti ti-x"aria-hidden=true>`),
46
- _tmpl$29 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__attachment role=listitem><div class=k2b-chat-composer__attachment-content><!$><!/><!$><!/></div><!$><!/>`),
47
- _tmpl$30 = /*#__PURE__*/_$template(`<img>`),
48
- _tmpl$31 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__attachment-identity><!$><!/><!$><!/>`),
49
- _tmpl$32 = /*#__PURE__*/_$template(`<a class=k2b-chat-composer__attachment-link target=_blank rel="noopener noreferrer"><!$><!/><!$><!/>`),
50
- _tmpl$33 = /*#__PURE__*/_$template(`<button type=button class=k2b-chat-composer__attachment-action><!$><!/><!$><!/>`),
51
- _tmpl$34 = /*#__PURE__*/_$template(`<footer class=k2b-chat-composer__footer>`),
52
- _tmpl$35 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__tools><!$><!/><!$><!/><!$><!/><!$><!/><!$><!/><!$><!/><!$><!/>`),
53
- _tmpl$36 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__submit><!$><!/><!$><!/><!$><!/><!$><!/><!$><!/>`);
54
- import { children, createEffect, createMemo, createSignal, createUniqueId, For, onCleanup, onMount, Show, untrack } from "solid-js";
28
+ _tmpl$11 = /*#__PURE__*/_$template(`<small>`),
29
+ _tmpl$12 = /*#__PURE__*/_$template(`<span class=k2b-chat-composer__command-end><i class="ti ti-check"aria-hidden=true></i><span class=k2b-sr-only>`),
30
+ _tmpl$13 = /*#__PURE__*/_$template(`<button class=k2b-chat-composer__command type=button role=option tabindex=-1><i aria-hidden=true></i><span class=k2b-chat-composer__command-text><strong></strong><!$><!/></span><!$><!/>`),
31
+ _tmpl$14 = /*#__PURE__*/_$template(`<b>`),
32
+ _tmpl$15 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer-accessory><div class=k2b-chat-composer__commands role=listbox>`),
33
+ _tmpl$16 = /*#__PURE__*/_$template(`<div role=status class=k2b-chat-composer__loading><i class="ti ti-loader-2 k2b-spin"aria-hidden=true></i><strong>`),
34
+ _tmpl$17 = /*#__PURE__*/_$template(`<div role=status><i class="ti ti-alert-circle"></i> <!$><!/>`),
35
+ _tmpl$18 = /*#__PURE__*/_$template(`<div role=status>`),
36
+ _tmpl$19 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer-accessory data-commands><div class=k2b-chat-composer__commands role=listbox><!$><!/><!$><!/><!$><!/><!$><!/>`),
37
+ _tmpl$20 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer-slot><div></div><!$><!/><!$><!/>`),
38
+ _tmpl$21 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__hint aria-live=polite>`),
39
+ _tmpl$22 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__attachments role=list tabindex=0>`),
40
+ _tmpl$23 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__error role=alert><i class="ti ti-alert-circle"aria-hidden=true></i><!$><!/>`),
41
+ _tmpl$24 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__row><!$><!/><!$><!/><div class=k2b-chat-composer__field><!$><!/><div class=k2b-chat-composer__field-tools><!$><!/><!$><!/><!$><!/></div></div><!$><!/>`),
42
+ _tmpl$25 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer-shell><!$><!/><section role=group><!$><!/><!$><!/><!$><!/><!$><!/></section><div class=k2b-sr-only role=status aria-live=polite></div><div class=k2b-chat-composer__status role=status><!$><!/><!$><!/>`),
43
+ _tmpl$26 = /*#__PURE__*/_$template(`<button type=button role=option tabindex=-1><span class=k2b-chat-composer__emoji-glyph aria-hidden=true></span><strong></strong><!$><!/>`),
44
+ _tmpl$27 = /*#__PURE__*/_$template(`<small>:<!$><!/>:`),
45
+ _tmpl$28 = /*#__PURE__*/_$template(`<i class="ti ti-loader-2 k2b-spin"aria-hidden=true>`),
46
+ _tmpl$29 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__command-placeholder aria-hidden=true><span></span><span><span></span><span>`),
47
+ _tmpl$30 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__command-group role=group><div class=k2b-chat-composer__command-heading role=presentation><span></span><!$><!/></div><!$><!/><!$><!/>`),
48
+ _tmpl$31 = /*#__PURE__*/_$template(`<span class=k2b-chat-composer__hint-text>`),
49
+ _tmpl$32 = /*#__PURE__*/_$template(`<span class=k2b-chat-composer__dictation><i aria-hidden=true></i><span>`),
50
+ _tmpl$33 = /*#__PURE__*/_$template(`<button type=button class=k2b-chat-composer__hint-action>`),
51
+ _tmpl$34 = /*#__PURE__*/_$template(`<button type=button class=k2b-chat-composer__attachment-remove><i class="ti ti-x"aria-hidden=true>`),
52
+ _tmpl$35 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__attachment role=listitem><div class=k2b-chat-composer__attachment-content><!$><!/><!$><!/></div><!$><!/>`),
53
+ _tmpl$36 = /*#__PURE__*/_$template(`<img>`),
54
+ _tmpl$37 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__attachment-identity><!$><!/><!$><!/>`),
55
+ _tmpl$38 = /*#__PURE__*/_$template(`<a class=k2b-chat-composer__attachment-link target=_blank rel="noopener noreferrer"><!$><!/><!$><!/>`),
56
+ _tmpl$39 = /*#__PURE__*/_$template(`<button type=button class=k2b-chat-composer__attachment-action><!$><!/><!$><!/>`),
57
+ _tmpl$40 = /*#__PURE__*/_$template(`<footer class=k2b-chat-composer__footer>`),
58
+ _tmpl$41 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__tools><!$><!/><!$><!/><!$><!/><!$><!/><!$><!/><!$><!/><!$><!/>`),
59
+ _tmpl$42 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__submit><!$><!/><!$><!/><!$><!/><!$><!/><!$><!/>`),
60
+ _tmpl$43 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__status-line><i aria-hidden=true></i><span>`),
61
+ _tmpl$44 = /*#__PURE__*/_$template(`<span class=k2b-sr-only>`);
62
+ import { batch, children, createEffect, createMemo, createSignal, createUniqueId, For, onCleanup, onMount, Show, untrack } from "solid-js";
55
63
  import { Dropdown } from "../actions/Dropdown";
64
+ import { dialogHistorySettled, holdDialogHistory } from "../feedback/dialog-core";
56
65
  import { Tooltip } from "../feedback/Tooltip";
57
66
  import { replaceTextareaRange } from "../inputs/editor-dom";
58
67
  import { completedEmojiShortcode, emojiInTone, emojiName, emojiShortcodeQuery, loadEmojiIndex, suggestEmoji } from "../inputs/emoji/emoji-index";
@@ -65,14 +74,25 @@ import { useSelectMessages } from "../inputs/select-messages";
65
74
  import { useLocale } from "../intl/locale";
66
75
  import { useUiMessages } from "../intl/messages";
67
76
  import { ChatContextUsage as ContextUsage } from "./ChatPrimitives";
68
- import { conversationEnterAction, executeChatAction, nextChatCommandIndex, reportChatFailure, runChatSubmission } from "./chat-behavior";
77
+ import { chatCommandKey, conversationEnterAction, executeChatAction, nextChatCommandIndex, reportChatFailure, runChatSubmission } from "./chat-behavior";
69
78
  import { useChatMessages } from "./chat-messages";
79
+ import { chatCommandListModel, parseChatCommandQuery } from "./command-search";
70
80
  import { chatCommandQuery, chatMentionSegments, reconcileChatMentions } from "./composer-document";
71
81
  const composerMaxInputHeight = 309;
82
+ const commandDoneMs = 3_000;
72
83
  /** Emoji suggestions for a `:shortcode`, as many as fit the list without scrolling on a phone. */
73
84
  const emojiSuggestionLimit = 8;
74
85
  // Keep editor undo text within approximately 2 MiB, plus the current edit.
75
86
  const composerUndoBudgetChars = 1_000_000;
87
+
88
+ /** An action can cancel and restore its token, or report a short completion message. */
89
+
90
+ /** A fixed place in the slash list. Sections keep the given order, also while searching. */
91
+
92
+ /** First-word narrowing; Tab writes `words[0]` followed by a space. */
93
+
94
+ /** Passed as the third argument to `searchCommands`. */
95
+
76
96
  /** The row stays short: what a chat message needs. Other Markdown, typed by hand, keeps working. */
77
97
  const formatTools = [{
78
98
  id: "bold",
@@ -103,21 +123,80 @@ const isTouchOnly = () => typeof matchMedia === "function" && matchMedia(touchOn
103
123
  const microphoneHoldMs = 500;
104
124
  /** Keeps the field focused (and a phone's keyboard open) when a composer button is pressed with a mouse or finger. */
105
125
  const keepFieldFocus = event => event.preventDefault();
126
+ /**
127
+ * Keeps one tap from reaching the page: its pointer, touch and mouse events stop at the window, and neither focus nor a
128
+ * click happens. A finger's tap ends with `touchend`, a scroll with `pointercancel`, a mouse's press with `click`.
129
+ */
130
+ const swallowTap = down => {
131
+ const blocked = ["pointerup", "pointercancel", "touchstart", "touchend", "mousedown", "mouseup", "click", "contextmenu"];
132
+ const stop = () => {
133
+ window.removeEventListener("pointerdown", next, true);
134
+ for (const type of blocked) window.removeEventListener(type, block, true);
135
+ };
136
+ const block = event => {
137
+ event.stopPropagation();
138
+ if (event.type !== "pointercancel" && event.type !== "touchstart" && event.type !== "pointerup") event.preventDefault();
139
+ if (event.type === "click" || event.type === "touchend" || event.type === "pointercancel") stop();
140
+ };
141
+ // The next press is a new gesture, whatever became of this one.
142
+ const next = event => {
143
+ if (event !== down) stop();
144
+ };
145
+ down.stopPropagation();
146
+ down.preventDefault();
147
+ window.addEventListener("pointerdown", next, true);
148
+ for (const type of blocked) window.addEventListener(type, block, {
149
+ capture: true,
150
+ passive: false
151
+ });
152
+ };
106
153
  const attachmentIcon = attachment => attachment.icon ?? (attachment.kind === "image" ? "ti ti-photo" : attachment.kind === "resource" ? "ti ti-link" : "ti ti-file");
107
154
  const hasContent = items => items.some(item => item != null && typeof item !== "boolean" && item !== "");
108
155
  export function ChatComposer(props) {
109
156
  const accessory = children(() => props.accessory);
110
157
  const hasAccessory = () => hasContent(accessory.toArray());
111
158
  const hint = children(() => props.hint);
159
+ const footer = children(() => props.footerContent);
112
160
  const messages = useUiMessages();
113
161
  const markdownToolbarMessages = useMarkdownToolbarMessages();
114
162
  const chatMessages = useChatMessages();
115
163
  const selectMessages = useSelectMessages();
116
164
  const commandListId = `k2b-chat-commands-${createUniqueId().replace(/[^A-Za-z0-9_-]/g, "-")}`;
117
165
  const formatGroupId = `${commandListId}-format`;
166
+ // Emoji suggestions keep their index-based selection and ids.
118
167
  const [selectedCommandIndex, setSelectedCommandIndex] = createSignal(0);
168
+ const [activeCommandKey, setActiveCommandKey] = createSignal();
169
+ const [commandMoved, setCommandMoved] = createSignal(false);
170
+ const commandIds = new Map();
171
+ let commandIdCounter = 0;
172
+ const commandOptionId = command => {
173
+ const key = chatCommandKey(command);
174
+ if (!commandIds.has(key)) commandIds.set(key, commandIdCounter++);
175
+ return `${commandListId}-c${commandIds.get(key)}`;
176
+ };
177
+ const [closedAt, setClosedAt] = createSignal();
178
+ // Where the pending native edit starts; a selection replaced as a whole starts at its beginning.
179
+ let inputStart;
180
+ let inputEnd;
181
+ const [commandStatus, setCommandStatus] = createSignal();
182
+ const [announcement, setAnnouncement] = createSignal();
183
+ let statusTimer;
184
+ let disposed = false;
185
+ const showCommandStatus = status => {
186
+ if (disposed) return;
187
+ clearTimeout(statusTimer);
188
+ setCommandStatus(status);
189
+ if (status?.tone === "done") {
190
+ statusTimer = setTimeout(() => setCommandStatus(undefined), commandDoneMs);
191
+ }
192
+ };
193
+ onCleanup(() => {
194
+ disposed = true;
195
+ clearTimeout(statusTimer);
196
+ });
119
197
  const [addingFiles, setAddingFiles] = createSignal(false);
120
198
  const [submitting, setSubmitting] = createSignal(false);
199
+ let shellRef;
121
200
  let composerRef;
122
201
  let textareaRef;
123
202
  let fileInputRef;
@@ -139,9 +218,51 @@ export function ChatComposer(props) {
139
218
  const [dismissed, setDismissed] = createSignal(false);
140
219
  const [composing, setComposing] = createSignal(false);
141
220
  const [searchResults, setSearchResults] = createSignal([]);
221
+ const [searchResultsQuery, setSearchResultsQuery] = createSignal();
222
+ const [searchResultsScope, setSearchResultsScope] = createSignal();
223
+ const [suggestionAnnouncement, setSuggestionAnnouncement] = createSignal();
142
224
  const [searching, setSearching] = createSignal(false);
143
225
  const [searchError, setSearchError] = createSignal(false);
144
226
  const [executing, setExecuting] = createSignal(false);
227
+ const [modelOpen, setModelOpen] = createSignal();
228
+ const [choosingModel, setChoosingModel] = createSignal(false);
229
+ let resolveModel;
230
+ const finishModelSelection = id => {
231
+ const resolve = resolveModel;
232
+ resolveModel = undefined;
233
+ if (choosingModel()) {
234
+ setModelOpen(false);
235
+ // Let the controlled close reach Dropdown before returning normal clicks to its own state.
236
+ queueMicrotask(() => {
237
+ if (!choosingModel()) setModelOpen(undefined);
238
+ });
239
+ }
240
+ setChoosingModel(false);
241
+ resolve?.(id);
242
+ };
243
+ const blockedBesidesCommand = () => Boolean(props.disabled || stopping() || state() === "submitting" || addingFiles() || submitting());
244
+ const usableModelControl = () => !conversation() && !footer() && !blockedBesidesCommand() && !running() && Boolean(props.models?.length && props.onModelChange);
245
+ const openModelSelection = () => {
246
+ if (!usableModelControl()) return Promise.resolve(null);
247
+ finishModelSelection(null);
248
+ return new Promise(resolve => {
249
+ resolveModel = resolve;
250
+ setChoosingModel(true);
251
+ setModelOpen(true);
252
+ queueMicrotask(() => {
253
+ if (!choosingModel() || !modelOpen()) return;
254
+ // Start on the current model, as a click on the chip would show it checked.
255
+ const menu = composerRef?.querySelector(".k2b-chat-composer__model");
256
+ (menu?.querySelector('[role="menuitemradio"][aria-checked="true"]:not(:disabled)') ?? menu?.querySelector('[role="menuitemradio"]:not(:disabled)'))?.focus();
257
+ });
258
+ });
259
+ };
260
+ createEffect(() => {
261
+ if (!usableModelControl()) finishModelSelection(null);
262
+ });
263
+ onCleanup(() => finishModelSelection(null));
264
+ const [commandOpening, setCommandOpening] = createSignal(0);
265
+ let retrySearch = false;
145
266
  let highlightRef;
146
267
  let commandListRef;
147
268
  const mentions = () => props.mentions ?? [];
@@ -158,27 +279,96 @@ export function ChatComposer(props) {
158
279
  return token && index ? suggestEmoji(index, token.query, emojiSuggestionLimit) : [];
159
280
  });
160
281
  const emojiOpen = () => emojiMatches().length > 0;
161
- const commandQuery = createMemo(() => dismissed() || composing() ? null : chatCommandQuery(props.value, caret(), selectionEnd()));
162
- const commandMatches = createMemo(() => {
163
- const token = commandQuery();
164
- if (!token) return [];
165
- return [...(props.commands ?? []).filter(command => command.name.toLowerCase().includes(token.query.toLowerCase())), ...searchResults()];
282
+ const caretCommandToken = createMemo(() => chatCommandQuery(props.value, caret(), selectionEnd()));
283
+ const caretCommandStart = createMemo(() => caretCommandToken()?.start);
284
+ // Retained server rows belong to one `/`: they go when it does or when another `/` starts.
285
+ createEffect(() => {
286
+ caretCommandStart();
287
+ setSearchResults([]);
288
+ setSearchResultsQuery(undefined);
289
+ });
290
+ // Escape closes the list for one `/` character, wherever the caret or selection goes; only that `/` going away ends it.
291
+ createEffect(() => {
292
+ const closed = closedAt();
293
+ if (closed !== undefined && props.value[closed] !== "/") setClosedAt(undefined);
294
+ });
295
+ const commandQuery = createMemo(() => {
296
+ const token = caretCommandToken();
297
+ return dismissed() || composing() || token?.start === closedAt() ? null : token;
298
+ });
299
+ const openingStart = createMemo(() => commandQuery()?.start);
300
+ createEffect(() => {
301
+ props.draftKey;
302
+ const start = openingStart();
303
+ if (start !== undefined) setCommandOpening(opening => opening + 1);
304
+ });
305
+ const parsedCommandQuery = createMemo(() => parseChatCommandQuery(commandQuery()?.query ?? "", props.commandScopes ?? []));
306
+ const currentCommandScope = createMemo(() => parsedCommandQuery().scope?.id);
307
+ createEffect(() => {
308
+ currentCommandScope();
309
+ setSearchResults([]);
310
+ setSearchResultsQuery(undefined);
311
+ });
312
+ const localCommands = createMemo(() => props.commands ?? []);
313
+ const commandModel = createMemo(() => chatCommandListModel({
314
+ query: commandQuery()?.query ?? "",
315
+ scopes: props.commandScopes,
316
+ sections: props.commandSections,
317
+ commands: localCommands(),
318
+ searchResults: searchResultsScope() === parsedCommandQuery().scope?.id ? searchResults() : [],
319
+ searchResultsFresh: searchResultsQuery() === commandQuery()?.query && searchResultsScope() === parsedCommandQuery().scope?.id,
320
+ searchSettled: searchResultsQuery() !== undefined && searchResultsScope() === parsedCommandQuery().scope?.id,
321
+ searching: searching()
322
+ }));
323
+ const commandMatches = createMemo(() => commandQuery() ? commandModel().rows.map(row => row.command) : []);
324
+ const currentCommandQuery = createMemo(() => caretCommandToken()?.query);
325
+ // Arrow marking belongs to one token in one draft; another draft or `/` starts at the top row again.
326
+ createEffect(() => {
327
+ props.draftKey;
328
+ caretCommandStart();
329
+ currentCommandQuery();
330
+ setCommandMoved(false);
331
+ });
332
+ const commandsOpen = () => Boolean(!emojiOpen() && commandQuery() && (localCommands().length || props.searchCommands));
333
+ const commandSheetHeld = createMemo(() => commandsOpen() && isTouchOnly());
334
+ createEffect(() => {
335
+ if (!commandSheetHeld()) return;
336
+ onCleanup(holdDialogHistory(() => setClosedAt(commandQuery()?.start)));
166
337
  });
167
- const commandsOpen = () => Boolean(!emojiOpen() && commandQuery() && (props.commands?.length || props.searchCommands));
168
338
  const suggestionsOpen = () => commandsOpen() || emojiOpen();
169
339
  createEffect(() => {
170
340
  if (!suggestionsOpen()) return;
171
341
  let disposed = false;
172
342
  const measure = () => {
173
343
  if (disposed || !commandListRef) return;
174
- let top = window.visualViewport?.offsetTop ?? 0;
175
- for (let parent = commandListRef.parentElement; parent; parent = parent.parentElement) {
176
- if (/(auto|scroll|hidden|clip)/.test(window.getComputedStyle(parent).overflowY)) {
344
+ const accessory = commandListRef.parentElement;
345
+ const viewportTop = window.visualViewport?.offsetTop ?? 0;
346
+ let top = viewportTop;
347
+ // The column a phone sheet spans: the nearest ancestor that clips sideways, or the page.
348
+ let column;
349
+ for (let parent = accessory.parentElement; parent; parent = parent.parentElement) {
350
+ const style = window.getComputedStyle(parent);
351
+ if (/(auto|scroll|hidden|clip)/.test(style.overflowY)) {
177
352
  top = Math.max(top, parent.getBoundingClientRect().top);
178
353
  }
354
+ if (!column && /(auto|scroll|hidden|clip)/.test(style.overflowX)) {
355
+ const left = parent.getBoundingClientRect().left + parent.clientLeft;
356
+ column = {
357
+ left,
358
+ right: left + parent.clientWidth
359
+ };
360
+ }
179
361
  }
180
- const bottom = commandListRef.parentElement.getBoundingClientRect().bottom;
362
+ const page = document.documentElement.clientWidth;
363
+ const left = Math.max(0, column?.left ?? 0);
364
+ const right = Math.min(page, column?.right ?? page);
365
+ const slot = accessory.parentElement.getBoundingClientRect();
366
+ const bottom = accessory.getBoundingClientRect().bottom;
181
367
  commandListRef.style.setProperty("--k2b-chat-command-space", `${Math.max(40, bottom - top - 8)}px`);
368
+ // Only a list that reaches the screen's top edge keeps clear of a notch or the status bar.
369
+ commandListRef.style.setProperty("--k2b-chat-command-safe-top", top === viewportTop ? "env(safe-area-inset-top, 0px)" : "0px");
370
+ accessory.style.setProperty("--k2b-chat-command-reach-left", `${Math.max(0, slot.left - left)}px`);
371
+ accessory.style.setProperty("--k2b-chat-command-reach-right", `${Math.max(0, right - slot.right)}px`);
182
372
  };
183
373
  queueMicrotask(measure);
184
374
  window.addEventListener("resize", measure);
@@ -191,30 +381,108 @@ export function ChatComposer(props) {
191
381
  window.visualViewport?.removeEventListener("resize", measure);
192
382
  });
193
383
  });
384
+ // A press outside the command list and the field closes the list, as Escape does; the text stays. With a mouse or a
385
+ // trackpad the press then acts as usual. On a touch-only device a tap outside the composer closes only the list: it
386
+ // reaches nothing beneath, and the field keeps focus, so the keyboard stays open.
194
387
  createEffect(() => {
388
+ if (!commandsOpen()) return;
389
+ const onPointerDown = event => {
390
+ const target = event.target;
391
+ if (!(target instanceof Node) || commandListRef?.contains(target) || textareaRef?.parentElement?.contains(target)) return;
392
+ setClosedAt(commandQuery()?.start);
393
+ if (isTouchOnly() && !shellRef?.contains(target)) swallowTap(event);
394
+ };
395
+ window.addEventListener("pointerdown", onPointerDown, true);
396
+ onCleanup(() => window.removeEventListener("pointerdown", onPointerDown, true));
397
+ });
398
+ createEffect(() => {
399
+ props.draftKey;
195
400
  const token = commandQuery();
196
- setSearchResults([]);
197
401
  setSearchError(false);
198
402
  if (!token || !props.searchCommands) {
199
403
  setSearching(false);
200
404
  return;
201
405
  }
406
+ running();
407
+ const parsed = parsedCommandQuery();
408
+ const opening = commandOpening();
202
409
  const abort = new AbortController();
203
410
  setSearching(true);
411
+ const delay = retrySearch ? 0 : 120;
412
+ retrySearch = false;
204
413
  const timer = setTimeout(() => {
205
- Promise.resolve(props.searchCommands(token.query, abort.signal)).then(results => {
206
- if (!abort.signal.aborted) setSearchResults(results);
414
+ Promise.resolve().then(() => props.searchCommands(parsed.query, abort.signal, {
415
+ scope: parsed.scope?.id,
416
+ opening
417
+ })).then(results => {
418
+ if (!abort.signal.aborted) {
419
+ batch(() => {
420
+ setSearchResults(results);
421
+ setSearchResultsQuery(token.query);
422
+ setSearchResultsScope(parsed.scope?.id);
423
+ });
424
+ }
207
425
  }).catch(() => {
208
- if (!abort.signal.aborted) setSearchError(true);
426
+ if (!abort.signal.aborted) {
427
+ setSearchResults([]);
428
+ setSearchResultsQuery(undefined);
429
+ setSearchError(true);
430
+ }
209
431
  }).finally(() => {
210
432
  if (!abort.signal.aborted) setSearching(false);
211
433
  });
212
- }, 120);
434
+ }, delay);
213
435
  onCleanup(() => {
214
436
  clearTimeout(timer);
215
437
  abort.abort();
216
438
  });
217
439
  });
440
+ let settledEmpty;
441
+ createEffect(() => {
442
+ const token = commandQuery();
443
+ if (!token || parsedCommandQuery().scope || searchError()) {
444
+ settledEmpty = undefined;
445
+ return;
446
+ }
447
+ const previous = settledEmpty;
448
+ if (/\s$/.test(token.query) && previous?.start === token.start && previous.query.trimEnd() === token.query.trimEnd()) {
449
+ setClosedAt(token.start);
450
+ return;
451
+ }
452
+ const settled = !searching() && (!props.searchCommands || searchResultsQuery() === token.query);
453
+ if (settled && commandModel().empty) {
454
+ settledEmpty = {
455
+ start: token.start,
456
+ query: token.query
457
+ };
458
+ if (/\s$/.test(token.query)) setClosedAt(token.start);
459
+ } else if (!searching()) settledEmpty = undefined;
460
+ });
461
+ let lastSuggestion;
462
+ createEffect(() => {
463
+ const model = commandModel();
464
+ const query = commandQuery()?.query;
465
+ if (!commandsOpen()) {
466
+ setSuggestionAnnouncement(undefined);
467
+ lastSuggestion = undefined;
468
+ return;
469
+ }
470
+ if (searching() || searchError() || props.searchCommands && searchResultsQuery() !== query) return;
471
+ const text = chatMessages().commandSuggestions({
472
+ count: model.rows.length
473
+ });
474
+ const timer = setTimeout(() => {
475
+ if (lastSuggestion && lastSuggestion.query === query && lastSuggestion.text === text) return;
476
+ lastSuggestion = {
477
+ query: query ?? "",
478
+ text
479
+ };
480
+ setSuggestionAnnouncement({
481
+ text
482
+ });
483
+ }, 350);
484
+ onCleanup(() => clearTimeout(timer));
485
+ });
218
486
  const history = [];
219
487
  let historyIndex = -1;
220
488
  createEffect(() => {
@@ -222,7 +490,13 @@ export function ChatComposer(props) {
222
490
  untrack(() => {
223
491
  history.length = 0;
224
492
  historyIndex = -1;
493
+ finishModelSelection(null);
225
494
  setDismissed(true);
495
+ setClosedAt(undefined);
496
+ setSearchResults([]);
497
+ setSearchResultsQuery(undefined);
498
+ // A failure belongs to the draft it happened in; success notes may follow a command into the chat it opened.
499
+ if (commandStatus()?.tone === "error") showCommandStatus();
226
500
  });
227
501
  });
228
502
  const snapshot = () => ({
@@ -241,6 +515,23 @@ export function ChatComposer(props) {
241
515
  }
242
516
  };
243
517
  const edit = (value, nextMentions = reconcileChatMentions(props.value, value, mentions())) => {
518
+ if (commandStatus()?.tone === "error") showCommandStatus();
519
+ // Replacing `/` can leave its position and query identical, but starts a new opening.
520
+ if (inputStart !== undefined && inputEnd !== undefined && props.value.slice(inputStart, inputEnd).includes("/")) {
521
+ setCommandOpening(opening => opening + 1);
522
+ setSearchResults([]);
523
+ setSearchResultsQuery(undefined);
524
+ setCommandMoved(false);
525
+ }
526
+ // An edit that starts at or before the closed `/` (select all, then type `/`) replaces it; the new `/` may open again.
527
+ const closed = closedAt();
528
+ if (closed !== undefined) {
529
+ let same = 0;
530
+ while (same <= closed && props.value[same] === value[same]) same++;
531
+ if (Math.min(same, inputStart ?? same) <= closed) setClosedAt(undefined);
532
+ }
533
+ inputStart = undefined;
534
+ inputEnd = undefined;
244
535
  record();
245
536
  props.onValueChange(value);
246
537
  props.onMentionsChange?.(nextMentions);
@@ -260,16 +551,33 @@ export function ChatComposer(props) {
260
551
  });
261
552
  };
262
553
  const syncCaret = () => {
263
- setCaret(textareaRef?.selectionStart ?? props.value.length);
264
- setSelectionEnd(textareaRef?.selectionEnd ?? props.value.length);
554
+ // One update, so no effect sees a half-moved selection (it would read as "no `/` here" and reopen a closed list).
555
+ batch(() => {
556
+ setCaret(textareaRef?.selectionStart ?? props.value.length);
557
+ setSelectionEnd(textareaRef?.selectionEnd ?? props.value.length);
558
+ });
265
559
  };
266
- const selectedCommand = () => commandMatches()[selectedCommandIndex()];
560
+ const selectedCommand = createMemo(() => {
561
+ const rows = commandMatches();
562
+ return commandMoved() && rows.find(command => chatCommandKey(command) === activeCommandKey()) || rows[0];
563
+ });
564
+ const selectedCommandKey = createMemo(() => {
565
+ const command = selectedCommand();
566
+ return command ? chatCommandKey(command) : undefined;
567
+ });
568
+ createEffect(() => {
569
+ if (!commandsOpen()) commandIds.clear();
570
+ selectedCommandKey();
571
+ setAnnouncement(undefined);
572
+ });
267
573
  const busy = () => Boolean(props.disabled || stopping() || state() === "submitting" || executing() || addingFiles());
268
574
  const blocked = () => busy() || submitting();
269
575
  /** The conversation field stays editable while a message is sent, so it keeps the focus and a phone its keyboard. */
270
576
  const editBlocked = () => conversation() ? busy() : blocked();
271
577
  const hasDraft = () => Boolean(props.value.trim() || !running() && attachments().length > 0);
272
- const canSubmit = () => !blocked() && hasDraft() && !(running() && runningSubmitIntent() === "steer" && mentions().length);
578
+ /** The draft may go out now, apart from a submission that is already on its way. */
579
+ const submittable = () => !busy() && hasDraft() && !(running() && runningSubmitIntent() === "steer" && mentions().length);
580
+ const canSubmit = () => !submitting() && submittable();
273
581
  const canSelectFiles = () => Boolean(props.fileSelection && !props.fileSelection.disabled && !running() && !blocked());
274
582
  const hasAddMenu = () => Boolean(props.fileSelection || props.menuActions?.length);
275
583
  const hasContextUsage = () => {
@@ -326,21 +634,23 @@ export function ChatComposer(props) {
326
634
  }
327
635
  });
328
636
  createEffect(() => {
329
- commandMatches();
330
637
  emojiMatches();
331
638
  setSelectedCommandIndex(0);
332
639
  });
333
640
  createEffect(() => {
334
- const index = selectedCommandIndex();
335
- commandMatches();
336
- emojiMatches();
641
+ const command = selectedCommand();
642
+ const id = emojiOpen() ? `${commandListId}-${selectedCommandIndex()}` : command ? commandOptionId(command) : undefined;
337
643
  queueMicrotask(() => {
338
644
  const list = commandListRef;
339
- const item = list?.querySelector(`[id="${commandListId}-${index}"]`);
645
+ const item = id ? list?.querySelector(`[id="${id}"]`) : undefined;
340
646
  if (!list || !item?.isConnected) return;
341
- if (item.offsetTop < list.scrollTop) list.scrollTop = item.offsetTop;else if (item.offsetTop + item.offsetHeight > list.scrollTop + list.clientHeight) {
342
- list.scrollTop = item.offsetTop + item.offsetHeight - list.clientHeight;
343
- }
647
+ // Measured against the visible part of the list: a sticky section heading covers the top of it.
648
+ const heading = item.closest(".k2b-chat-composer__command-group")?.querySelector(".k2b-chat-composer__command-heading");
649
+ const listTop = list.getBoundingClientRect().top + list.clientTop;
650
+ const box = item.getBoundingClientRect();
651
+ const top = box.top - listTop - (heading?.offsetHeight ?? 0);
652
+ const bottom = box.bottom - listTop - list.clientHeight;
653
+ if (top < 0) list.scrollTop += top;else if (bottom > 0) list.scrollTop += bottom;
344
654
  });
345
655
  });
346
656
  createEffect(() => {
@@ -393,18 +703,26 @@ export function ChatComposer(props) {
393
703
  };
394
704
  const submit = async () => {
395
705
  if (!canSubmit()) return;
396
- const intent = running() ? runningSubmitIntent() : "send";
397
- const previousValue = props.value;
398
- const previousAttachments = attachments();
399
- const previousMentions = mentions();
400
- const input = {
401
- intent,
402
- text: previousValue,
403
- mentions: previousMentions,
404
- attachments: intent !== "steer" ? previousAttachments : []
405
- };
706
+ const key = props.draftKey;
406
707
  setSubmitting(true);
407
708
  try {
709
+ if (isTouchOnly()) {
710
+ if (commandSheetHeld()) setClosedAt(commandQuery()?.start);
711
+ // The sheet's Back entry leaves first, so a submit handler that navigates finds the history settled.
712
+ await dialogHistorySettled();
713
+ // A draft that another one replaced, or that may no longer go out, is not sent and keeps its text.
714
+ if (disposed || props.draftKey !== key || !submittable()) return;
715
+ }
716
+ const intent = running() ? runningSubmitIntent() : "send";
717
+ const previousValue = props.value;
718
+ const previousAttachments = attachments();
719
+ const previousMentions = mentions();
720
+ const input = {
721
+ intent,
722
+ text: previousValue,
723
+ mentions: previousMentions,
724
+ attachments: intent !== "steer" ? previousAttachments : []
725
+ };
408
726
  await runChatSubmission({
409
727
  clear: () => {
410
728
  props.onValueChange("");
@@ -436,9 +754,32 @@ export function ChatComposer(props) {
436
754
  });
437
755
  }
438
756
  };
439
- const executeCommand = async command => {
757
+ const narrowCommand = command => {
758
+ const scope = props.commandScopes?.find(scope => scope.id === command.scope);
759
+ const word = scope?.words[0];
440
760
  const token = commandQuery();
441
- if (!token || command.disabled || blocked()) return;
761
+ if (!word || !token || !textareaRef) return false;
762
+ replaceTextareaRange(textareaRef, token.start + 1, token.end, `${word} `);
763
+ syncCaret();
764
+ return true;
765
+ };
766
+ const executeCommand = async (command, tab = false) => {
767
+ const token = commandQuery();
768
+ const heldHistory = commandSheetHeld();
769
+ if (!token || blocked()) return;
770
+ if (command.disabled || command.reason) {
771
+ // A new object each time, so choosing the same row again inserts and announces its reason again.
772
+ setAnnouncement(command.reason ? {
773
+ text: command.reason
774
+ } : undefined);
775
+ return;
776
+ }
777
+ if (command.searchAgain) {
778
+ retrySearch = true;
779
+ setCommandOpening(opening => opening + 1);
780
+ return;
781
+ }
782
+ if (command.scope && (tab || !command.action && !command.mention) && narrowCommand(command)) return;
442
783
  const previous = snapshot();
443
784
  const key = props.draftKey;
444
785
  const replacement = command.mention ? command.mention.name + " " : "";
@@ -449,32 +790,73 @@ export function ChatComposer(props) {
449
790
  end: token.start + command.mention.name.length,
450
791
  attachment: command.mention
451
792
  });
793
+ // A cancelled or failed command leaves no undo step behind: restoring puts the history back as well.
794
+ const previousHistory = {
795
+ entries: [...history],
796
+ index: historyIndex
797
+ };
452
798
  edit(nextValue, nextMentions);
453
799
  setDismissed(true);
454
800
  setExecuting(true);
455
801
  let submitRequested = false;
802
+ let restored = false;
803
+ const restore = () => {
804
+ if (props.draftKey !== key || props.value !== nextValue) return;
805
+ setDismissed(true);
806
+ props.onValueChange(previous.value);
807
+ props.onMentionsChange?.(previous.mentions);
808
+ history.splice(0, history.length, ...previousHistory.entries);
809
+ historyIndex = previousHistory.index;
810
+ restored = true;
811
+ };
812
+ showCommandStatus(command.busyLabel ? {
813
+ tone: "busy",
814
+ text: command.busyLabel
815
+ } : undefined);
456
816
  try {
457
- await command.action?.({
817
+ // The sheet's Back entry leaves first, so an action that navigates or opens a dialog finds the history settled.
818
+ if (heldHistory && command.action) {
819
+ await dialogHistorySettled();
820
+ // Another draft or no composer any more: the command does not run against it.
821
+ if (disposed || props.draftKey !== key) return;
822
+ }
823
+ const result = await command.action?.({
458
824
  setValue: value => edit(value),
459
825
  submit: () => {
460
826
  submitRequested = true;
461
827
  },
462
- focus
828
+ focus,
829
+ openModelSelection
463
830
  });
831
+ if (result === "cancelled") {
832
+ submitRequested = false;
833
+ restore();
834
+ showCommandStatus();
835
+ } else if (result) {
836
+ showCommandStatus({
837
+ tone: "done",
838
+ text: result.done
839
+ });
840
+ }
464
841
  } catch (error) {
465
842
  submitRequested = false;
466
- if (props.draftKey === key && props.value === nextValue) {
467
- props.onValueChange(previous.value);
468
- props.onMentionsChange?.(previous.mentions);
469
- }
470
- props.onError?.(error);
843
+ restore();
844
+ // An unmounted composer has no status line left; the app's error channel keeps the failure from going silent.
845
+ if (disposed) props.onError?.(error);else showCommandStatus({
846
+ tone: "error",
847
+ text: error instanceof Error && error.message ? error.message : chatMessages().commandFailed
848
+ });
471
849
  } finally {
850
+ if (commandStatus()?.tone === "busy") showCommandStatus();
472
851
  setExecuting(false);
473
852
  }
474
853
  if (submitRequested && props.draftKey === key) await submit();
475
854
  queueMicrotask(() => {
476
855
  if (props.draftKey !== key) return;
477
- textareaRef?.setSelectionRange(token.start + replacement.length, token.start + replacement.length);
856
+ if (restored || props.value === nextValue) {
857
+ const position = restored ? token.end : token.start + replacement.length;
858
+ textareaRef?.setSelectionRange(position, position);
859
+ }
478
860
  syncCaret();
479
861
  autoResize();
480
862
  focus();
@@ -552,19 +934,28 @@ export function ChatComposer(props) {
552
934
  if (commandsOpen()) {
553
935
  if (event.key === "ArrowUp" || event.key === "ArrowDown") {
554
936
  event.preventDefault();
555
- setSelectedCommandIndex(index => nextChatCommandIndex(index, matches.length, event.key === "ArrowUp" ? -1 : 1));
937
+ const index = matches.indexOf(selectedCommand());
938
+ const next = matches[nextChatCommandIndex(index, matches.length, event.key === "ArrowUp" ? -1 : 1)];
939
+ setActiveCommandKey(next ? chatCommandKey(next) : undefined);
940
+ setCommandMoved(true);
941
+ setAnnouncement(undefined);
556
942
  return;
557
943
  }
558
944
  // Ctrl/⌘+Enter sends, also while suggestions are open.
559
- if ((event.key === "Tab" || event.key === "Enter" && !event.ctrlKey && !event.metaKey) && matches.length > 0) {
945
+ const plain = !event.shiftKey && !event.altKey && !event.ctrlKey && !event.metaKey;
946
+ if (plain && (event.key === "Tab" || event.key === "Enter") && matches.length > 0) {
560
947
  event.preventDefault();
561
948
  const command = selectedCommand();
562
- if (command) void executeCommand(command);
949
+ // A server row answering an earlier query may no longer match; wait for fresh results. Local rows match now.
950
+ const row = commandModel().rows.find(row => chatCommandKey(row.command) === selectedCommandKey());
951
+ const staleServerRow = row?.server && (searchResultsQuery() !== commandQuery()?.query || searchResultsScope() !== parsedCommandQuery().scope?.id);
952
+ if (staleServerRow) return;
953
+ if (command) void executeCommand(command, event.key === "Tab");
563
954
  return;
564
955
  }
565
956
  if (event.key === "Escape") {
566
957
  event.preventDefault();
567
- setDismissed(true);
958
+ setClosedAt(commandQuery()?.start);
568
959
  return;
569
960
  }
570
961
  }
@@ -1043,6 +1434,8 @@ export function ChatComposer(props) {
1043
1434
  }), _el$25, _co$4);
1044
1435
  _el$22.$$keydown = onKeyDown;
1045
1436
  _el$22.$$beforeinput = event => {
1437
+ inputStart = event.currentTarget.selectionStart;
1438
+ inputEnd = event.currentTarget.selectionEnd;
1046
1439
  if (event.inputType === "historyUndo" || event.inputType === "historyRedo") {
1047
1440
  event.preventDefault();
1048
1441
  restoreHistory(event.inputType === "historyUndo" ? -1 : 1);
@@ -1073,8 +1466,10 @@ export function ChatComposer(props) {
1073
1466
  props.onPaste?.(event);
1074
1467
  });
1075
1468
  _el$22.$$input = event => {
1076
- edit(event.currentTarget.value);
1077
- syncCaret();
1469
+ batch(() => {
1470
+ edit(event.currentTarget.value);
1471
+ syncCaret();
1472
+ });
1078
1473
  autoResize();
1079
1474
  const input = event;
1080
1475
  if (input.inputType === "insertText" && input.data === ":") queueMicrotask(completeShortcode);
@@ -1103,7 +1498,7 @@ export function ChatComposer(props) {
1103
1498
  _v$0 = suggestionsOpen() ? "list" : undefined,
1104
1499
  _v$1 = suggestionsOpen() ? commandListId : undefined,
1105
1500
  _v$10 = suggestionsOpen() ? "true" : undefined,
1106
- _v$11 = (emojiOpen() ? emojiMatches()[selectedCommandIndex()] : selectedCommand()) ? `${commandListId}-${selectedCommandIndex()}` : undefined;
1501
+ _v$11 = emojiOpen() ? `${commandListId}-${selectedCommandIndex()}` : selectedCommand() ? commandOptionId(selectedCommand()) : undefined;
1107
1502
  _v$3 !== _p$.e && _$setAttribute(_el$17, "aria-label", _p$.e = _v$3);
1108
1503
  _v$4 !== _p$.t && _el$22.classList.toggle("k2b-chat-composer__textarea--highlighted", _p$.t = _v$4);
1109
1504
  _v$5 !== _p$.a && _$setProperty(_el$22, "disabled", _p$.a = _v$5);
@@ -1133,78 +1528,170 @@ export function ChatComposer(props) {
1133
1528
  _$runHydrationEvents();
1134
1529
  return _el$17;
1135
1530
  })();
1531
+ const commandRowMap = createMemo(() => new Map(commandModel().rows.map(row => [row.command, row])));
1532
+ const commandGroupKey = group => group.scopeTitle ? "scope" : group.section ? `section:${group.section.id}` : "flat";
1533
+ const renderCommandRow = command => {
1534
+ const highlight = () => commandRowMap().get(command)?.highlight;
1535
+ const title = () => command.label ?? command.name;
1536
+ return (() => {
1537
+ var _el$29 = _$getNextElement(_tmpl$13),
1538
+ _el$30 = _el$29.firstChild,
1539
+ _el$31 = _el$30.nextSibling,
1540
+ _el$32 = _el$31.firstChild,
1541
+ _el$34 = _el$32.nextSibling,
1542
+ [_el$35, _co$6] = _$getNextMarker(_el$34.nextSibling),
1543
+ _el$39 = _el$31.nextSibling,
1544
+ [_el$40, _co$7] = _$getNextMarker(_el$39.nextSibling);
1545
+ _el$29.$$click = event => {
1546
+ event.preventDefault();
1547
+ void executeCommand(command);
1548
+ };
1549
+ _el$29.$$mousedown = keepFieldFocus;
1550
+ _$insert(_el$32, _$createComponent(Show, {
1551
+ get when() {
1552
+ return highlight();
1553
+ },
1554
+ get fallback() {
1555
+ return title();
1556
+ },
1557
+ children: range => [_$memo(() => title().slice(0, range()[0])), (() => {
1558
+ var _el$41 = _$getNextElement(_tmpl$14);
1559
+ _$insert(_el$41, () => title().slice(range()[0], range()[1]));
1560
+ return _el$41;
1561
+ })(), _$memo(() => title().slice(range()[1]))]
1562
+ }));
1563
+ _$insert(_el$31, _$createComponent(Show, {
1564
+ get when() {
1565
+ return command.reason ?? command.description;
1566
+ },
1567
+ get children() {
1568
+ var _el$33 = _$getNextElement(_tmpl$11);
1569
+ _$insert(_el$33, () => command.reason ?? command.description);
1570
+ _$effect(() => _$setAttribute(_el$33, "id", command.reason ? `${commandOptionId(command)}-reason` : undefined));
1571
+ return _el$33;
1572
+ }
1573
+ }), _el$35, _co$6);
1574
+ _$insert(_el$29, _$createComponent(Show, {
1575
+ get when() {
1576
+ return command.selected;
1577
+ },
1578
+ get children() {
1579
+ var _el$36 = _$getNextElement(_tmpl$12),
1580
+ _el$37 = _el$36.firstChild,
1581
+ _el$38 = _el$37.nextSibling;
1582
+ _$insert(_el$38, () => chatMessages().commandSelected);
1583
+ return _el$36;
1584
+ }
1585
+ }), _el$40, _co$7);
1586
+ _$effect(_p$ => {
1587
+ var _v$12 = commandOptionId(command),
1588
+ _v$13 = selectedCommand() === command,
1589
+ _v$14 = Boolean(command.disabled || command.reason),
1590
+ _v$15 = command.reason ? `${commandOptionId(command)}-reason` : undefined,
1591
+ _v$16 = command.reason ? "true" : undefined,
1592
+ _v$17 = selectedCommand() === command ? "true" : undefined,
1593
+ _v$18 = command.icon ?? "ti ti-slash";
1594
+ _v$12 !== _p$.e && _$setAttribute(_el$29, "id", _p$.e = _v$12);
1595
+ _v$13 !== _p$.t && _$setAttribute(_el$29, "aria-selected", _p$.t = _v$13);
1596
+ _v$14 !== _p$.a && _$setAttribute(_el$29, "aria-disabled", _p$.a = _v$14);
1597
+ _v$15 !== _p$.o && _$setAttribute(_el$29, "aria-describedby", _p$.o = _v$15);
1598
+ _v$16 !== _p$.i && _$setAttribute(_el$29, "data-reason", _p$.i = _v$16);
1599
+ _v$17 !== _p$.n && _$setAttribute(_el$29, "data-active", _p$.n = _v$17);
1600
+ _v$18 !== _p$.s && _$className(_el$30, _p$.s = _v$18);
1601
+ return _p$;
1602
+ }, {
1603
+ e: undefined,
1604
+ t: undefined,
1605
+ a: undefined,
1606
+ o: undefined,
1607
+ i: undefined,
1608
+ n: undefined,
1609
+ s: undefined
1610
+ });
1611
+ _$runHydrationEvents();
1612
+ return _el$29;
1613
+ })();
1614
+ };
1136
1615
  return (() => {
1137
- var _el$29 = _$getNextElement(_tmpl$21),
1138
- _el$89 = _el$29.firstChild,
1139
- [_el$90, _co$23] = _$getNextMarker(_el$89.nextSibling),
1140
- _el$57 = _el$90.nextSibling,
1141
- _el$81 = _el$57.firstChild,
1142
- [_el$82, _co$19] = _$getNextMarker(_el$81.nextSibling),
1143
- _el$83 = _el$82.nextSibling,
1144
- [_el$84, _co$20] = _$getNextMarker(_el$83.nextSibling),
1145
- _el$85 = _el$84.nextSibling,
1146
- [_el$86, _co$21] = _$getNextMarker(_el$85.nextSibling),
1147
- _el$87 = _el$86.nextSibling,
1148
- [_el$88, _co$22] = _$getNextMarker(_el$87.nextSibling);
1149
- _$insert(_el$29, _$createComponent(Show, {
1616
+ var _el$42 = _$getNextElement(_tmpl$25),
1617
+ _el$108 = _el$42.firstChild,
1618
+ [_el$109, _co$27] = _$getNextMarker(_el$108.nextSibling),
1619
+ _el$70 = _el$109.nextSibling,
1620
+ _el$94 = _el$70.firstChild,
1621
+ [_el$95, _co$21] = _$getNextMarker(_el$94.nextSibling),
1622
+ _el$96 = _el$95.nextSibling,
1623
+ [_el$97, _co$22] = _$getNextMarker(_el$96.nextSibling),
1624
+ _el$98 = _el$97.nextSibling,
1625
+ [_el$99, _co$23] = _$getNextMarker(_el$98.nextSibling),
1626
+ _el$100 = _el$99.nextSibling,
1627
+ [_el$101, _co$24] = _$getNextMarker(_el$100.nextSibling),
1628
+ _el$102 = _el$70.nextSibling,
1629
+ _el$103 = _el$102.nextSibling,
1630
+ _el$104 = _el$103.firstChild,
1631
+ [_el$105, _co$25] = _$getNextMarker(_el$104.nextSibling),
1632
+ _el$106 = _el$105.nextSibling,
1633
+ [_el$107, _co$26] = _$getNextMarker(_el$106.nextSibling);
1634
+ var _ref$6 = shellRef;
1635
+ typeof _ref$6 === "function" ? _$use(_ref$6, _el$42) : shellRef = _el$42;
1636
+ _$insert(_el$42, _$createComponent(Show, {
1150
1637
  get when() {
1151
1638
  return suggestionsOpen() || hasAccessory();
1152
1639
  },
1153
1640
  get children() {
1154
- var _el$30 = _$getNextElement(_tmpl$16),
1155
- _el$31 = _el$30.firstChild,
1156
- _el$53 = _el$31.nextSibling,
1157
- [_el$54, _co$1] = _$getNextMarker(_el$53.nextSibling),
1158
- _el$55 = _el$54.nextSibling,
1159
- [_el$56, _co$10] = _$getNextMarker(_el$55.nextSibling);
1160
- _$insert(_el$31, accessory);
1161
- _$insert(_el$30, _$createComponent(Show, {
1641
+ var _el$43 = _$getNextElement(_tmpl$20),
1642
+ _el$44 = _el$43.firstChild,
1643
+ _el$66 = _el$44.nextSibling,
1644
+ [_el$67, _co$11] = _$getNextMarker(_el$66.nextSibling),
1645
+ _el$68 = _el$67.nextSibling,
1646
+ [_el$69, _co$12] = _$getNextMarker(_el$68.nextSibling);
1647
+ _$insert(_el$44, accessory);
1648
+ _$insert(_el$43, _$createComponent(Show, {
1162
1649
  get when() {
1163
1650
  return emojiOpen();
1164
1651
  },
1165
1652
  get children() {
1166
- var _el$32 = _$getNextElement(_tmpl$11),
1167
- _el$33 = _el$32.firstChild;
1168
- var _ref$6 = commandListRef;
1169
- typeof _ref$6 === "function" ? _$use(_ref$6, _el$33) : commandListRef = _el$33;
1170
- _$setAttribute(_el$33, "id", commandListId);
1171
- _$insert(_el$33, _$createComponent(For, {
1653
+ var _el$45 = _$getNextElement(_tmpl$15),
1654
+ _el$46 = _el$45.firstChild;
1655
+ var _ref$7 = commandListRef;
1656
+ typeof _ref$7 === "function" ? _$use(_ref$7, _el$46) : commandListRef = _el$46;
1657
+ _$setAttribute(_el$46, "id", commandListId);
1658
+ _$insert(_el$46, _$createComponent(For, {
1172
1659
  get each() {
1173
1660
  return emojiMatches();
1174
1661
  },
1175
1662
  children: (entry, index) => (() => {
1176
- var _el$91 = _$getNextElement(_tmpl$22),
1177
- _el$92 = _el$91.firstChild,
1178
- _el$93 = _el$92.nextSibling,
1179
- _el$94 = _el$93.nextSibling,
1180
- [_el$95, _co$24] = _$getNextMarker(_el$94.nextSibling);
1181
- _el$91.$$click = () => pickEmojiSuggestion(index());
1182
- _el$91.$$pointerdown = event => event.preventDefault();
1183
- _$insert(_el$92, () => emojiInTone(entry, props.emoji?.skinTone ?? 0));
1184
- _$insert(_el$93, () => emojiName(entry, locale()));
1185
- _$insert(_el$91, _$createComponent(Show, {
1663
+ var _el$110 = _$getNextElement(_tmpl$26),
1664
+ _el$111 = _el$110.firstChild,
1665
+ _el$112 = _el$111.nextSibling,
1666
+ _el$113 = _el$112.nextSibling,
1667
+ [_el$114, _co$28] = _$getNextMarker(_el$113.nextSibling);
1668
+ _el$110.$$click = () => pickEmojiSuggestion(index());
1669
+ _el$110.$$mousedown = keepFieldFocus;
1670
+ _$insert(_el$111, () => emojiInTone(entry, props.emoji?.skinTone ?? 0));
1671
+ _$insert(_el$112, () => emojiName(entry, locale()));
1672
+ _$insert(_el$110, _$createComponent(Show, {
1186
1673
  get when() {
1187
1674
  return entry.shortcodes[0];
1188
1675
  },
1189
1676
  children: code => (() => {
1190
- var _el$96 = _$getNextElement(_tmpl$23),
1191
- _el$97 = _el$96.firstChild,
1192
- _el$99 = _el$97.nextSibling,
1193
- [_el$100, _co$25] = _$getNextMarker(_el$99.nextSibling),
1194
- _el$98 = _el$100.nextSibling;
1195
- _$insert(_el$96, code, _el$100, _co$25);
1196
- return _el$96;
1677
+ var _el$115 = _$getNextElement(_tmpl$27),
1678
+ _el$116 = _el$115.firstChild,
1679
+ _el$118 = _el$116.nextSibling,
1680
+ [_el$119, _co$29] = _$getNextMarker(_el$118.nextSibling),
1681
+ _el$117 = _el$119.nextSibling;
1682
+ _$insert(_el$115, code, _el$119, _co$29);
1683
+ return _el$115;
1197
1684
  })()
1198
- }), _el$95, _co$24);
1685
+ }), _el$114, _co$28);
1199
1686
  _$effect(_p$ => {
1200
- var _v$19 = `${commandListId}-${index()}`,
1201
- _v$20 = index() === selectedCommandIndex(),
1202
- _v$21 = emojiName(entry, locale()),
1203
- _v$22 = index() === selectedCommandIndex() ? "true" : undefined;
1204
- _v$19 !== _p$.e && _$setAttribute(_el$91, "id", _p$.e = _v$19);
1205
- _v$20 !== _p$.t && _$setAttribute(_el$91, "aria-selected", _p$.t = _v$20);
1206
- _v$21 !== _p$.a && _$setAttribute(_el$91, "aria-label", _p$.a = _v$21);
1207
- _v$22 !== _p$.o && _$setAttribute(_el$91, "data-active", _p$.o = _v$22);
1687
+ var _v$28 = `${commandListId}-${index()}`,
1688
+ _v$29 = index() === selectedCommandIndex(),
1689
+ _v$30 = emojiName(entry, locale()),
1690
+ _v$31 = index() === selectedCommandIndex() ? "true" : undefined;
1691
+ _v$28 !== _p$.e && _$setAttribute(_el$110, "id", _p$.e = _v$28);
1692
+ _v$29 !== _p$.t && _$setAttribute(_el$110, "aria-selected", _p$.t = _v$29);
1693
+ _v$30 !== _p$.a && _$setAttribute(_el$110, "aria-label", _p$.a = _v$30);
1694
+ _v$31 !== _p$.o && _$setAttribute(_el$110, "data-active", _p$.o = _v$31);
1208
1695
  return _p$;
1209
1696
  }, {
1210
1697
  e: undefined,
@@ -1213,343 +1700,387 @@ export function ChatComposer(props) {
1213
1700
  o: undefined
1214
1701
  });
1215
1702
  _$runHydrationEvents();
1216
- return _el$91;
1703
+ return _el$110;
1217
1704
  })()
1218
1705
  }));
1219
- _$effect(() => _$setAttribute(_el$33, "aria-label", chatMessages().emojiSuggestions));
1220
- return _el$32;
1706
+ _$effect(() => _$setAttribute(_el$46, "aria-label", chatMessages().emojiSuggestions));
1707
+ return _el$45;
1221
1708
  }
1222
- }), _el$54, _co$1);
1223
- _$insert(_el$30, _$createComponent(Show, {
1709
+ }), _el$67, _co$11);
1710
+ _$insert(_el$43, _$createComponent(Show, {
1224
1711
  get when() {
1225
1712
  return commandsOpen();
1226
1713
  },
1227
1714
  get children() {
1228
- var _el$34 = _$getNextElement(_tmpl$15),
1229
- _el$35 = _el$34.firstChild,
1230
- _el$45 = _el$35.firstChild,
1231
- [_el$46, _co$7] = _$getNextMarker(_el$45.nextSibling),
1232
- _el$47 = _el$46.nextSibling,
1233
- [_el$48, _co$8] = _$getNextMarker(_el$47.nextSibling),
1234
- _el$49 = _el$48.nextSibling,
1235
- [_el$50, _co$9] = _$getNextMarker(_el$49.nextSibling),
1236
- _el$51 = _el$50.nextSibling,
1237
- [_el$52, _co$0] = _$getNextMarker(_el$51.nextSibling);
1238
- var _ref$7 = commandListRef;
1239
- typeof _ref$7 === "function" ? _$use(_ref$7, _el$35) : commandListRef = _el$35;
1240
- _$setAttribute(_el$35, "id", commandListId);
1241
- _$insert(_el$35, _$createComponent(For, {
1715
+ var _el$47 = _$getNextElement(_tmpl$19),
1716
+ _el$48 = _el$47.firstChild,
1717
+ _el$58 = _el$48.firstChild,
1718
+ [_el$59, _co$9] = _$getNextMarker(_el$58.nextSibling),
1719
+ _el$60 = _el$59.nextSibling,
1720
+ [_el$61, _co$0] = _$getNextMarker(_el$60.nextSibling),
1721
+ _el$62 = _el$61.nextSibling,
1722
+ [_el$63, _co$1] = _$getNextMarker(_el$62.nextSibling),
1723
+ _el$64 = _el$63.nextSibling,
1724
+ [_el$65, _co$10] = _$getNextMarker(_el$64.nextSibling);
1725
+ var _ref$8 = commandListRef;
1726
+ typeof _ref$8 === "function" ? _$use(_ref$8, _el$48) : commandListRef = _el$48;
1727
+ _$setAttribute(_el$48, "id", commandListId);
1728
+ _$insert(_el$48, _$createComponent(For, {
1242
1729
  get each() {
1243
- return commandMatches();
1730
+ return commandModel().groups.map(commandGroupKey);
1244
1731
  },
1245
- children: (command, index) => (() => {
1246
- var _el$101 = _$getNextElement(_tmpl$24),
1247
- _el$102 = _el$101.firstChild,
1248
- _el$103 = _el$102.nextSibling,
1249
- _el$104 = _el$103.nextSibling;
1250
- _el$101.$$click = () => void executeCommand(command);
1251
- _el$101.$$pointerdown = event => event.preventDefault();
1252
- _$insert(_el$103, () => command.label ?? `/${command.name}`);
1253
- _$insert(_el$104, () => command.description);
1254
- _$effect(_p$ => {
1255
- var _v$23 = `${commandListId}-${index()}`,
1256
- _v$24 = index() === selectedCommandIndex(),
1257
- _v$25 = command.disabled,
1258
- _v$26 = index() === selectedCommandIndex() ? "true" : undefined,
1259
- _v$27 = command.icon ?? "ti ti-slash";
1260
- _v$23 !== _p$.e && _$setAttribute(_el$101, "id", _p$.e = _v$23);
1261
- _v$24 !== _p$.t && _$setAttribute(_el$101, "aria-selected", _p$.t = _v$24);
1262
- _v$25 !== _p$.a && _$setAttribute(_el$101, "aria-disabled", _p$.a = _v$25);
1263
- _v$26 !== _p$.o && _$setAttribute(_el$101, "data-active", _p$.o = _v$26);
1264
- _v$27 !== _p$.i && _$className(_el$102, _p$.i = _v$27);
1265
- return _p$;
1266
- }, {
1267
- e: undefined,
1268
- t: undefined,
1269
- a: undefined,
1270
- o: undefined,
1271
- i: undefined
1732
+ children: key => {
1733
+ const group = createMemo(() => commandModel().groups.find(group => commandGroupKey(group) === key));
1734
+ const headingId = () => `${commandListId}-g-${key === "scope" ? "scope" : props.commandSections?.findIndex(section => section.id === group()?.section?.id)}`;
1735
+ const rows = () => group()?.rows.map(row => row.command) ?? [];
1736
+ return _$createComponent(Show, {
1737
+ when: key !== "flat",
1738
+ get fallback() {
1739
+ return _$createComponent(For, {
1740
+ get each() {
1741
+ return rows();
1742
+ },
1743
+ children: renderCommandRow
1744
+ });
1745
+ },
1746
+ get children() {
1747
+ var _el$120 = _$getNextElement(_tmpl$30),
1748
+ _el$121 = _el$120.firstChild,
1749
+ _el$122 = _el$121.firstChild,
1750
+ _el$124 = _el$122.nextSibling,
1751
+ [_el$125, _co$30] = _$getNextMarker(_el$124.nextSibling),
1752
+ _el$127 = _el$121.nextSibling,
1753
+ [_el$128, _co$31] = _$getNextMarker(_el$127.nextSibling),
1754
+ _el$129 = _el$128.nextSibling,
1755
+ [_el$130, _co$32] = _$getNextMarker(_el$129.nextSibling);
1756
+ _$insert(_el$122, () => group()?.scopeTitle ?? group()?.section?.label);
1757
+ _$insert(_el$121, _$createComponent(Show, {
1758
+ get when() {
1759
+ return group()?.loading;
1760
+ },
1761
+ get children() {
1762
+ return _$getNextElement(_tmpl$28);
1763
+ }
1764
+ }), _el$125, _co$30);
1765
+ _$insert(_el$120, _$createComponent(For, {
1766
+ get each() {
1767
+ return rows();
1768
+ },
1769
+ children: renderCommandRow
1770
+ }), _el$128, _co$31);
1771
+ _$insert(_el$120, _$createComponent(Show, {
1772
+ get when() {
1773
+ return group()?.placeholder;
1774
+ },
1775
+ get children() {
1776
+ return _$getNextElement(_tmpl$29);
1777
+ }
1778
+ }), _el$130, _co$32);
1779
+ _$effect(_p$ => {
1780
+ var _v$32 = headingId(),
1781
+ _v$33 = headingId();
1782
+ _v$32 !== _p$.e && _$setAttribute(_el$120, "aria-labelledby", _p$.e = _v$32);
1783
+ _v$33 !== _p$.t && _$setAttribute(_el$121, "id", _p$.t = _v$33);
1784
+ return _p$;
1785
+ }, {
1786
+ e: undefined,
1787
+ t: undefined
1788
+ });
1789
+ return _el$120;
1790
+ }
1272
1791
  });
1273
- _$runHydrationEvents();
1274
- return _el$101;
1275
- })()
1276
- }), _el$46, _co$7);
1277
- _$insert(_el$35, _$createComponent(Show, {
1792
+ }
1793
+ }), _el$59, _co$9);
1794
+ _$insert(_el$48, _$createComponent(Show, {
1278
1795
  get when() {
1279
- return searching();
1796
+ return _$memo(() => !!(searching() && commandMatches().length === 0))() && !commandModel().groups.some(group => group.section || group.scopeTitle);
1280
1797
  },
1281
1798
  get children() {
1282
- var _el$36 = _$getNextElement(_tmpl$12),
1283
- _el$37 = _el$36.firstChild,
1284
- _el$38 = _el$37.nextSibling;
1285
- _$insert(_el$38, () => messages().loading);
1286
- return _el$36;
1799
+ var _el$49 = _$getNextElement(_tmpl$16),
1800
+ _el$50 = _el$49.firstChild,
1801
+ _el$51 = _el$50.nextSibling;
1802
+ _$insert(_el$51, () => messages().loading);
1803
+ return _el$49;
1287
1804
  }
1288
- }), _el$48, _co$8);
1289
- _$insert(_el$35, _$createComponent(Show, {
1805
+ }), _el$61, _co$0);
1806
+ _$insert(_el$48, _$createComponent(Show, {
1290
1807
  get when() {
1291
1808
  return searchError();
1292
1809
  },
1293
1810
  get children() {
1294
- var _el$39 = _$getNextElement(_tmpl$13),
1295
- _el$40 = _el$39.firstChild,
1296
- _el$41 = _el$40.nextSibling,
1297
- _el$42 = _el$41.nextSibling,
1298
- [_el$43, _co$6] = _$getNextMarker(_el$42.nextSibling);
1299
- _$insert(_el$39, () => messages().error, _el$43, _co$6);
1300
- return _el$39;
1811
+ var _el$52 = _$getNextElement(_tmpl$17),
1812
+ _el$53 = _el$52.firstChild,
1813
+ _el$54 = _el$53.nextSibling,
1814
+ _el$55 = _el$54.nextSibling,
1815
+ [_el$56, _co$8] = _$getNextMarker(_el$55.nextSibling);
1816
+ _$insert(_el$52, () => messages().error, _el$56, _co$8);
1817
+ return _el$52;
1301
1818
  }
1302
- }), _el$50, _co$9);
1303
- _$insert(_el$35, _$createComponent(Show, {
1819
+ }), _el$63, _co$1);
1820
+ _$insert(_el$48, _$createComponent(Show, {
1304
1821
  get when() {
1305
1822
  return _$memo(() => !!(!searching() && !searchError()))() && commandMatches().length === 0;
1306
1823
  },
1307
1824
  get children() {
1308
- var _el$44 = _$getNextElement(_tmpl$14);
1309
- _$insert(_el$44, () => messages().noResults);
1310
- return _el$44;
1825
+ var _el$57 = _$getNextElement(_tmpl$18);
1826
+ _$insert(_el$57, (() => {
1827
+ var _c$ = _$memo(() => !!!parsedCommandQuery().query.trim());
1828
+ return () => _c$() ? messages().noResults : chatMessages().commandsNothingFound({
1829
+ query: parsedCommandQuery().query.trim()
1830
+ });
1831
+ })());
1832
+ return _el$57;
1311
1833
  }
1312
- }), _el$52, _co$0);
1313
- _$effect(() => _$setAttribute(_el$35, "aria-label", chatMessages().commands));
1314
- return _el$34;
1834
+ }), _el$65, _co$10);
1835
+ _$effect(_p$ => {
1836
+ var _v$19 = chatMessages().commands,
1837
+ _v$20 = searching() ? "true" : undefined;
1838
+ _v$19 !== _p$.e && _$setAttribute(_el$48, "aria-label", _p$.e = _v$19);
1839
+ _v$20 !== _p$.t && _$setAttribute(_el$48, "aria-busy", _p$.t = _v$20);
1840
+ return _p$;
1841
+ }, {
1842
+ e: undefined,
1843
+ t: undefined
1844
+ });
1845
+ return _el$47;
1315
1846
  }
1316
- }), _el$56, _co$10);
1847
+ }), _el$69, _co$12);
1317
1848
  _$effect(_p$ => {
1318
- var _v$12 = hasAccessory() ? undefined : "true",
1319
- _v$13 = suggestionsOpen() ? "hidden" : undefined,
1320
- _v$14 = suggestionsOpen();
1321
- _v$12 !== _p$.e && _$setAttribute(_el$30, "data-overlay", _p$.e = _v$12);
1322
- _v$13 !== _p$.t && _$setStyleProperty(_el$31, "visibility", _p$.t = _v$13);
1323
- _v$14 !== _p$.a && _$setProperty(_el$31, "inert", _p$.a = _v$14);
1849
+ var _v$21 = hasAccessory() ? undefined : "true",
1850
+ _v$22 = suggestionsOpen() ? "hidden" : undefined,
1851
+ _v$23 = suggestionsOpen();
1852
+ _v$21 !== _p$.e && _$setAttribute(_el$43, "data-overlay", _p$.e = _v$21);
1853
+ _v$22 !== _p$.t && _$setStyleProperty(_el$44, "visibility", _p$.t = _v$22);
1854
+ _v$23 !== _p$.a && _$setProperty(_el$44, "inert", _p$.a = _v$23);
1324
1855
  return _p$;
1325
1856
  }, {
1326
1857
  e: undefined,
1327
1858
  t: undefined,
1328
1859
  a: undefined
1329
1860
  });
1330
- return _el$30;
1861
+ return _el$43;
1331
1862
  }
1332
- }), _el$90, _co$23);
1333
- var _ref$8 = composerRef;
1334
- typeof _ref$8 === "function" ? _$use(_ref$8, _el$57) : composerRef = _el$57;
1335
- _$insert(_el$57, _$createComponent(Show, {
1863
+ }), _el$109, _co$27);
1864
+ var _ref$9 = composerRef;
1865
+ typeof _ref$9 === "function" ? _$use(_ref$9, _el$70) : composerRef = _el$70;
1866
+ _$insert(_el$70, _$createComponent(Show, {
1336
1867
  get when() {
1337
1868
  return showHint();
1338
1869
  },
1339
1870
  get children() {
1340
- var _el$58 = _$getNextElement(_tmpl$17);
1341
- _$insert(_el$58, _$createComponent(Show, {
1871
+ var _el$71 = _$getNextElement(_tmpl$21);
1872
+ _$insert(_el$71, _$createComponent(Show, {
1342
1873
  get when() {
1343
1874
  return dictationStatus();
1344
1875
  },
1345
1876
  get fallback() {
1346
1877
  return (() => {
1347
- var _el$105 = _$getNextElement(_tmpl$25);
1348
- _$insert(_el$105, hint);
1349
- return _el$105;
1878
+ var _el$131 = _$getNextElement(_tmpl$31);
1879
+ _$insert(_el$131, hint);
1880
+ return _el$131;
1350
1881
  })();
1351
1882
  },
1352
1883
  children: status => [(() => {
1353
- var _el$106 = _$getNextElement(_tmpl$26),
1354
- _el$107 = _el$106.firstChild,
1355
- _el$108 = _el$107.nextSibling;
1356
- _$insert(_el$108, () => status().text);
1884
+ var _el$132 = _$getNextElement(_tmpl$32),
1885
+ _el$133 = _el$132.firstChild,
1886
+ _el$134 = _el$133.nextSibling;
1887
+ _$insert(_el$134, () => status().text);
1357
1888
  _$effect(_p$ => {
1358
- var _v$28 = dictation() ?? undefined,
1359
- _v$29 = status().icon;
1360
- _v$28 !== _p$.e && _$setAttribute(_el$106, "data-state", _p$.e = _v$28);
1361
- _v$29 !== _p$.t && _$className(_el$107, _p$.t = _v$29);
1889
+ var _v$34 = dictation() ?? undefined,
1890
+ _v$35 = status().icon;
1891
+ _v$34 !== _p$.e && _$setAttribute(_el$132, "data-state", _p$.e = _v$34);
1892
+ _v$35 !== _p$.t && _$className(_el$133, _p$.t = _v$35);
1362
1893
  return _p$;
1363
1894
  }, {
1364
1895
  e: undefined,
1365
1896
  t: undefined
1366
1897
  });
1367
- return _el$106;
1898
+ return _el$132;
1368
1899
  })(), _$createComponent(Show, {
1369
1900
  get when() {
1370
1901
  return _$memo(() => dictation() === "refined")() ? props.microphone?.onRestoreOriginal : undefined;
1371
1902
  },
1372
1903
  children: restore => (() => {
1373
- var _el$109 = _$getNextElement(_tmpl$27);
1374
- _el$109.$$click = () => reportChatFailure(restore(), props.onError);
1375
- _el$109.$$mousedown = keepFieldFocus;
1376
- _$insert(_el$109, () => chatMessages().restoreOriginal);
1377
- _$effect(() => _$setProperty(_el$109, "disabled", microphoneDisabled()));
1904
+ var _el$135 = _$getNextElement(_tmpl$33);
1905
+ _el$135.$$click = () => reportChatFailure(restore(), props.onError);
1906
+ _el$135.$$mousedown = keepFieldFocus;
1907
+ _$insert(_el$135, () => chatMessages().restoreOriginal);
1908
+ _$effect(() => _$setProperty(_el$135, "disabled", microphoneDisabled()));
1378
1909
  _$runHydrationEvents();
1379
- return _el$109;
1910
+ return _el$135;
1380
1911
  })()
1381
1912
  })]
1382
1913
  }));
1383
- return _el$58;
1914
+ return _el$71;
1384
1915
  }
1385
- }), _el$82, _co$19);
1386
- _$insert(_el$57, _$createComponent(Show, {
1916
+ }), _el$95, _co$21);
1917
+ _$insert(_el$70, _$createComponent(Show, {
1387
1918
  get when() {
1388
1919
  return attachments().length > 0;
1389
1920
  },
1390
1921
  get children() {
1391
- var _el$59 = _$getNextElement(_tmpl$18);
1392
- _$insert(_el$59, _$createComponent(For, {
1922
+ var _el$72 = _$getNextElement(_tmpl$22);
1923
+ _$insert(_el$72, _$createComponent(For, {
1393
1924
  get each() {
1394
1925
  return attachments();
1395
1926
  },
1396
1927
  children: attachment => (() => {
1397
- var _el$110 = _$getNextElement(_tmpl$29),
1398
- _el$111 = _el$110.firstChild,
1399
- _el$112 = _el$111.firstChild,
1400
- [_el$113, _co$26] = _$getNextMarker(_el$112.nextSibling),
1401
- _el$114 = _el$113.nextSibling,
1402
- [_el$115, _co$27] = _$getNextMarker(_el$114.nextSibling),
1403
- _el$117 = _el$111.nextSibling,
1404
- [_el$118, _co$28] = _$getNextMarker(_el$117.nextSibling);
1405
- _$insert(_el$111, _$createComponent(Show, {
1928
+ var _el$136 = _$getNextElement(_tmpl$35),
1929
+ _el$137 = _el$136.firstChild,
1930
+ _el$138 = _el$137.firstChild,
1931
+ [_el$139, _co$33] = _$getNextMarker(_el$138.nextSibling),
1932
+ _el$140 = _el$139.nextSibling,
1933
+ [_el$141, _co$34] = _$getNextMarker(_el$140.nextSibling),
1934
+ _el$143 = _el$137.nextSibling,
1935
+ [_el$144, _co$35] = _$getNextMarker(_el$143.nextSibling);
1936
+ _$insert(_el$137, _$createComponent(Show, {
1406
1937
  get when() {
1407
1938
  return attachment.href;
1408
1939
  },
1409
1940
  get fallback() {
1410
1941
  return (() => {
1411
- var _el$119 = _$getNextElement(_tmpl$31),
1412
- _el$121 = _el$119.firstChild,
1413
- [_el$122, _co$29] = _$getNextMarker(_el$121.nextSibling),
1414
- _el$123 = _el$122.nextSibling,
1415
- [_el$124, _co$30] = _$getNextMarker(_el$123.nextSibling);
1416
- _$insert(_el$119, _$createComponent(Show, {
1942
+ var _el$145 = _$getNextElement(_tmpl$37),
1943
+ _el$147 = _el$145.firstChild,
1944
+ [_el$148, _co$36] = _$getNextMarker(_el$147.nextSibling),
1945
+ _el$149 = _el$148.nextSibling,
1946
+ [_el$150, _co$37] = _$getNextMarker(_el$149.nextSibling);
1947
+ _$insert(_el$145, _$createComponent(Show, {
1417
1948
  get when() {
1418
1949
  return _$memo(() => attachment.kind === "image")() && attachment.previewUrl;
1419
1950
  },
1420
1951
  get fallback() {
1421
1952
  return (() => {
1422
- var _el$125 = _$getNextElement(_tmpl$3);
1423
- _$effect(() => _$className(_el$125, attachmentIcon(attachment)));
1424
- return _el$125;
1953
+ var _el$151 = _$getNextElement(_tmpl$3);
1954
+ _$effect(() => _$className(_el$151, attachmentIcon(attachment)));
1955
+ return _el$151;
1425
1956
  })();
1426
1957
  },
1427
1958
  get children() {
1428
- var _el$120 = _$getNextElement(_tmpl$30);
1959
+ var _el$146 = _$getNextElement(_tmpl$36);
1429
1960
  _$effect(_p$ => {
1430
- var _v$32 = attachment.previewUrl,
1431
- _v$33 = attachment.alt ?? "";
1432
- _v$32 !== _p$.e && _$setAttribute(_el$120, "src", _p$.e = _v$32);
1433
- _v$33 !== _p$.t && _$setAttribute(_el$120, "alt", _p$.t = _v$33);
1961
+ var _v$38 = attachment.previewUrl,
1962
+ _v$39 = attachment.alt ?? "";
1963
+ _v$38 !== _p$.e && _$setAttribute(_el$146, "src", _p$.e = _v$38);
1964
+ _v$39 !== _p$.t && _$setAttribute(_el$146, "alt", _p$.t = _v$39);
1434
1965
  return _p$;
1435
1966
  }, {
1436
1967
  e: undefined,
1437
1968
  t: undefined
1438
1969
  });
1439
- return _el$120;
1970
+ return _el$146;
1440
1971
  }
1441
- }), _el$122, _co$29);
1442
- _$insert(_el$119, () => renderAttachmentCopy(attachment), _el$124, _co$30);
1443
- return _el$119;
1972
+ }), _el$148, _co$36);
1973
+ _$insert(_el$145, () => renderAttachmentCopy(attachment), _el$150, _co$37);
1974
+ return _el$145;
1444
1975
  })();
1445
1976
  },
1446
1977
  children: href => (() => {
1447
- var _el$126 = _$getNextElement(_tmpl$32),
1448
- _el$128 = _el$126.firstChild,
1449
- [_el$129, _co$31] = _$getNextMarker(_el$128.nextSibling),
1450
- _el$130 = _el$129.nextSibling,
1451
- [_el$131, _co$32] = _$getNextMarker(_el$130.nextSibling);
1452
- _$insert(_el$126, _$createComponent(Show, {
1978
+ var _el$152 = _$getNextElement(_tmpl$38),
1979
+ _el$154 = _el$152.firstChild,
1980
+ [_el$155, _co$38] = _$getNextMarker(_el$154.nextSibling),
1981
+ _el$156 = _el$155.nextSibling,
1982
+ [_el$157, _co$39] = _$getNextMarker(_el$156.nextSibling);
1983
+ _$insert(_el$152, _$createComponent(Show, {
1453
1984
  get when() {
1454
1985
  return _$memo(() => attachment.kind === "image")() && attachment.previewUrl;
1455
1986
  },
1456
1987
  get fallback() {
1457
1988
  return (() => {
1458
- var _el$132 = _$getNextElement(_tmpl$3);
1459
- _$effect(() => _$className(_el$132, attachmentIcon(attachment)));
1460
- return _el$132;
1989
+ var _el$158 = _$getNextElement(_tmpl$3);
1990
+ _$effect(() => _$className(_el$158, attachmentIcon(attachment)));
1991
+ return _el$158;
1461
1992
  })();
1462
1993
  },
1463
1994
  get children() {
1464
- var _el$127 = _$getNextElement(_tmpl$30);
1995
+ var _el$153 = _$getNextElement(_tmpl$36);
1465
1996
  _$effect(_p$ => {
1466
- var _v$34 = attachment.previewUrl,
1467
- _v$35 = attachment.alt ?? "";
1468
- _v$34 !== _p$.e && _$setAttribute(_el$127, "src", _p$.e = _v$34);
1469
- _v$35 !== _p$.t && _$setAttribute(_el$127, "alt", _p$.t = _v$35);
1997
+ var _v$40 = attachment.previewUrl,
1998
+ _v$41 = attachment.alt ?? "";
1999
+ _v$40 !== _p$.e && _$setAttribute(_el$153, "src", _p$.e = _v$40);
2000
+ _v$41 !== _p$.t && _$setAttribute(_el$153, "alt", _p$.t = _v$41);
1470
2001
  return _p$;
1471
2002
  }, {
1472
2003
  e: undefined,
1473
2004
  t: undefined
1474
2005
  });
1475
- return _el$127;
2006
+ return _el$153;
1476
2007
  }
1477
- }), _el$129, _co$31);
1478
- _$insert(_el$126, () => renderAttachmentCopy(attachment), _el$131, _co$32);
2008
+ }), _el$155, _co$38);
2009
+ _$insert(_el$152, () => renderAttachmentCopy(attachment), _el$157, _co$39);
1479
2010
  _$effect(_p$ => {
1480
- var _v$36 = href(),
1481
- _v$37 = chatMessages().openInNewTab({
2011
+ var _v$42 = href(),
2012
+ _v$43 = chatMessages().openInNewTab({
1482
2013
  name: attachment.name
1483
2014
  });
1484
- _v$36 !== _p$.e && _$setAttribute(_el$126, "href", _p$.e = _v$36);
1485
- _v$37 !== _p$.t && _$setAttribute(_el$126, "aria-label", _p$.t = _v$37);
2015
+ _v$42 !== _p$.e && _$setAttribute(_el$152, "href", _p$.e = _v$42);
2016
+ _v$43 !== _p$.t && _$setAttribute(_el$152, "aria-label", _p$.t = _v$43);
1486
2017
  return _p$;
1487
2018
  }, {
1488
2019
  e: undefined,
1489
2020
  t: undefined
1490
2021
  });
1491
- return _el$126;
2022
+ return _el$152;
1492
2023
  })()
1493
- }), _el$113, _co$26);
1494
- _$insert(_el$111, _$createComponent(Show, {
2024
+ }), _el$139, _co$33);
2025
+ _$insert(_el$137, _$createComponent(Show, {
1495
2026
  get when() {
1496
2027
  return attachment.action;
1497
2028
  },
1498
2029
  children: action => (() => {
1499
- var _el$133 = _$getNextElement(_tmpl$33),
1500
- _el$134 = _el$133.firstChild,
1501
- [_el$135, _co$33] = _$getNextMarker(_el$134.nextSibling),
1502
- _el$136 = _el$135.nextSibling,
1503
- [_el$137, _co$34] = _$getNextMarker(_el$136.nextSibling);
1504
- _el$133.$$click = () => reportChatFailure(() => executeChatAction(action()), props.onError);
1505
- _$insert(_el$133, _$createComponent(Show, {
2030
+ var _el$159 = _$getNextElement(_tmpl$39),
2031
+ _el$160 = _el$159.firstChild,
2032
+ [_el$161, _co$40] = _$getNextMarker(_el$160.nextSibling),
2033
+ _el$162 = _el$161.nextSibling,
2034
+ [_el$163, _co$41] = _$getNextMarker(_el$162.nextSibling);
2035
+ _el$159.$$click = () => reportChatFailure(() => executeChatAction(action()), props.onError);
2036
+ _$insert(_el$159, _$createComponent(Show, {
1506
2037
  get when() {
1507
2038
  return action().icon;
1508
2039
  },
1509
2040
  children: icon => (() => {
1510
- var _el$138 = _$getNextElement(_tmpl$3);
1511
- _$effect(() => _$className(_el$138, icon()));
1512
- return _el$138;
2041
+ var _el$164 = _$getNextElement(_tmpl$3);
2042
+ _$effect(() => _$className(_el$164, icon()));
2043
+ return _el$164;
1513
2044
  })()
1514
- }), _el$135, _co$33);
1515
- _$insert(_el$133, () => action().label, _el$137, _co$34);
1516
- _$effect(() => _$setProperty(_el$133, "disabled", blocked() || action().disabled));
2045
+ }), _el$161, _co$40);
2046
+ _$insert(_el$159, () => action().label, _el$163, _co$41);
2047
+ _$effect(() => _$setProperty(_el$159, "disabled", blocked() || action().disabled));
1517
2048
  _$runHydrationEvents();
1518
- return _el$133;
2049
+ return _el$159;
1519
2050
  })()
1520
- }), _el$115, _co$27);
1521
- _$insert(_el$110, _$createComponent(Show, {
2051
+ }), _el$141, _co$34);
2052
+ _$insert(_el$136, _$createComponent(Show, {
1522
2053
  get when() {
1523
2054
  return props.onAttachmentsChange;
1524
2055
  },
1525
2056
  get children() {
1526
- var _el$116 = _$getNextElement(_tmpl$28);
1527
- _el$116.$$click = () => setAttachments(attachments().filter(candidate => candidate.id !== attachment.id));
2057
+ var _el$142 = _$getNextElement(_tmpl$34);
2058
+ _el$142.$$click = () => setAttachments(attachments().filter(candidate => candidate.id !== attachment.id));
1528
2059
  _$effect(_p$ => {
1529
- var _v$30 = selectMessages().removeNamed({
2060
+ var _v$36 = selectMessages().removeNamed({
1530
2061
  name: attachment.name
1531
2062
  }),
1532
- _v$31 = blocked();
1533
- _v$30 !== _p$.e && _$setAttribute(_el$116, "aria-label", _p$.e = _v$30);
1534
- _v$31 !== _p$.t && _$setProperty(_el$116, "disabled", _p$.t = _v$31);
2063
+ _v$37 = blocked();
2064
+ _v$36 !== _p$.e && _$setAttribute(_el$142, "aria-label", _p$.e = _v$36);
2065
+ _v$37 !== _p$.t && _$setProperty(_el$142, "disabled", _p$.t = _v$37);
1535
2066
  return _p$;
1536
2067
  }, {
1537
2068
  e: undefined,
1538
2069
  t: undefined
1539
2070
  });
1540
2071
  _$runHydrationEvents();
1541
- return _el$116;
2072
+ return _el$142;
1542
2073
  }
1543
- }), _el$118, _co$28);
1544
- _$effect(() => _el$111.classList.toggle("k2b-chat-composer__attachment-content--action", !!Boolean(attachment.action)));
1545
- return _el$110;
2074
+ }), _el$144, _co$35);
2075
+ _$effect(() => _el$137.classList.toggle("k2b-chat-composer__attachment-content--action", !!Boolean(attachment.action)));
2076
+ return _el$136;
1546
2077
  })()
1547
2078
  }));
1548
- _$effect(() => _$setAttribute(_el$59, "aria-label", chatMessages().attachments));
1549
- return _el$59;
2079
+ _$effect(() => _$setAttribute(_el$72, "aria-label", chatMessages().attachments));
2080
+ return _el$72;
1550
2081
  }
1551
- }), _el$84, _co$20);
1552
- _$insert(_el$57, _$createComponent(Show, {
2082
+ }), _el$97, _co$22);
2083
+ _$insert(_el$70, _$createComponent(Show, {
1553
2084
  get when() {
1554
2085
  return conversation();
1555
2086
  },
@@ -1559,49 +2090,49 @@ export function ChatComposer(props) {
1559
2090
  return props.error;
1560
2091
  },
1561
2092
  get children() {
1562
- var _el$139 = _$getNextElement(_tmpl$19),
1563
- _el$140 = _el$139.firstChild,
1564
- _el$141 = _el$140.nextSibling,
1565
- [_el$142, _co$35] = _$getNextMarker(_el$141.nextSibling);
1566
- _$insert(_el$139, () => props.error, _el$142, _co$35);
1567
- return _el$139;
2093
+ var _el$165 = _$getNextElement(_tmpl$23),
2094
+ _el$166 = _el$165.firstChild,
2095
+ _el$167 = _el$166.nextSibling,
2096
+ [_el$168, _co$42] = _$getNextMarker(_el$167.nextSibling);
2097
+ _$insert(_el$165, () => props.error, _el$168, _co$42);
2098
+ return _el$165;
1568
2099
  }
1569
2100
  }), _$memo(formatRow), (() => {
1570
- var _el$143 = _$getNextElement(_tmpl$34);
1571
- _$insert(_el$143, _$createComponent(Show, {
2101
+ var _el$169 = _$getNextElement(_tmpl$40);
2102
+ _$insert(_el$169, _$createComponent(Show, {
1572
2103
  get when() {
1573
- return props.footerContent;
2104
+ return footer();
1574
2105
  },
1575
2106
  get fallback() {
1576
2107
  return [(() => {
1577
- var _el$144 = _$getNextElement(_tmpl$35),
1578
- _el$145 = _el$144.firstChild,
1579
- [_el$146, _co$36] = _$getNextMarker(_el$145.nextSibling),
1580
- _el$147 = _el$146.nextSibling,
1581
- [_el$148, _co$37] = _$getNextMarker(_el$147.nextSibling),
1582
- _el$149 = _el$148.nextSibling,
1583
- [_el$150, _co$38] = _$getNextMarker(_el$149.nextSibling),
1584
- _el$151 = _el$150.nextSibling,
1585
- [_el$152, _co$39] = _$getNextMarker(_el$151.nextSibling),
1586
- _el$153 = _el$152.nextSibling,
1587
- [_el$154, _co$40] = _$getNextMarker(_el$153.nextSibling),
1588
- _el$155 = _el$154.nextSibling,
1589
- [_el$156, _co$41] = _$getNextMarker(_el$155.nextSibling),
1590
- _el$157 = _el$156.nextSibling,
1591
- [_el$158, _co$42] = _$getNextMarker(_el$157.nextSibling);
1592
- _$insert(_el$144, () => props.footerTools, _el$146, _co$36);
1593
- _$insert(_el$144, _$createComponent(Show, {
2108
+ var _el$170 = _$getNextElement(_tmpl$41),
2109
+ _el$171 = _el$170.firstChild,
2110
+ [_el$172, _co$43] = _$getNextMarker(_el$171.nextSibling),
2111
+ _el$173 = _el$172.nextSibling,
2112
+ [_el$174, _co$44] = _$getNextMarker(_el$173.nextSibling),
2113
+ _el$175 = _el$174.nextSibling,
2114
+ [_el$176, _co$45] = _$getNextMarker(_el$175.nextSibling),
2115
+ _el$177 = _el$176.nextSibling,
2116
+ [_el$178, _co$46] = _$getNextMarker(_el$177.nextSibling),
2117
+ _el$179 = _el$178.nextSibling,
2118
+ [_el$180, _co$47] = _$getNextMarker(_el$179.nextSibling),
2119
+ _el$181 = _el$180.nextSibling,
2120
+ [_el$182, _co$48] = _$getNextMarker(_el$181.nextSibling),
2121
+ _el$183 = _el$182.nextSibling,
2122
+ [_el$184, _co$49] = _$getNextMarker(_el$183.nextSibling);
2123
+ _$insert(_el$170, () => props.footerTools, _el$172, _co$43);
2124
+ _$insert(_el$170, _$createComponent(Show, {
1594
2125
  get when() {
1595
2126
  return hasAddMenu();
1596
2127
  },
1597
2128
  get children() {
1598
2129
  return addMenu("ti ti-plus");
1599
2130
  }
1600
- }), _el$148, _co$37);
1601
- _$insert(_el$144, fileInput, _el$150, _co$38);
1602
- _$insert(_el$144, formatToggle, _el$152, _co$39);
1603
- _$insert(_el$144, emojiButton, _el$154, _co$40);
1604
- _$insert(_el$144, _$createComponent(Show, {
2131
+ }), _el$174, _co$44);
2132
+ _$insert(_el$170, fileInput, _el$176, _co$45);
2133
+ _$insert(_el$170, formatToggle, _el$178, _co$46);
2134
+ _$insert(_el$170, emojiButton, _el$180, _co$47);
2135
+ _$insert(_el$170, _$createComponent(Show, {
1605
2136
  get when() {
1606
2137
  return (props.models?.length ?? 0) > 0;
1607
2138
  },
@@ -1626,31 +2157,43 @@ export function ChatComposer(props) {
1626
2157
  image: model.image
1627
2158
  }));
1628
2159
  },
2160
+ get open() {
2161
+ return modelOpen();
2162
+ },
2163
+ onOpenChange: open => {
2164
+ if (!choosingModel()) return;
2165
+ setModelOpen(open);
2166
+ // Dropdown closes before committing the choice; let onValueChange settle it first.
2167
+ if (!open) queueMicrotask(() => {
2168
+ if (!modelOpen()) finishModelSelection(null);
2169
+ });
2170
+ },
1629
2171
  get disabled() {
1630
- return blocked() || running() || !props.onModelChange;
2172
+ return (choosingModel() ? blockedBesidesCommand() : blocked()) || running() || !props.onModelChange;
1631
2173
  },
1632
2174
  onValueChange: modelId => {
1633
2175
  props.onModelChange?.(modelId);
2176
+ finishModelSelection(modelId);
1634
2177
  queueMicrotask(focus);
1635
2178
  }
1636
2179
  });
1637
2180
  }
1638
- }), _el$156, _co$41);
1639
- _$insert(_el$144, () => props.modelDetails, _el$158, _co$42);
1640
- return _el$144;
2181
+ }), _el$182, _co$48);
2182
+ _$insert(_el$170, () => props.modelDetails, _el$184, _co$49);
2183
+ return _el$170;
1641
2184
  })(), (() => {
1642
- var _el$159 = _$getNextElement(_tmpl$36),
1643
- _el$160 = _el$159.firstChild,
1644
- [_el$161, _co$43] = _$getNextMarker(_el$160.nextSibling),
1645
- _el$162 = _el$161.nextSibling,
1646
- [_el$163, _co$44] = _$getNextMarker(_el$162.nextSibling),
1647
- _el$164 = _el$163.nextSibling,
1648
- [_el$165, _co$45] = _$getNextMarker(_el$164.nextSibling),
1649
- _el$166 = _el$165.nextSibling,
1650
- [_el$167, _co$46] = _$getNextMarker(_el$166.nextSibling),
1651
- _el$168 = _el$167.nextSibling,
1652
- [_el$169, _co$47] = _$getNextMarker(_el$168.nextSibling);
1653
- _$insert(_el$159, _$createComponent(For, {
2185
+ var _el$185 = _$getNextElement(_tmpl$42),
2186
+ _el$186 = _el$185.firstChild,
2187
+ [_el$187, _co$50] = _$getNextMarker(_el$186.nextSibling),
2188
+ _el$188 = _el$187.nextSibling,
2189
+ [_el$189, _co$51] = _$getNextMarker(_el$188.nextSibling),
2190
+ _el$190 = _el$189.nextSibling,
2191
+ [_el$191, _co$52] = _$getNextMarker(_el$190.nextSibling),
2192
+ _el$192 = _el$191.nextSibling,
2193
+ [_el$193, _co$53] = _$getNextMarker(_el$192.nextSibling),
2194
+ _el$194 = _el$193.nextSibling,
2195
+ [_el$195, _co$54] = _$getNextMarker(_el$194.nextSibling);
2196
+ _$insert(_el$185, _$createComponent(For, {
1654
2197
  get each() {
1655
2198
  return props.contextActions;
1656
2199
  },
@@ -1674,13 +2217,13 @@ export function ChatComposer(props) {
1674
2217
  },
1675
2218
  onClick: () => reportChatFailure(() => executeChatAction(action), props.onError),
1676
2219
  get children() {
1677
- var _el$170 = _$getNextElement(_tmpl$3);
1678
- _$effect(() => _$className(_el$170, action.icon ?? "ti ti-dots"));
1679
- return _el$170;
2220
+ var _el$196 = _$getNextElement(_tmpl$3);
2221
+ _$effect(() => _$className(_el$196, action.icon ?? "ti ti-dots"));
2222
+ return _el$196;
1680
2223
  }
1681
2224
  })
1682
- }), _el$161, _co$43);
1683
- _$insert(_el$159, _$createComponent(Show, {
2225
+ }), _el$187, _co$50);
2226
+ _$insert(_el$185, _$createComponent(Show, {
1684
2227
  get when() {
1685
2228
  return _$memo(() => !!hasContextUsage())() ? props.contextUsage ?? {} : undefined;
1686
2229
  },
@@ -1692,16 +2235,18 @@ export function ChatComposer(props) {
1692
2235
  return props.onError;
1693
2236
  }
1694
2237
  }))
1695
- }), _el$163, _co$44);
1696
- _$insert(_el$159, () => props.submitTools, _el$165, _co$45);
1697
- _$insert(_el$159, microphoneControl, _el$167, _co$46);
1698
- _$insert(_el$159, sendControl, _el$169, _co$47);
1699
- return _el$159;
2238
+ }), _el$189, _co$51);
2239
+ _$insert(_el$185, () => props.submitTools, _el$191, _co$52);
2240
+ _$insert(_el$185, microphoneControl, _el$193, _co$53);
2241
+ _$insert(_el$185, sendControl, _el$195, _co$54);
2242
+ return _el$185;
1700
2243
  })()];
1701
2244
  },
1702
- children: content => content()
2245
+ get children() {
2246
+ return footer();
2247
+ }
1703
2248
  }));
1704
- return _el$143;
2249
+ return _el$169;
1705
2250
  })()];
1706
2251
  },
1707
2252
  get children() {
@@ -1710,43 +2255,43 @@ export function ChatComposer(props) {
1710
2255
  return props.error;
1711
2256
  },
1712
2257
  get children() {
1713
- var _el$60 = _$getNextElement(_tmpl$19),
1714
- _el$61 = _el$60.firstChild,
1715
- _el$62 = _el$61.nextSibling,
1716
- [_el$63, _co$11] = _$getNextMarker(_el$62.nextSibling);
1717
- _$insert(_el$60, () => props.error, _el$63, _co$11);
1718
- return _el$60;
2258
+ var _el$73 = _$getNextElement(_tmpl$23),
2259
+ _el$74 = _el$73.firstChild,
2260
+ _el$75 = _el$74.nextSibling,
2261
+ [_el$76, _co$13] = _$getNextMarker(_el$75.nextSibling);
2262
+ _$insert(_el$73, () => props.error, _el$76, _co$13);
2263
+ return _el$73;
1719
2264
  }
1720
2265
  }), _$memo(() => formatRow()), (() => {
1721
- var _el$64 = _$getNextElement(_tmpl$20),
1722
- _el$75 = _el$64.firstChild,
1723
- [_el$76, _co$16] = _$getNextMarker(_el$75.nextSibling),
1724
- _el$77 = _el$76.nextSibling,
1725
- [_el$78, _co$17] = _$getNextMarker(_el$77.nextSibling),
1726
- _el$65 = _el$78.nextSibling,
1727
- _el$73 = _el$65.firstChild,
1728
- [_el$74, _co$15] = _$getNextMarker(_el$73.nextSibling),
1729
- _el$66 = _el$74.nextSibling,
1730
- _el$67 = _el$66.firstChild,
1731
- [_el$68, _co$12] = _$getNextMarker(_el$67.nextSibling),
1732
- _el$69 = _el$68.nextSibling,
1733
- [_el$70, _co$13] = _$getNextMarker(_el$69.nextSibling),
1734
- _el$71 = _el$70.nextSibling,
1735
- [_el$72, _co$14] = _$getNextMarker(_el$71.nextSibling),
1736
- _el$79 = _el$65.nextSibling,
1737
- [_el$80, _co$18] = _$getNextMarker(_el$79.nextSibling);
1738
- _$insert(_el$64, attachControl, _el$76, _co$16);
1739
- _$insert(_el$64, fileInput, _el$78, _co$17);
1740
- _$insert(_el$65, field, _el$74, _co$15);
1741
- _$insert(_el$66, formatToggle, _el$68, _co$12);
1742
- _$insert(_el$66, emojiButton, _el$70, _co$13);
1743
- _$insert(_el$66, microphoneControl, _el$72, _co$14);
1744
- _$insert(_el$64, sendControl, _el$80, _co$18);
1745
- return _el$64;
2266
+ var _el$77 = _$getNextElement(_tmpl$24),
2267
+ _el$88 = _el$77.firstChild,
2268
+ [_el$89, _co$18] = _$getNextMarker(_el$88.nextSibling),
2269
+ _el$90 = _el$89.nextSibling,
2270
+ [_el$91, _co$19] = _$getNextMarker(_el$90.nextSibling),
2271
+ _el$78 = _el$91.nextSibling,
2272
+ _el$86 = _el$78.firstChild,
2273
+ [_el$87, _co$17] = _$getNextMarker(_el$86.nextSibling),
2274
+ _el$79 = _el$87.nextSibling,
2275
+ _el$80 = _el$79.firstChild,
2276
+ [_el$81, _co$14] = _$getNextMarker(_el$80.nextSibling),
2277
+ _el$82 = _el$81.nextSibling,
2278
+ [_el$83, _co$15] = _$getNextMarker(_el$82.nextSibling),
2279
+ _el$84 = _el$83.nextSibling,
2280
+ [_el$85, _co$16] = _$getNextMarker(_el$84.nextSibling),
2281
+ _el$92 = _el$78.nextSibling,
2282
+ [_el$93, _co$20] = _$getNextMarker(_el$92.nextSibling);
2283
+ _$insert(_el$77, attachControl, _el$89, _co$18);
2284
+ _$insert(_el$77, fileInput, _el$91, _co$19);
2285
+ _$insert(_el$78, field, _el$87, _co$17);
2286
+ _$insert(_el$79, formatToggle, _el$81, _co$14);
2287
+ _$insert(_el$79, emojiButton, _el$83, _co$15);
2288
+ _$insert(_el$79, microphoneControl, _el$85, _co$16);
2289
+ _$insert(_el$77, sendControl, _el$93, _co$20);
2290
+ return _el$77;
1746
2291
  })()];
1747
2292
  }
1748
- }), _el$86, _co$21);
1749
- _$insert(_el$57, _$createComponent(Show, {
2293
+ }), _el$99, _co$23);
2294
+ _$insert(_el$70, _$createComponent(Show, {
1750
2295
  get when() {
1751
2296
  return props.fileSelection;
1752
2297
  },
@@ -1765,16 +2310,60 @@ export function ChatComposer(props) {
1765
2310
  },
1766
2311
  onDrop: files => void runFiles(files)
1767
2312
  })
1768
- }), _el$88, _co$22);
2313
+ }), _el$101, _co$24);
2314
+ _$insert(_el$102, _$createComponent(Show, {
2315
+ get when() {
2316
+ return suggestionAnnouncement();
2317
+ },
2318
+ keyed: true,
2319
+ children: announced => (() => {
2320
+ var _el$197 = _$getNextElement(_tmpl$10);
2321
+ _$insert(_el$197, () => announced.text);
2322
+ return _el$197;
2323
+ })()
2324
+ }));
2325
+ _$insert(_el$103, _$createComponent(Show, {
2326
+ get when() {
2327
+ return _$memo(() => !!!suggestionsOpen())() && commandStatus();
2328
+ },
2329
+ children: status => (() => {
2330
+ var _el$198 = _$getNextElement(_tmpl$43),
2331
+ _el$199 = _el$198.firstChild,
2332
+ _el$200 = _el$199.nextSibling;
2333
+ _$insert(_el$200, () => status().text);
2334
+ _$effect(_p$ => {
2335
+ var _v$44 = status().tone,
2336
+ _v$45 = status().tone === "busy" ? "ti ti-loader-2 k2b-spin" : status().tone === "done" ? "ti ti-check" : "ti ti-alert-circle";
2337
+ _v$44 !== _p$.e && _$setAttribute(_el$198, "data-tone", _p$.e = _v$44);
2338
+ _v$45 !== _p$.t && _$className(_el$199, _p$.t = _v$45);
2339
+ return _p$;
2340
+ }, {
2341
+ e: undefined,
2342
+ t: undefined
2343
+ });
2344
+ return _el$198;
2345
+ })()
2346
+ }), _el$105, _co$25);
2347
+ _$insert(_el$103, _$createComponent(Show, {
2348
+ get when() {
2349
+ return _$memo(() => !!suggestionsOpen())() && announcement();
2350
+ },
2351
+ keyed: true,
2352
+ children: announced => (() => {
2353
+ var _el$201 = _$getNextElement(_tmpl$44);
2354
+ _$insert(_el$201, () => announced.text);
2355
+ return _el$201;
2356
+ })()
2357
+ }), _el$107, _co$26);
1769
2358
  _$effect(_p$ => {
1770
- var _v$15 = `k2b-chat-composer ${props.class ?? ""}`,
1771
- _v$16 = running() ? "true" : undefined,
1772
- _v$17 = conversation() ? "conversation" : undefined,
1773
- _v$18 = props.label ?? chatMessages().messageComposer;
1774
- _v$15 !== _p$.e && _$className(_el$57, _p$.e = _v$15);
1775
- _v$16 !== _p$.t && _$setAttribute(_el$57, "data-running", _p$.t = _v$16);
1776
- _v$17 !== _p$.a && _$setAttribute(_el$57, "data-variant", _p$.a = _v$17);
1777
- _v$18 !== _p$.o && _$setAttribute(_el$57, "aria-label", _p$.o = _v$18);
2359
+ var _v$24 = `k2b-chat-composer ${props.class ?? ""}`,
2360
+ _v$25 = running() ? "true" : undefined,
2361
+ _v$26 = conversation() ? "conversation" : undefined,
2362
+ _v$27 = props.label ?? chatMessages().messageComposer;
2363
+ _v$24 !== _p$.e && _$className(_el$70, _p$.e = _v$24);
2364
+ _v$25 !== _p$.t && _$setAttribute(_el$70, "data-running", _p$.t = _v$25);
2365
+ _v$26 !== _p$.a && _$setAttribute(_el$70, "data-variant", _p$.a = _v$26);
2366
+ _v$27 !== _p$.o && _$setAttribute(_el$70, "aria-label", _p$.o = _v$27);
1778
2367
  return _p$;
1779
2368
  }, {
1780
2369
  e: undefined,
@@ -1782,8 +2371,8 @@ export function ChatComposer(props) {
1782
2371
  a: undefined,
1783
2372
  o: undefined
1784
2373
  });
1785
- return _el$29;
2374
+ return _el$42;
1786
2375
  })();
1787
2376
  }
1788
- _$delegateEvents(["input", "click", "keyup", "beforeinput", "keydown", "pointerdown", "mousedown"]);
2377
+ _$delegateEvents(["input", "click", "keyup", "beforeinput", "keydown", "mousedown"]);
1789
2378
  //# sourceMappingURL=ChatComposer.js.map