@k2b/ui 0.28.0 → 0.30.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 (278) hide show
  1. package/README.md +1 -1
  2. package/dist/base.css +2 -2
  3. package/dist/browser/actions/ContextMenu.js +5 -0
  4. package/dist/browser/actions/ContextMenu.js.map +1 -1
  5. package/dist/browser/actions/DragAndDrop.js +89 -0
  6. package/dist/browser/actions/DragAndDrop.js.map +1 -0
  7. package/dist/browser/actions/Dropdown.js +6 -3
  8. package/dist/browser/actions/Dropdown.js.map +1 -1
  9. package/dist/browser/actions/FilterChip.js +137 -7
  10. package/dist/browser/actions/FilterChip.js.map +1 -1
  11. package/dist/browser/actions/GestureMenu.js +26 -3
  12. package/dist/browser/actions/GestureMenu.js.map +1 -1
  13. package/dist/browser/actions/SegmentedControl.js +5 -9
  14. package/dist/browser/actions/SegmentedControl.js.map +1 -1
  15. package/dist/browser/actions/SpotlightSearch.js +6 -3
  16. package/dist/browser/actions/SpotlightSearch.js.map +1 -1
  17. package/dist/browser/actions/Tabs.js +5 -2
  18. package/dist/browser/actions/Tabs.js.map +1 -1
  19. package/dist/browser/actions/ViewTabs.js +294 -0
  20. package/dist/browser/actions/ViewTabs.js.map +1 -0
  21. package/dist/browser/actions/drag-and-drop-messages.js +75 -0
  22. package/dist/browser/actions/drag-and-drop-messages.js.map +1 -0
  23. package/dist/browser/actions/drag-and-drop.js +692 -0
  24. package/dist/browser/actions/drag-and-drop.js.map +1 -0
  25. package/dist/browser/actions/filter-messages.js +6 -2
  26. package/dist/browser/actions/filter-messages.js.map +1 -1
  27. package/dist/browser/actions/index.js +3 -1
  28. package/dist/browser/actions/index.js.map +1 -1
  29. package/dist/browser/chat/ChatComposer.js +1229 -605
  30. package/dist/browser/chat/ChatComposer.js.map +1 -1
  31. package/dist/browser/chat/ChatDecision.js +814 -0
  32. package/dist/browser/chat/ChatDecision.js.map +1 -0
  33. package/dist/browser/chat/ChatPrimitives.js +292 -153
  34. package/dist/browser/chat/ChatPrimitives.js.map +1 -1
  35. package/dist/browser/chat/ChatTimeline.js.map +1 -1
  36. package/dist/browser/chat/chat-messages.js +14 -0
  37. package/dist/browser/chat/chat-messages.js.map +1 -1
  38. package/dist/browser/chat/command-search.js +35 -17
  39. package/dist/browser/chat/command-search.js.map +1 -1
  40. package/dist/browser/chat/index.js +10 -3
  41. package/dist/browser/chat/index.js.map +1 -1
  42. package/dist/browser/chat/types.js.map +1 -1
  43. package/dist/browser/content/Calendar.js +146 -119
  44. package/dist/browser/content/Calendar.js.map +1 -1
  45. package/dist/browser/content/CalendarWeekView.js +291 -266
  46. package/dist/browser/content/CalendarWeekView.js.map +1 -1
  47. package/dist/browser/content/Chart.js +54 -71
  48. package/dist/browser/content/Chart.js.map +1 -1
  49. package/dist/browser/content/DataTable.js +224 -155
  50. package/dist/browser/content/DataTable.js.map +1 -1
  51. package/dist/browser/content/FileBrowser.js +2 -2
  52. package/dist/browser/content/FileBrowser.js.map +1 -1
  53. package/dist/browser/content/FileTree.js +42 -36
  54. package/dist/browser/content/FileTree.js.map +1 -1
  55. package/dist/browser/content/FileTypeIcon.js +72 -0
  56. package/dist/browser/content/FileTypeIcon.js.map +1 -0
  57. package/dist/browser/content/FileView.js +2 -2
  58. package/dist/browser/content/FileView.js.map +1 -1
  59. package/dist/browser/content/ReferenceChip.js +162 -0
  60. package/dist/browser/content/ReferenceChip.js.map +1 -0
  61. package/dist/browser/content/calendar-pointer.js +9 -0
  62. package/dist/browser/content/calendar-pointer.js.map +1 -1
  63. package/dist/browser/content/calendar-time-view.js +6 -3
  64. package/dist/browser/content/calendar-time-view.js.map +1 -1
  65. package/dist/browser/content/data-table-messages.js +4 -2
  66. package/dist/browser/content/data-table-messages.js.map +1 -1
  67. package/dist/browser/content/index.js +2 -0
  68. package/dist/browser/content/index.js.map +1 -1
  69. package/dist/browser/feedback/MovedHint.js +197 -0
  70. package/dist/browser/feedback/MovedHint.js.map +1 -0
  71. package/dist/browser/feedback/dialog-core.js +66 -9
  72. package/dist/browser/feedback/dialog-core.js.map +1 -1
  73. package/dist/browser/feedback/index.js +1 -0
  74. package/dist/browser/feedback/index.js.map +1 -1
  75. package/dist/browser/feedback/prompts.js +6 -1
  76. package/dist/browser/feedback/prompts.js.map +1 -1
  77. package/dist/browser/inputs/DatePicker.js +337 -212
  78. package/dist/browser/inputs/DatePicker.js.map +1 -1
  79. package/dist/browser/inputs/date-picker.js +59 -5
  80. package/dist/browser/inputs/date-picker.js.map +1 -1
  81. package/dist/browser/intl/messages.js +12 -0
  82. package/dist/browser/intl/messages.js.map +1 -1
  83. package/dist/browser/intl/weekend.js +39 -0
  84. package/dist/browser/intl/weekend.js.map +1 -0
  85. package/dist/browser/layout/AppOverview.js +1 -2
  86. package/dist/browser/layout/AppOverview.js.map +1 -1
  87. package/dist/browser/layout/AppWorkspace.js +947 -531
  88. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  89. package/dist/browser/layout/PageTitle.js +3 -2
  90. package/dist/browser/layout/PageTitle.js.map +1 -1
  91. package/dist/browser/layout/PanelDialog.js +88 -86
  92. package/dist/browser/layout/PanelDialog.js.map +1 -1
  93. package/dist/browser/layout/ResizeSeparator.js +81 -0
  94. package/dist/browser/layout/ResizeSeparator.js.map +1 -0
  95. package/dist/browser/layout/SettingsModal.js +2 -2
  96. package/dist/browser/layout/SettingsModal.js.map +1 -1
  97. package/dist/browser/layout/SidebarSwitcher.js +19 -11
  98. package/dist/browser/layout/SidebarSwitcher.js.map +1 -1
  99. package/dist/browser/layout/TabBar.js +16 -13
  100. package/dist/browser/layout/TabBar.js.map +1 -1
  101. package/dist/browser/layout/app-host-width.js +44 -0
  102. package/dist/browser/layout/app-host-width.js.map +1 -0
  103. package/dist/browser/layout/app-workspace-controller.js +337 -44
  104. package/dist/browser/layout/app-workspace-controller.js.map +1 -1
  105. package/dist/browser/layout/index.js +4 -1
  106. package/dist/browser/layout/index.js.map +1 -1
  107. package/dist/browser/layout/resize-separator.js +90 -0
  108. package/dist/browser/layout/resize-separator.js.map +1 -0
  109. package/dist/browser/layout/workspace-messages.js +12 -2
  110. package/dist/browser/layout/workspace-messages.js.map +1 -1
  111. package/dist/browser/surfaces/LinkCard.js +1 -1
  112. package/dist/browser/surfaces/LinkCard.js.map +1 -1
  113. package/dist/browser/surfaces/Placeholder.js +45 -11
  114. package/dist/browser/surfaces/Placeholder.js.map +1 -1
  115. package/dist/browser/surfaces/StatCell.js +23 -0
  116. package/dist/browser/surfaces/StatCell.js.map +1 -1
  117. package/dist/browser/widgets/Widget.js +1 -1
  118. package/dist/browser/widgets/Widget.js.map +1 -1
  119. package/dist/ssr/actions/ContextMenu.js +5 -0
  120. package/dist/ssr/actions/ContextMenu.js.map +1 -1
  121. package/dist/ssr/actions/DragAndDrop.js +63 -0
  122. package/dist/ssr/actions/DragAndDrop.js.map +1 -0
  123. package/dist/ssr/actions/Dropdown.js +5 -2
  124. package/dist/ssr/actions/Dropdown.js.map +1 -1
  125. package/dist/ssr/actions/FilterChip.js +59 -7
  126. package/dist/ssr/actions/FilterChip.js.map +1 -1
  127. package/dist/ssr/actions/GestureMenu.js +26 -3
  128. package/dist/ssr/actions/GestureMenu.js.map +1 -1
  129. package/dist/ssr/actions/SegmentedControl.js +1 -2
  130. package/dist/ssr/actions/SegmentedControl.js.map +1 -1
  131. package/dist/ssr/actions/SpotlightSearch.js +2 -2
  132. package/dist/ssr/actions/SpotlightSearch.js.map +1 -1
  133. package/dist/ssr/actions/Tabs.js +2 -2
  134. package/dist/ssr/actions/Tabs.js.map +1 -1
  135. package/dist/ssr/actions/ViewTabs.js +211 -0
  136. package/dist/ssr/actions/ViewTabs.js.map +1 -0
  137. package/dist/ssr/actions/drag-and-drop-messages.js +75 -0
  138. package/dist/ssr/actions/drag-and-drop-messages.js.map +1 -0
  139. package/dist/ssr/actions/drag-and-drop.js +692 -0
  140. package/dist/ssr/actions/drag-and-drop.js.map +1 -0
  141. package/dist/ssr/actions/filter-messages.js +6 -2
  142. package/dist/ssr/actions/filter-messages.js.map +1 -1
  143. package/dist/ssr/actions/index.js +3 -1
  144. package/dist/ssr/actions/index.js.map +1 -1
  145. package/dist/ssr/chat/ChatComposer.js +668 -136
  146. package/dist/ssr/chat/ChatComposer.js.map +1 -1
  147. package/dist/ssr/chat/ChatDecision.js +479 -0
  148. package/dist/ssr/chat/ChatDecision.js.map +1 -0
  149. package/dist/ssr/chat/ChatPrimitives.js +95 -24
  150. package/dist/ssr/chat/ChatPrimitives.js.map +1 -1
  151. package/dist/ssr/chat/ChatTimeline.js.map +1 -1
  152. package/dist/ssr/chat/chat-messages.js +14 -0
  153. package/dist/ssr/chat/chat-messages.js.map +1 -1
  154. package/dist/ssr/chat/command-search.js +35 -17
  155. package/dist/ssr/chat/command-search.js.map +1 -1
  156. package/dist/ssr/chat/index.js +10 -3
  157. package/dist/ssr/chat/index.js.map +1 -1
  158. package/dist/ssr/chat/types.js.map +1 -1
  159. package/dist/ssr/content/Calendar.js +112 -103
  160. package/dist/ssr/content/Calendar.js.map +1 -1
  161. package/dist/ssr/content/CalendarWeekView.js +42 -28
  162. package/dist/ssr/content/CalendarWeekView.js.map +1 -1
  163. package/dist/ssr/content/Chart.js +19 -23
  164. package/dist/ssr/content/Chart.js.map +1 -1
  165. package/dist/ssr/content/DataTable.js +78 -31
  166. package/dist/ssr/content/DataTable.js.map +1 -1
  167. package/dist/ssr/content/FileBrowser.js +2 -2
  168. package/dist/ssr/content/FileBrowser.js.map +1 -1
  169. package/dist/ssr/content/FileTree.js +21 -14
  170. package/dist/ssr/content/FileTree.js.map +1 -1
  171. package/dist/ssr/content/FileTypeIcon.js +50 -0
  172. package/dist/ssr/content/FileTypeIcon.js.map +1 -0
  173. package/dist/ssr/content/FileView.js +2 -2
  174. package/dist/ssr/content/FileView.js.map +1 -1
  175. package/dist/ssr/content/ReferenceChip.js +121 -0
  176. package/dist/ssr/content/ReferenceChip.js.map +1 -0
  177. package/dist/ssr/content/calendar-pointer.js +9 -0
  178. package/dist/ssr/content/calendar-pointer.js.map +1 -1
  179. package/dist/ssr/content/calendar-time-view.js +6 -3
  180. package/dist/ssr/content/calendar-time-view.js.map +1 -1
  181. package/dist/ssr/content/data-table-messages.js +4 -2
  182. package/dist/ssr/content/data-table-messages.js.map +1 -1
  183. package/dist/ssr/content/index.js +2 -0
  184. package/dist/ssr/content/index.js.map +1 -1
  185. package/dist/ssr/feedback/MovedHint.js +166 -0
  186. package/dist/ssr/feedback/MovedHint.js.map +1 -0
  187. package/dist/ssr/feedback/dialog-core.js +66 -9
  188. package/dist/ssr/feedback/dialog-core.js.map +1 -1
  189. package/dist/ssr/feedback/index.js +1 -0
  190. package/dist/ssr/feedback/index.js.map +1 -1
  191. package/dist/ssr/feedback/prompts.js +6 -1
  192. package/dist/ssr/feedback/prompts.js.map +1 -1
  193. package/dist/ssr/inputs/DatePicker.js +138 -69
  194. package/dist/ssr/inputs/DatePicker.js.map +1 -1
  195. package/dist/ssr/inputs/date-picker.js +59 -5
  196. package/dist/ssr/inputs/date-picker.js.map +1 -1
  197. package/dist/ssr/intl/messages.js +12 -0
  198. package/dist/ssr/intl/messages.js.map +1 -1
  199. package/dist/ssr/intl/weekend.js +39 -0
  200. package/dist/ssr/intl/weekend.js.map +1 -0
  201. package/dist/ssr/layout/AppOverview.js +1 -2
  202. package/dist/ssr/layout/AppOverview.js.map +1 -1
  203. package/dist/ssr/layout/AppWorkspace.js +457 -116
  204. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  205. package/dist/ssr/layout/PageTitle.js +3 -2
  206. package/dist/ssr/layout/PageTitle.js.map +1 -1
  207. package/dist/ssr/layout/PanelDialog.js +7 -6
  208. package/dist/ssr/layout/PanelDialog.js.map +1 -1
  209. package/dist/ssr/layout/ResizeSeparator.js +45 -0
  210. package/dist/ssr/layout/ResizeSeparator.js.map +1 -0
  211. package/dist/ssr/layout/SettingsModal.js +2 -2
  212. package/dist/ssr/layout/SettingsModal.js.map +1 -1
  213. package/dist/ssr/layout/SidebarSwitcher.js +19 -11
  214. package/dist/ssr/layout/SidebarSwitcher.js.map +1 -1
  215. package/dist/ssr/layout/TabBar.js +2 -2
  216. package/dist/ssr/layout/TabBar.js.map +1 -1
  217. package/dist/ssr/layout/app-host-width.js +44 -0
  218. package/dist/ssr/layout/app-host-width.js.map +1 -0
  219. package/dist/ssr/layout/app-workspace-controller.js +337 -44
  220. package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
  221. package/dist/ssr/layout/index.js +4 -1
  222. package/dist/ssr/layout/index.js.map +1 -1
  223. package/dist/ssr/layout/resize-separator.js +90 -0
  224. package/dist/ssr/layout/resize-separator.js.map +1 -0
  225. package/dist/ssr/layout/workspace-messages.js +12 -2
  226. package/dist/ssr/layout/workspace-messages.js.map +1 -1
  227. package/dist/ssr/surfaces/LinkCard.js +1 -1
  228. package/dist/ssr/surfaces/LinkCard.js.map +1 -1
  229. package/dist/ssr/surfaces/Placeholder.js +25 -6
  230. package/dist/ssr/surfaces/Placeholder.js.map +1 -1
  231. package/dist/ssr/surfaces/StatCell.js +23 -0
  232. package/dist/ssr/surfaces/StatCell.js.map +1 -1
  233. package/dist/ssr/widgets/Widget.js +1 -1
  234. package/dist/ssr/widgets/Widget.js.map +1 -1
  235. package/dist/styles.css +1 -1
  236. package/dist/types/actions/ContextMenu.d.ts +1 -0
  237. package/dist/types/actions/DragAndDrop.d.ts +29 -0
  238. package/dist/types/actions/Dropdown.d.ts +4 -0
  239. package/dist/types/actions/FilterChip.d.ts +22 -0
  240. package/dist/types/actions/ViewTabs.d.ts +30 -0
  241. package/dist/types/actions/drag-and-drop-messages.d.ts +35 -0
  242. package/dist/types/actions/drag-and-drop.d.ts +36 -0
  243. package/dist/types/actions/filter-messages.d.ts +2 -0
  244. package/dist/types/actions/index.d.ts +6 -2
  245. package/dist/types/chat/ChatComposer.d.ts +71 -1
  246. package/dist/types/chat/ChatDecision.d.ts +149 -0
  247. package/dist/types/chat/ChatPrimitives.d.ts +14 -1
  248. package/dist/types/chat/ChatTimeline.d.ts +2 -1
  249. package/dist/types/chat/chat-messages.d.ts +7 -0
  250. package/dist/types/chat/command-search.d.ts +5 -0
  251. package/dist/types/chat/index.d.ts +28 -5
  252. package/dist/types/chat/types.d.ts +54 -1
  253. package/dist/types/content/Chart.d.ts +9 -3
  254. package/dist/types/content/DataTable.d.ts +3 -0
  255. package/dist/types/content/FileTypeIcon.d.ts +27 -0
  256. package/dist/types/content/ReferenceChip.d.ts +49 -0
  257. package/dist/types/content/calendar-pointer.d.ts +6 -0
  258. package/dist/types/content/data-table-messages.d.ts +1 -0
  259. package/dist/types/content/index.d.ts +3 -0
  260. package/dist/types/feedback/MovedHint.d.ts +25 -0
  261. package/dist/types/feedback/dialog-core.d.ts +5 -2
  262. package/dist/types/feedback/index.d.ts +2 -0
  263. package/dist/types/feedback/prompts.d.ts +2 -0
  264. package/dist/types/inputs/DatePicker.d.ts +7 -0
  265. package/dist/types/inputs/date-picker.d.ts +25 -1
  266. package/dist/types/intl/messages.d.ts +6 -0
  267. package/dist/types/intl/weekend.d.ts +12 -0
  268. package/dist/types/layout/AppWorkspace.d.ts +48 -10
  269. package/dist/types/layout/ResizeSeparator.d.ts +9 -0
  270. package/dist/types/layout/TabBar.d.ts +7 -0
  271. package/dist/types/layout/app-host-width.d.ts +6 -0
  272. package/dist/types/layout/app-workspace-controller.d.ts +2 -0
  273. package/dist/types/layout/index.d.ts +5 -2
  274. package/dist/types/layout/resize-separator.d.ts +18 -0
  275. package/dist/types/layout/workspace-messages.d.ts +5 -0
  276. package/dist/types/surfaces/Placeholder.d.ts +2 -1
  277. package/dist/types/surfaces/StatCell.d.ts +6 -0
  278. package/package.json +5 -5
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["chat/command-search.ts"],"sourcesContent":["import { fuzzy } from \"@k2b/stdlib\";\nimport type { ChatCommand, ChatCommandScope, ChatCommandSection } from \"./ChatComposer\";\nimport { chatCommandKey, foldChatSearchText } from \"./chat-behavior\";\n\nconst wordPattern = /[^\\s\\-_.\\/·:,()„“\"']+/gu;\nconst words = (text: string) => [...text.matchAll(wordPattern)];\ntype Rank = { rank: number; highlight?: readonly [number, number] };\n\nconst prepare = (command: ChatCommand) => {\n const title = command.label ?? command.name;\n // Each folded UTF-16 position maps to the whole original character and its combining marks.\n const starts: number[] = [],\n ends: number[] = [];\n let foldedTitle = \"\";\n for (const part of title.matchAll(/\\P{M}\\p{M}*|\\p{M}+/gu)) {\n const folded = foldChatSearchText(part[0]);\n foldedTitle += folded;\n for (let i = 0; i < folded.length; i++) {\n starts.push(part.index);\n ends.push(part.index + part[0].length);\n }\n }\n return {\n foldedTitle,\n starts,\n ends,\n titleWords: words(foldedTitle),\n keywords: [...(command.keywords ?? []), ...(command.label !== undefined ? [command.name] : [])].map(foldChatSearchText),\n app: foldChatSearchText(command.app ?? \"\"),\n descriptionWords: words(foldChatSearchText(command.description)),\n };\n};\n\nconst rankPrepared = (entry: ReturnType<typeof prepare>, query: string): Rank | null => {\n if (!query) return { rank: 0 };\n const titleMatch = (rank: number, index: number): Rank => ({\n rank,\n highlight: [entry.starts[index]!, entry.ends[index + query.length - 1]!],\n });\n if (entry.foldedTitle.startsWith(query)) return titleMatch(0, 0);\n const word = entry.titleWords.find((word) => word[0].startsWith(query));\n if (word) return titleMatch(1, word.index);\n const index = entry.foldedTitle.indexOf(query);\n if (index >= 0) return titleMatch(2, index);\n if (entry.keywords.some((word) => word.startsWith(query))) return { rank: 3 };\n if (entry.app.startsWith(query)) return { rank: 4 };\n if (query.length >= 3 && entry.descriptionWords.some((word) => word[0].startsWith(query))) return { rank: 5 };\n if (query.length >= 4) {\n for (const word of [...entry.titleWords.map((word) => word[0]), ...entry.keywords]) {\n for (const length of [query.length - 1, query.length, query.length + 1]) {\n if (word.length >= length && fuzzy.distance(query, word.slice(0, length)) <= 1) return { rank: 6 };\n }\n }\n }\n return null;\n};\n\nexport const rankChatCommand = (command: ChatCommand, query: string): Rank | null =>\n rankPrepared(prepare(command), foldChatSearchText(query).trim());\n\nexport function resolveChatCommandScope(word: string, scopes: readonly ChatCommandScope[]): ChatCommandScope | undefined {\n const query = foldChatSearchText(word);\n const folded = scopes.map((scope) => ({ scope, words: scope.words.map(foldChatSearchText) }));\n const exact = folded.filter((entry) => entry.words.includes(query));\n if (exact.length) return exact.length === 1 ? exact[0]?.scope : undefined;\n if (query.length < 3) return undefined;\n let best: ChatCommandScope | undefined,\n extension = Infinity;\n for (const entry of folded) {\n const extra = Math.min(...entry.words.filter((word) => word.startsWith(query)).map((word) => word.length - query.length));\n if (extra < extension) {\n best = entry.scope;\n extension = extra;\n } else if (extra === extension) best = undefined;\n }\n return best;\n}\n\nexport function parseChatCommandQuery(query: string, scopes: readonly ChatCommandScope[]): { scope?: ChatCommandScope; query: string } {\n const match = /^(\\S+)\\s(.*)$/s.exec(query);\n const scope = match ? resolveChatCommandScope(match[1]!, scopes) : undefined;\n return scope ? { scope, query: match![2]!.trimStart() } : { query };\n}\n\nexport type ChatCommandRow = { command: ChatCommand; server: boolean; highlight?: readonly [number, number] };\ntype Group = { section?: ChatCommandSection; scopeTitle?: string; rows: ChatCommandRow[]; loading: boolean; placeholder: boolean };\n\nexport function chatCommandListModel(input: {\n query: string;\n scopes?: readonly ChatCommandScope[];\n sections?: readonly ChatCommandSection[];\n commands: readonly ChatCommand[];\n searchResults: readonly ChatCommand[];\n searchResultsFresh: boolean;\n searchSettled: boolean;\n searching: boolean;\n}): { scope?: ChatCommandScope; groups: Group[]; rows: ChatCommandRow[]; empty: boolean } {\n const { scope, query: rawQuery } = parseChatCommandQuery(input.query, input.scopes ?? []);\n const query = foldChatSearchText(rawQuery).trim();\n const overview = !scope && !query;\n const groups: Group[] = scope\n ? [{ scopeTitle: scope.title, rows: [], loading: input.searching, placeholder: false }]\n : [\n ...(input.sections ?? []).map((section) => ({\n section,\n rows: [],\n loading: Boolean(section.searched && input.searching && !(overview && section.searchOnly)),\n placeholder: false,\n })),\n { rows: [], loading: !input.sections?.length && input.searching, placeholder: false },\n ];\n const bySection = new Map(groups.map((group, index) => [group.section?.id, index]));\n const buckets: { command: ChatCommand; server: boolean }[][] = groups.map(() => []);\n for (const [commands, server] of [\n [scope ? [] : input.commands, false],\n [input.searchResults, true],\n ] as const) {\n for (const command of commands) {\n const index = scope ? 0 : (bySection.get(command.section) ?? groups.length - 1);\n buckets[index]!.push({ command, server });\n }\n }\n const seen = new Set<string>();\n for (const [index, group] of groups.entries()) {\n // A search-only section is absent from the overview, rows and placeholder included.\n if (overview && group.section?.searchOnly) continue;\n const ranked: (ChatCommandRow & { rank: number })[] = [];\n for (const { command, server } of buckets[index]!) {\n const key = chatCommandKey(command);\n if (seen.has(key)) continue;\n if (overview && command.hiddenUntilSearch) continue;\n const match = rankPrepared(prepare(command), query);\n if (!overview && !match && !(server && input.searchResultsFresh)) continue;\n seen.add(key);\n ranked.push({ command, server, highlight: match?.highlight, rank: match?.rank ?? Infinity });\n }\n if (!overview) ranked.sort((a, b) => a.rank - b.rank);\n group.rows = ranked.map(({ command, server, highlight }) => ({ command, server, highlight }));\n group.placeholder =\n group.loading && group.rows.length === 0 && Boolean(scope || !input.searchSettled || buckets[index]!.some((entry) => entry.server));\n }\n // A section without rows has no heading, also in the overview; a scope always shows its title.\n const visible = groups.filter((group) => scope || group.rows.length || group.placeholder);\n const rows = visible.flatMap((group) => group.rows);\n return { scope, groups: visible, rows, empty: rows.length === 0 && !input.searching };\n}\n\n/** Use the composer ranking rules to filter consumer-owned server rows. */\nexport const matchesChatCommand = (command: ChatCommand, query: string): boolean => rankChatCommand(command, query) !== null;\n"],"mappings":"AAAA,SAAS,KAAK,QAAQ,aAAa;AAEnC,SAAS,cAAc,EAAE,kBAAkB,QAAQ,iBAAiB;AAEpE,MAAM,WAAW,GAAG,yBAAyB;AAC7C,MAAM,KAAK,GAAI,IAAY,IAAK,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAG/D,MAAM,OAAO,GAAI,OAAoB,IAAK;EACxC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,IAAI;EAC3C;EACA,MAAM,MAAgB,GAAG,EAAE;IACzB,IAAc,GAAG,EAAE;EACrB,IAAI,WAAW,GAAG,EAAE;EACpB,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,QAAQ,CAAC,sBAAsB,CAAC,EAAE;IACzD,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1C,WAAW,IAAI,MAAM;IACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;MACtC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;MACvB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACxC;EACF;EACA,OAAO;IACL,WAAW;IACX,MAAM;IACN,IAAI;IACJ,UAAU,EAAE,KAAK,CAAC,WAAW,CAAC;IAC9B,QAAQ,EAAE,CAAC,IAAI,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC;IACvH,GAAG,EAAE,kBAAkB,CAAC,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC;IAC1C,gBAAgB,EAAE,KAAK,CAAC,kBAAkB,CAAC,OAAO,CAAC,WAAW,CAAC;EACjE,CAAC;AACH,CAAC;AAED,MAAM,YAAY,GAAG,CAAC,KAAiC,EAAE,KAAa,KAAkB;EACtF,IAAI,CAAC,KAAK,EAAE,OAAO;IAAE,IAAI,EAAE;EAAE,CAAC;EAC9B,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,KAAa,MAAY;IACzD,IAAI;IACJ,SAAS,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EAAG,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;EACxE,CAAC,CAAC;EACF,IAAI,KAAK,CAAC,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC;EAChE,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,IAAI,CAAE,IAAI,IAAK,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;EACvE,IAAI,IAAI,EAAE,OAAO,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC;EAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;EAC9C,IAAI,KAAK,IAAI,CAAC,EAAE,OAAO,UAAU,CAAC,CAAC,EAAE,KAAK,CAAC;EAC3C,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAE,IAAI,IAAK,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO;IAAE,IAAI,EAAE;EAAE,CAAC;EAC7E,IAAI,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,OAAO;IAAE,IAAI,EAAE;EAAE,CAAC;EACnD,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAE,IAAI,IAAK,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO;IAAE,IAAI,EAAE;EAAE,CAAC;EAC7G,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE;IACrB,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAE,IAAI,IAAK,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,QAAQ,CAAC,EAAE;MAClF,KAAK,MAAM,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE;QACvE,IAAI,IAAI,CAAC,MAAM,IAAI,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO;UAAE,IAAI,EAAE;QAAE,CAAC;MACpG;IACF;EACF;EACA,OAAO,IAAI;AACb,CAAC;AAED,OAAO,MAAM,eAAe,GAAG,CAAC,OAAoB,EAAE,KAAa,KACjE,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,kBAAkB,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAElE,OAAO,SAAS,uBAAuB,CAAC,IAAY,EAAE,MAAmC,EAAgC;EACvH,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC;EACtC,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAE,KAAK,KAAM;IAAE,KAAK;IAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB;EAAE,CAAC,CAAC,CAAC;EAC7F,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAE,KAAK,IAAK,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;EACnE,IAAI,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,SAAS;EACzE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,OAAO,SAAS;EACtC,IAAI,IAAkC;IACpC,SAAS,GAAG,QAAQ;EACtB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;IAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAE,IAAI,IAAK,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAE,IAAI,IAAK,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IACzH,IAAI,KAAK,GAAG,SAAS,EAAE;MACrB,IAAI,GAAG,KAAK,CAAC,KAAK;MAClB,SAAS,GAAG,KAAK;IACnB,CAAC,MAAM,IAAI,KAAK,KAAK,SAAS,EAAE,IAAI,GAAG,SAAS;EAClD;EACA,OAAO,IAAI;AACb;AAEA,OAAO,SAAS,qBAAqB,CAAC,KAAa,EAAE,MAAmC,EAA+C;EACrI,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC;EAC1C,MAAM,KAAK,GAAG,KAAK,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAG,MAAM,CAAC,GAAG,SAAS;EAC5E,OAAO,KAAK,GAAG;IAAE,KAAK;IAAE,KAAK,EAAE,KAAK,CAAE,CAAC,CAAC,CAAE,SAAS,CAAC;EAAE,CAAC,GAAG;IAAE;EAAM,CAAC;AACrE;AAKA,OAAO,SAAS,oBAAoB,CAAC,KASpC,EAAyF;EACxF,MAAM;IAAE,KAAK;IAAE,KAAK,EAAE;EAAS,CAAC,GAAG,qBAAqB,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC;EACzF,MAAM,KAAK,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC;EACjD,MAAM,QAAQ,GAAG,CAAC,KAAK,IAAI,CAAC,KAAK;EACjC,MAAM,MAAe,GAAG,KAAK,GACzB,CAAC;IAAE,UAAU,EAAE,KAAK,CAAC,KAAK;IAAE,IAAI,EAAE,EAAE;IAAE,OAAO,EAAE,KAAK,CAAC,SAAS;IAAE,WAAW,EAAE;EAAM,CAAC,CAAC,GACrF,CACE,GAAG,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,EAAE,GAAG,CAAE,OAAO,KAAM;IAC1C,OAAO;IACP,IAAI,EAAE,EAAE;IACR,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,QAAQ,IAAI,KAAK,CAAC,SAAS,IAAI,EAAE,QAAQ,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;IAC1F,WAAW,EAAE;EACf,CAAC,CAAC,CAAC,EACH;IAAE,IAAI,EAAE,EAAE;IAAE,OAAO,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,CAAC,SAAS;IAAE,WAAW,EAAE;EAAM,CAAC,CACtF;EACL,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;EACnF,MAAM,OAAsD,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;EACnF,KAAK,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAC/B,CAAC,KAAK,GAAG,EAAE,GAAG,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,EACpC,CAAC,KAAK,CAAC,aAAa,EAAE,IAAI,CAAC,CAC5B,EAAW;IACV,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;MAC9B,MAAM,KAAK,GAAG,KAAK,GAAG,CAAC,GAAI,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAE;MAC/E,OAAO,CAAC,KAAK,CAAC,CAAE,IAAI,CAAC;QAAE,OAAO;QAAE;MAAO,CAAC,CAAC;IAC3C;EACF;EACA,MAAM,IAAI,GAAG,IAAI,GAAG,CAAS,CAAC;EAC9B,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE;IAC7C;IACA,IAAI,QAAQ,IAAI,KAAK,CAAC,OAAO,EAAE,UAAU,EAAE;IAC3C,MAAM,MAA6C,GAAG,EAAE;IACxD,KAAK,MAAM;MAAE,OAAO;MAAE;IAAO,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,EAAG;MACjD,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,CAAC;MACnC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;MACnB,IAAI,QAAQ,IAAI,OAAO,CAAC,iBAAiB,EAAE;MAC3C,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC;MACnD,IAAI,CAAC,QAAQ,IAAI,CAAC,KAAK,IAAI,EAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,EAAE;MAClE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;MACb,MAAM,CAAC,IAAI,CAAC;QAAE,OAAO;QAAE,MAAM;QAAE,SAAS,EAAE,KAAK,EAAE,SAAS;QAAE,IAAI,EAAE,KAAK,EAAE,IAAI,IAAI;MAAS,CAAC,CAAC;IAC9F;IACA,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;IACrD,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;MAAE,OAAO;MAAE,MAAM;MAAE;IAAU,CAAC,MAAM;MAAE,OAAO;MAAE,MAAM;MAAE;IAAU,CAAC,CAAC,CAAC;IAC7F,KAAK,CAAC,WAAW,GACf,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,aAAa,IAAI,OAAO,CAAC,KAAK,CAAC,CAAE,IAAI,CAAE,KAAK,IAAK,KAAK,CAAC,MAAM,CAAC,CAAC;EACvI;EACA;EACA,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAE,KAAK,IAAK,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC;EACzF,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAE,KAAK,IAAK,KAAK,CAAC,IAAI,CAAC;EACnD,OAAO;IAAE,KAAK;IAAE,MAAM,EAAE,OAAO;IAAE,IAAI;IAAE,KAAK,EAAE,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;EAAU,CAAC;AACvF;;AAEA;AACA,OAAO,MAAM,kBAAkB,GAAG,CAAC,OAAoB,EAAE,KAAa,KAAc,eAAe,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,IAAI","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["chat/command-search.ts"],"sourcesContent":["import { fuzzy } from \"@k2b/stdlib\";\nimport type { ChatCommand, ChatCommandScope, ChatCommandSection } from \"./ChatComposer\";\nimport { chatCommandKey, foldChatSearchText } from \"./chat-behavior\";\n\nconst wordPattern = /[^\\s\\-_.\\/·:,()„“\"']+/gu;\nconst words = (text: string) => [...text.matchAll(wordPattern)];\ntype Rank = { rank: number; highlight?: readonly [number, number] };\n\nconst prepare = (command: ChatCommand) => {\n const title = command.label ?? command.name;\n // Each folded UTF-16 position maps to the whole original character and its combining marks.\n const starts: number[] = [],\n ends: number[] = [];\n let foldedTitle = \"\";\n for (const part of title.matchAll(/\\P{M}\\p{M}*|\\p{M}+/gu)) {\n const folded = foldChatSearchText(part[0]);\n foldedTitle += folded;\n for (let i = 0; i < folded.length; i++) {\n starts.push(part.index);\n ends.push(part.index + part[0].length);\n }\n }\n return {\n foldedTitle,\n starts,\n ends,\n titleWords: words(foldedTitle),\n keywords: [...(command.keywords ?? []), ...(command.label !== undefined ? [command.name] : [])].map(foldChatSearchText),\n app: foldChatSearchText(command.app ?? \"\"),\n descriptionWords: words(foldChatSearchText(command.description)),\n };\n};\n\nconst rankPrepared = (entry: ReturnType<typeof prepare>, query: string): Rank | null => {\n if (!query) return { rank: 0 };\n const titleMatch = (rank: number, index: number): Rank => ({\n rank,\n highlight: [entry.starts[index]!, entry.ends[index + query.length - 1]!],\n });\n if (entry.foldedTitle.startsWith(query)) return titleMatch(0, 0);\n const word = entry.titleWords.find((word) => word[0].startsWith(query));\n if (word) return titleMatch(1, word.index);\n const index = entry.foldedTitle.indexOf(query);\n if (index >= 0) return titleMatch(2, index);\n if (entry.keywords.some((word) => word.startsWith(query))) return { rank: 3 };\n if (entry.app.startsWith(query)) return { rank: 4 };\n if (query.length >= 3 && entry.descriptionWords.some((word) => word[0].startsWith(query))) return { rank: 5 };\n if (query.length >= 4) {\n for (const word of [...entry.titleWords.map((word) => word[0]), ...entry.keywords]) {\n for (const length of [query.length - 1, query.length, query.length + 1]) {\n if (word.length >= length && fuzzy.distance(query, word.slice(0, length)) <= 1) return { rank: 6 };\n }\n }\n }\n return null;\n};\n\nexport const rankChatCommand = (command: ChatCommand, query: string): Rank | null =>\n rankPrepared(prepare(command), foldChatSearchText(query).trim());\n\nexport function resolveChatCommandScope(word: string, scopes: readonly ChatCommandScope[]): ChatCommandScope | undefined {\n const query = foldChatSearchText(word);\n const folded = scopes.map((scope) => ({ scope, words: scope.words.map(foldChatSearchText) }));\n const exact = folded.filter((entry) => entry.words.includes(query));\n if (exact.length) return exact.length === 1 ? exact[0]?.scope : undefined;\n if (query.length < 3) return undefined;\n let best: ChatCommandScope | undefined,\n extension = Infinity;\n for (const entry of folded) {\n const extra = Math.min(...entry.words.filter((word) => word.startsWith(query)).map((word) => word.length - query.length));\n if (extra < extension) {\n best = entry.scope;\n extension = extra;\n } else if (extra === extension) best = undefined;\n }\n return best;\n}\n\nexport function parseChatCommandQuery(query: string, scopes: readonly ChatCommandScope[]): { scope?: ChatCommandScope; query: string } {\n const match = /^(\\S+)\\s(.*)$/s.exec(query);\n const scope = match ? resolveChatCommandScope(match[1]!, scopes) : undefined;\n return scope ? { scope, query: match![2]!.trimStart() } : { query };\n}\n\nexport type ChatCommandRow = { command: ChatCommand; server: boolean; highlight?: readonly [number, number] };\ntype Group = {\n section?: ChatCommandSection;\n scopeTitle?: string;\n rows: ChatCommandRow[];\n loading: boolean;\n placeholder: boolean;\n /** Placeholder rows of a `pending` section, after its rows: three in the overview, one while searching. */\n pendingRows: number;\n};\n\nexport function chatCommandListModel(input: {\n query: string;\n scopes?: readonly ChatCommandScope[];\n sections?: readonly ChatCommandSection[];\n commands: readonly ChatCommand[];\n searchResults: readonly ChatCommand[];\n searchResultsFresh: boolean;\n searchSettled: boolean;\n searching: boolean;\n /** The composer's `commandFallback` row for this query, if any. */\n fallback?: ChatCommand;\n}): { scope?: ChatCommandScope; groups: Group[]; rows: ChatCommandRow[]; empty: boolean; fallback?: ChatCommandRow } {\n const { scope, query: rawQuery } = parseChatCommandQuery(input.query, input.scopes ?? []);\n const query = foldChatSearchText(rawQuery).trim();\n const overview = !scope && !query;\n const groups: Group[] = scope\n ? [{ scopeTitle: scope.title, rows: [], loading: input.searching, placeholder: false, pendingRows: 0 }]\n : [\n ...(input.sections ?? []).map((section) => {\n // A section hidden for this query also hides its loading state.\n const hidden = overview ? section.searchOnly : section.overviewOnly;\n const pendingRows = section.pending && !hidden ? (overview ? 3 : 1) : 0;\n return {\n section,\n rows: [],\n loading: Boolean(pendingRows || (section.searched && input.searching && !hidden)),\n placeholder: false,\n pendingRows,\n };\n }),\n { rows: [], loading: !input.sections?.length && input.searching, placeholder: false, pendingRows: 0 },\n ];\n const bySection = new Map(groups.map((group, index) => [group.section?.id, index]));\n const buckets: { command: ChatCommand; server: boolean }[][] = groups.map(() => []);\n for (const [commands, server] of [\n [scope ? [] : input.commands, false],\n [input.searchResults, true],\n ] as const) {\n for (const command of commands) {\n const index = scope ? 0 : (bySection.get(command.section) ?? groups.length - 1);\n buckets[index]!.push({ command, server });\n }\n }\n const seen = new Set<string>();\n for (const [index, group] of groups.entries()) {\n // A search-only section is absent from the overview, rows and placeholder included; an overview-only one while searching.\n if (overview ? group.section?.searchOnly : group.section?.overviewOnly) continue;\n const ranked: (ChatCommandRow & { rank: number })[] = [];\n for (const { command, server } of buckets[index]!) {\n const key = chatCommandKey(command);\n if (seen.has(key)) continue;\n if (overview && command.hiddenUntilSearch) continue;\n const match = rankPrepared(prepare(command), query);\n if (!overview && !match && !command.persistent && !(server && input.searchResultsFresh)) continue;\n seen.add(key);\n // A recent match moves one step up the ladder and leads its rank.\n const rank = (match?.rank ?? Infinity) - (command.recent && match ? 1.5 : 0);\n ranked.push({ command, server, highlight: match?.highlight, rank });\n }\n if (!overview) ranked.sort((a, b) => a.rank - b.rank);\n group.rows = ranked.map(({ command, server, highlight }) => ({ command, server, highlight }));\n group.placeholder =\n !group.pendingRows &&\n group.loading &&\n group.rows.length === 0 &&\n Boolean(scope || !input.searchSettled || buckets[index]!.some((entry) => entry.server));\n }\n // A section without rows has no heading, also in the overview; a scope always shows its title.\n const visible = groups.filter((group) => scope || group.rows.length || group.placeholder || group.pendingRows);\n const matches = visible.flatMap((group) => group.rows);\n // The fallback is no match: unscoped it ends the list after \"Nothing found\"; in a scope it is the scope's last row.\n const fallback =\n !overview && input.fallback && !seen.has(chatCommandKey(input.fallback)) ? { command: input.fallback, server: false } : undefined;\n if (fallback && scope) visible[0]!.rows.push(fallback);\n return {\n scope,\n groups: visible,\n rows: fallback ? [...matches, fallback] : matches,\n // Rows still on their way may match, so \"Nothing found\" waits for them.\n empty: matches.length === 0 && !input.searching && !visible.some((group) => group.pendingRows),\n fallback: scope ? undefined : fallback,\n };\n}\n\n/** Use the composer ranking rules to filter consumer-owned server rows. */\nexport const matchesChatCommand = (command: ChatCommand, query: string): boolean => rankChatCommand(command, query) !== null;\n"],"mappings":"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","ignoreList":[]}
@@ -1,7 +1,8 @@
1
1
  import { ChatContextPanel, ChatContextPopup } from "./ChatContextPopup";
2
2
  import { ChatTasks } from "./ChatTasks";
3
3
  import { ChatComposer } from "./ChatComposer";
4
- import { ChatActivity, ChatContextUsage, ChatMessage } from "./ChatPrimitives";
4
+ import { ChatDecision, ChatMark, ChatOutcome, ChatPreview } from "./ChatDecision";
5
+ import { ChatActivity, ChatActivityToggle, ChatContextUsage, ChatMessage } from "./ChatPrimitives";
5
6
  import { ChatRoot } from "./ChatRoot";
6
7
  import { ChatTimeline } from "./ChatTimeline";
7
8
  export { formatChatTokens } from "./ChatPrimitives";
@@ -13,11 +14,17 @@ export const Chat = Object.assign(ChatRoot, {
13
14
  Tasks: ChatTasks,
14
15
  Timeline: ChatTimeline,
15
16
  Message: ChatMessage,
16
- Activity: ChatActivity,
17
+ Activity: Object.assign(ChatActivity, {
18
+ Toggle: ChatActivityToggle
19
+ }),
17
20
  Composer: ChatComposer,
18
21
  ContextUsage: ChatContextUsage,
19
22
  ContextPopup: ChatContextPopup,
20
- ContextPanel: ChatContextPanel
23
+ ContextPanel: ChatContextPanel,
24
+ Decision: ChatDecision,
25
+ Outcome: ChatOutcome,
26
+ Preview: ChatPreview,
27
+ Mark: ChatMark
21
28
  });
22
29
  export { matchesChatCommand } from "./command-search";
23
30
  export { reconcileChatMentions } from "./composer-document";
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["chat/index.ts"],"sourcesContent":["export type { ChatContextPanelProps, ChatContextPopupProps } from \"./ChatContextPopup\";\n\nimport { ChatContextPanel, ChatContextPopup } from \"./ChatContextPopup\";\nimport { ChatTasks } from \"./ChatTasks\";\n\nexport type { ChatTask, ChatTasksProps } from \"./ChatTasks\";\n\nimport { ChatComposer } from \"./ChatComposer\";\nimport { ChatActivity, ChatContextUsage, ChatMessage } from \"./ChatPrimitives\";\nimport { ChatRoot } from \"./ChatRoot\";\nimport { ChatTimeline } from \"./ChatTimeline\";\n\nexport type {\n ChatCommand,\n ChatCommandContext,\n ChatCommandResult,\n ChatCommandScope,\n ChatCommandSearch,\n ChatCommandSection,\n ChatComposerProps,\n ChatFileSelection,\n ChatPasteHandler,\n} from \"./ChatComposer\";\nexport type { ChatActivityProps, ChatContextUsageProps, ChatMessageProps } from \"./ChatPrimitives\";\nexport { formatChatTokens } from \"./ChatPrimitives\";\nexport type { ChatRootProps } from \"./ChatRoot\";\nexport type { ChatActivityItem, ChatMessageItem, ChatTimelineItem, ChatTimelineProps } from \"./ChatTimeline\";\nexport type {\n ChatAction,\n ChatActivityTone,\n ChatAttachment,\n ChatComposerEmoji,\n ChatComposerMicrophone,\n ChatComposerState,\n ChatContextUsageData,\n ChatDictationState,\n ChatMention,\n ChatMessageStatus,\n ChatModelOption,\n ChatRole,\n ChatSubmitInput,\n ChatSubmitIntent,\n ChatUsage,\n} from \"./types\";\n\n/**\n * Portable, controlled chat surface. Applications own storage, streaming,\n * authorization, rich message rendering, and domain actions.\n */\nexport const Chat = Object.assign(ChatRoot, {\n Tasks: ChatTasks,\n Timeline: ChatTimeline,\n Message: ChatMessage,\n Activity: ChatActivity,\n Composer: ChatComposer,\n ContextUsage: ChatContextUsage,\n ContextPopup: ChatContextPopup,\n ContextPanel: ChatContextPanel,\n});\n\nexport { matchesChatCommand } from \"./command-search\";\nexport { reconcileChatMentions } from \"./composer-document\";\n\nexport { type ReactionPeopleInput, reactionPeople } from \"./reaction-people\";\n"],"mappings":"AAEA,SAAS,gBAAgB,EAAE,gBAAgB,QAAQ,oBAAoB;AACvE,SAAS,SAAS,QAAQ,aAAa;AAIvC,SAAS,YAAY,QAAQ,gBAAgB;AAC7C,SAAS,YAAY,EAAE,gBAAgB,EAAE,WAAW,QAAQ,kBAAkB;AAC9E,SAAS,QAAQ,QAAQ,YAAY;AACrC,SAAS,YAAY,QAAQ,gBAAgB;AAc7C,SAAS,gBAAgB,QAAQ,kBAAkB;AAqBnD;AACA;AACA;AACA;AACA,OAAO,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE;EAC1C,KAAK,EAAE,SAAS;EAChB,QAAQ,EAAE,YAAY;EACtB,OAAO,EAAE,WAAW;EACpB,QAAQ,EAAE,YAAY;EACtB,QAAQ,EAAE,YAAY;EACtB,YAAY,EAAE,gBAAgB;EAC9B,YAAY,EAAE,gBAAgB;EAC9B,YAAY,EAAE;AAChB,CAAC,CAAC;AAEF,SAAS,kBAAkB,QAAQ,kBAAkB;AACrD,SAAS,qBAAqB,QAAQ,qBAAqB;AAE3D,SAAmC,cAAc,QAAQ,mBAAmB","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["chat/index.ts"],"sourcesContent":["export type { ChatContextPanelProps, ChatContextPopupProps } from \"./ChatContextPopup\";\n\nimport { ChatContextPanel, ChatContextPopup } from \"./ChatContextPopup\";\nimport { ChatTasks } from \"./ChatTasks\";\n\nexport type { ChatTask, ChatTasksProps } from \"./ChatTasks\";\n\nimport { ChatComposer } from \"./ChatComposer\";\nimport { ChatDecision, ChatMark, ChatOutcome, ChatPreview } from \"./ChatDecision\";\nimport { ChatActivity, ChatActivityToggle, ChatContextUsage, ChatMessage } from \"./ChatPrimitives\";\nimport { ChatRoot } from \"./ChatRoot\";\nimport { ChatTimeline } from \"./ChatTimeline\";\n\nexport type {\n ChatCommand,\n ChatCommandContext,\n ChatCommandDraft,\n ChatCommandOpenResult,\n ChatCommandResult,\n ChatCommandScope,\n ChatCommandSearch,\n ChatCommandSection,\n ChatComposerProps,\n ChatFileSelection,\n ChatPasteHandler,\n} from \"./ChatComposer\";\nexport type {\n ChatDecisionProps,\n ChatMarkProps,\n ChatOutcomeProps,\n ChatPreviewExcerptProps,\n ChatPreviewHeaderProps,\n ChatPreviewLineProps,\n ChatPreviewPeopleProps,\n ChatPreviewProps,\n ChatPreviewReadMoreProps,\n ChatPreviewShowAllProps,\n ChatPreviewTitleProps,\n} from \"./ChatDecision\";\nexport type { ChatActivityProps, ChatActivityToggleProps, ChatContextUsageProps, ChatMessageProps } from \"./ChatPrimitives\";\nexport { formatChatTokens } from \"./ChatPrimitives\";\nexport type { ChatRootProps } from \"./ChatRoot\";\nexport type { ChatActivityItem, ChatMessageItem, ChatTimelineItem, ChatTimelineProps } from \"./ChatTimeline\";\nexport type {\n ChatAction,\n ChatActivityTone,\n ChatAttachment,\n ChatComposerEmoji,\n ChatComposerMicrophone,\n ChatComposerState,\n ChatContextUsageData,\n ChatDecisionAnswer,\n ChatDecisionReason,\n ChatDecisionState,\n ChatDictationState,\n ChatMention,\n ChatMessageStatus,\n ChatModelOption,\n ChatOutcomeLine,\n ChatOutcomeTone,\n ChatPreviewHeaderRow,\n ChatPreviewPerson,\n ChatRole,\n ChatSubmitInput,\n ChatSubmitIntent,\n ChatUsage,\n} from \"./types\";\n\n/**\n * Portable, controlled chat surface. Applications own storage, streaming,\n * authorization, rich message rendering, and domain actions.\n */\nexport const Chat = Object.assign(ChatRoot, {\n Tasks: ChatTasks,\n Timeline: ChatTimeline,\n Message: ChatMessage,\n Activity: Object.assign(ChatActivity, { Toggle: ChatActivityToggle }),\n Composer: ChatComposer,\n ContextUsage: ChatContextUsage,\n ContextPopup: ChatContextPopup,\n ContextPanel: ChatContextPanel,\n Decision: ChatDecision,\n Outcome: ChatOutcome,\n Preview: ChatPreview,\n Mark: ChatMark,\n});\n\nexport { matchesChatCommand } from \"./command-search\";\nexport { reconcileChatMentions } from \"./composer-document\";\n\nexport { type ReactionPeopleInput, reactionPeople } from \"./reaction-people\";\n"],"mappings":"AAEA,SAAS,gBAAgB,EAAE,gBAAgB,QAAQ,oBAAoB;AACvE,SAAS,SAAS,QAAQ,aAAa;AAIvC,SAAS,YAAY,QAAQ,gBAAgB;AAC7C,SAAS,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,QAAQ,gBAAgB;AACjF,SAAS,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,WAAW,QAAQ,kBAAkB;AAClG,SAAS,QAAQ,QAAQ,YAAY;AACrC,SAAS,YAAY,QAAQ,gBAAgB;AA6B7C,SAAS,gBAAgB,QAAQ,kBAAkB;AA4BnD;AACA;AACA;AACA;AACA,OAAO,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE;EAC1C,KAAK,EAAE,SAAS;EAChB,QAAQ,EAAE,YAAY;EACtB,OAAO,EAAE,WAAW;EACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE;IAAE,MAAM,EAAE;EAAmB,CAAC,CAAC;EACrE,QAAQ,EAAE,YAAY;EACtB,YAAY,EAAE,gBAAgB;EAC9B,YAAY,EAAE,gBAAgB;EAC9B,YAAY,EAAE,gBAAgB;EAC9B,QAAQ,EAAE,YAAY;EACtB,OAAO,EAAE,WAAW;EACpB,OAAO,EAAE,WAAW;EACpB,IAAI,EAAE;AACR,CAAC,CAAC;AAEF,SAAS,kBAAkB,QAAQ,kBAAkB;AACrD,SAAS,qBAAqB,QAAQ,qBAAqB;AAE3D,SAAmC,cAAc,QAAQ,mBAAmB","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["chat/types.ts"],"sourcesContent":["import type { EmojiSkinTone } from \"../inputs/emoji/emoji-index\";\n\nexport type ChatRole = \"user\" | \"assistant\" | \"system\" | \"tool\";\n\nexport type ChatMessageStatus = \"pending\" | \"streaming\" | \"complete\" | \"error\";\n\nexport type ChatActivityTone = \"neutral\" | \"ai\" | \"success\" | \"danger\";\n\ntype ChatActionBase = {\n id: string;\n label: string;\n icon?: string;\n variant?: \"danger\";\n disabled?: boolean;\n /** Toggle state for persistent message actions such as feedback. */\n pressed?: boolean;\n /** Semantic foreground for selected feedback actions, without a persistent background. */\n pressedTone?: \"success\" | \"danger\";\n};\n\n/** Exactly one executable behavior for every chat action. */\nexport type ChatAction = ChatActionBase &\n ({ onSelect: () => void | Promise<void>; copyText?: never } | { copyText: string; onSelect?: never });\n\nexport type ChatAttachment = {\n id: string;\n name: string;\n size?: number;\n kind?: \"file\" | \"image\" | \"resource\";\n icon?: string;\n previewUrl?: string;\n alt?: string;\n /** Optional destination represented by this attachment. */\n href?: string;\n /** Opaque application-owned payload returned unchanged with ChatSubmitInput. */\n data?: unknown;\n /** Optional application-owned action presented below the attachment label. */\n action?: ChatAction;\n};\n\nexport type ChatUsage = {\n input?: number;\n output?: number;\n total?: number;\n};\n\nexport type ChatContextUsageData = {\n usage?: ChatUsage | null;\n loopUsage?: ChatUsage | null;\n contextWindow?: number;\n modelLabel?: string;\n};\n\nexport type ChatModelOption = {\n id: string;\n label: string;\n description?: string;\n image?: string;\n icon?: string;\n capabilities?: readonly string[];\n};\n\nexport type ChatComposerState = \"idle\" | \"submitting\" | \"running\" | \"stopping\";\n\nexport type ChatSubmitIntent = \"send\" | \"steer\" | \"queue\";\n\nexport type ChatSubmitInput = {\n intent: ChatSubmitIntent;\n text: string;\n attachments: readonly ChatAttachment[];\n mentions?: readonly ChatMention[];\n};\n\n/** Ranges use UTF-16 offsets into the untrimmed composer text. Payloads stay application-owned. */\nexport type ChatMention = { start: number; end: number; attachment: ChatAttachment };\n\n/**\n * Live dictation as the caller runs it: `listening` while speech arrives, `refining` after the stop until the refined\n * text replaced it, `refined` afterwards, `unrefined` when the raw text stays, and `interrupted` when the connection\n * ended early and the text so far stays.\n */\nexport type ChatDictationState = \"listening\" | \"refining\" | \"refined\" | \"unrefined\" | \"interrupted\";\n\n/** The composer's microphone. Dictation comes first; a voice message is the deliberate second action. */\nexport type ChatComposerMicrophone = {\n /** A tap starts or stops live dictation. Without it, a tap opens the microphone menu. */\n onDictate?: () => void;\n /** Holding the microphone, or \"Record voice message\" in its menu. Omit it where recording is not available. */\n onVoiceMessage?: () => void;\n /** The dictation state, shown on the microphone and in the hint line. */\n dictation?: ChatDictationState | null;\n /** Offered as \"Restore original\" while `dictation` is `refined`. */\n onRestoreOriginal?: () => void;\n disabled?: boolean;\n};\n\n/**\n * The composer's emoji button and `:shortcode` completion. Typing a colon and two letters suggests emoji by their\n * English or German name or GitHub shortcode; a complete `:thumbsup:` becomes 👍 when its closing colon is typed.\n */\nexport type ChatComposerEmoji = {\n /** Opens the emoji choice next to `anchor`, usually `EmojiPicker.Popover`; `insert` puts the chosen text at the caret. */\n onOpen: (context: { anchor: HTMLElement; insert: (text: string) => void }) => void;\n /** The skin tone of completed emoji that have one, as in the picker. */\n skinTone?: EmojiSkinTone;\n /** Called with each emoji the completion inserted, for example to remember it with `rememberEmoji`. */\n onPick?: (emoji: string) => void;\n};\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["chat/types.ts"],"sourcesContent":["import type { JSX } from \"solid-js\";\nimport type { EmojiSkinTone } from \"../inputs/emoji/emoji-index\";\n\nexport type ChatRole = \"user\" | \"assistant\" | \"system\" | \"tool\";\n\nexport type ChatMessageStatus = \"pending\" | \"streaming\" | \"complete\" | \"error\";\n\n/** `warning` marks a partial result or an outcome that is not yet known. */\nexport type ChatActivityTone = \"neutral\" | \"ai\" | \"success\" | \"warning\" | \"danger\";\n\n/** `open` asks; `sending` while the answer is on its way; `decided` once answered; `expired` when it ran out. */\nexport type ChatDecisionState = \"open\" | \"sending\" | \"decided\" | \"expired\";\n\n/** One answer of a question. Set the question's state in `onSelect` before awaiting anything, so it collapses at once. */\nexport type ChatDecisionAnswer = {\n label: string;\n /** Icon class, for example `ti ti-send`. */\n icon?: string;\n onSelect: () => void | Promise<void>;\n};\n\n/** Why a question is asked, or why its main answer is off. */\nexport type ChatDecisionReason = {\n text: JSX.Element;\n /** Icon class; the text after it starts 1.5rem from the edge. */\n icon?: string;\n /** `danger` for deletions, `warning` for outside content and limits. */\n tone?: \"neutral\" | \"danger\" | \"warning\";\n};\n\nexport type ChatOutcomeTone = \"running\" | \"done\" | \"off\" | \"waiting\" | \"warning\" | \"error\";\n\n/** One text of an outcome flow. */\nexport type ChatOutcomeLine = {\n tone: ChatOutcomeTone;\n /** What happened, as one sentence, usually with `ReferenceChip`s. */\n text: JSX.Element;\n /** A quiet second sentence, such as \"You declined.\" */\n detail?: JSX.Element;\n /** A formatted time after the text. */\n time?: string;\n /** Replaces the tone's icon, for example `ti ti-clock-x` for an expired question. */\n icon?: string;\n /** One text link after the line, such as \"Ask again\". */\n action?: { label: string; onSelect: () => void | Promise<void> };\n /** Small buttons under the line. Shown while this line is current; otherwise hidden but still reserving their row. */\n actions?: JSX.Element;\n};\n\n/** A person in a preview header: the name in the text colour, then the address the message really uses. */\nexport type ChatPreviewPerson = { name?: string; address?: string };\n\n/** One header row, such as \"To Lea Berg lea.berg@example.com\". */\nexport type ChatPreviewHeaderRow = {\n label: string;\n people?: readonly ChatPreviewPerson[];\n /** Further content after the people, such as \"and 2 more\". */\n value?: JSX.Element;\n /** Draws the label stronger, for recipients others cannot see. */\n emphasis?: boolean;\n};\n\ntype ChatActionBase = {\n id: string;\n label: string;\n icon?: string;\n variant?: \"danger\";\n disabled?: boolean;\n /** Toggle state for persistent message actions such as feedback. */\n pressed?: boolean;\n /** Semantic foreground for selected feedback actions, without a persistent background. */\n pressedTone?: \"success\" | \"danger\";\n};\n\n/** Exactly one executable behavior for every chat action. */\nexport type ChatAction = ChatActionBase &\n ({ onSelect: () => void | Promise<void>; copyText?: never } | { copyText: string; onSelect?: never });\n\nexport type ChatAttachment = {\n id: string;\n name: string;\n size?: number;\n kind?: \"file\" | \"image\" | \"resource\";\n icon?: string;\n previewUrl?: string;\n alt?: string;\n /** Optional destination represented by this attachment. */\n href?: string;\n /** Opaque application-owned payload returned unchanged with ChatSubmitInput. */\n data?: unknown;\n /** Optional application-owned action presented below the attachment label. */\n action?: ChatAction;\n};\n\nexport type ChatUsage = {\n input?: number;\n output?: number;\n total?: number;\n};\n\nexport type ChatContextUsageData = {\n usage?: ChatUsage | null;\n loopUsage?: ChatUsage | null;\n contextWindow?: number;\n modelLabel?: string;\n};\n\nexport type ChatModelOption = {\n id: string;\n label: string;\n description?: string;\n image?: string;\n icon?: string;\n capabilities?: readonly string[];\n};\n\nexport type ChatComposerState = \"idle\" | \"submitting\" | \"running\" | \"stopping\";\n\nexport type ChatSubmitIntent = \"send\" | \"steer\" | \"queue\";\n\nexport type ChatSubmitInput = {\n intent: ChatSubmitIntent;\n text: string;\n attachments: readonly ChatAttachment[];\n mentions?: readonly ChatMention[];\n};\n\n/** Ranges use UTF-16 offsets into the untrimmed composer text. Payloads stay application-owned. */\nexport type ChatMention = { start: number; end: number; attachment: ChatAttachment };\n\n/**\n * Live dictation as the caller runs it: `listening` while speech arrives, `refining` after the stop until the refined\n * text replaced it, `refined` afterwards, `unrefined` when the raw text stays, and `interrupted` when the connection\n * ended early and the text so far stays.\n */\nexport type ChatDictationState = \"listening\" | \"refining\" | \"refined\" | \"unrefined\" | \"interrupted\";\n\n/** The composer's microphone. Dictation comes first; a voice message is the deliberate second action. */\nexport type ChatComposerMicrophone = {\n /** A tap starts or stops live dictation. Without it, a tap opens the microphone menu. */\n onDictate?: () => void;\n /** Holding the microphone, or \"Record voice message\" in its menu. Omit it where recording is not available. */\n onVoiceMessage?: () => void;\n /** The dictation state, shown on the microphone and in the hint line. */\n dictation?: ChatDictationState | null;\n /** Offered as \"Restore original\" while `dictation` is `refined`. */\n onRestoreOriginal?: () => void;\n disabled?: boolean;\n};\n\n/**\n * The composer's emoji button and `:shortcode` completion. Typing a colon and two letters suggests emoji by their\n * English or German name or GitHub shortcode; a complete `:thumbsup:` becomes 👍 when its closing colon is typed.\n */\nexport type ChatComposerEmoji = {\n /** Opens the emoji choice next to `anchor`, usually `EmojiPicker.Popover`; `insert` puts the chosen text at the caret. */\n onOpen: (context: { anchor: HTMLElement; insert: (text: string) => void }) => void;\n /** The skin tone of completed emoji that have one, as in the picker. */\n skinTone?: EmojiSkinTone;\n /** Called with each emoji the completion inserted, for example to remember it with `rememberEmoji`. */\n onPick?: (emoji: string) => void;\n};\n"],"mappings":"","ignoreList":[]}
@@ -85,6 +85,7 @@ import { GestureMenu } from "../actions/GestureMenu";
85
85
  import SegmentedControl from "../actions/SegmentedControl";
86
86
  import { useDateConfigLocale } from "../intl/locale";
87
87
  import { useUiMessages } from "../intl/messages";
88
+ import { isWeekendColumn, isWeekendKey } from "../intl/weekend";
88
89
  import { prefersReducedMotion } from "../motion";
89
90
  import { CalendarDayView } from "./CalendarDayView";
90
91
  import { CalendarWeekView } from "./CalendarWeekView";
@@ -94,7 +95,7 @@ import { layoutCalendarIntervals } from "./calendar-event-layout";
94
95
  import { useCalendarMessages } from "./calendar-messages";
95
96
  import { fitMonthWeek, layoutMonthWeek, monthLaneCapacity } from "./calendar-month-layout";
96
97
  import { MONTH_ROW_BLOCK, MONTH_ROWS_IN_VIEW, monthFocusRow, monthOfWeek, monthRenderWindow, monthRevealTop, monthRowOf, monthTodayDirection, monthVisibleRows, monthWeekKeys } from "./calendar-month-scroll";
97
- import { calendarDayIndexAtPoint, calendarMinuteAtPoint, startCalendarPointerSession } from "./calendar-pointer";
98
+ import { afterPointerRelease, calendarDayIndexAtPoint, calendarMinuteAtPoint, startCalendarPointerSession } from "./calendar-pointer";
98
99
  import { EventChip, eventHref, followCalendarHref, formatTime, ownerDateConfig, parseDate, placeCalendarPopover, textWidth, validDate } from "./calendar-shared";
99
100
  import { compactGermanDate } from "./calendar-time-view";
100
101
 
@@ -905,9 +906,10 @@ const MonthPickerView = props => {
905
906
  get each() {
906
907
  return weekdays();
907
908
  },
908
- children: day => (() => {
909
+ children: (day, index) => (() => {
909
910
  var _el$44 = _$getNextElement(_tmpl$11);
910
911
  _$insert(_el$44, day);
912
+ _$effect(() => _$setAttribute(_el$44, "data-weekend", isWeekendColumn(index(), dateConfig().firstDayOfWeek ?? 1, dateConfig().locale) ? "true" : undefined));
911
913
  return _el$44;
912
914
  })()
913
915
  }), _el$41, _co$1);
@@ -1138,12 +1140,12 @@ const MonthPickerView = props => {
1138
1140
  children: event => (() => {
1139
1141
  var _el$76 = _$getNextElement(_tmpl$20);
1140
1142
  _$effect(_p$ => {
1141
- var _v$5 = event.colorHex ? undefined : event.color ?? "blue",
1142
- _v$6 = event.colorHex ? {
1143
+ var _v$7 = event.colorHex ? undefined : event.color ?? "blue",
1144
+ _v$8 = event.colorHex ? {
1143
1145
  "background-color": event.colorHex
1144
1146
  } : undefined;
1145
- _v$5 !== _p$.e && _$setAttribute(_el$76, "data-color", _p$.e = _v$5);
1146
- _p$.t = _$style(_el$76, _v$6, _p$.t);
1147
+ _v$7 !== _p$.e && _$setAttribute(_el$76, "data-color", _p$.e = _v$7);
1148
+ _p$.t = _$style(_el$76, _v$8, _p$.t);
1147
1149
  return _p$;
1148
1150
  }, {
1149
1151
  e: undefined,
@@ -1152,7 +1154,16 @@ const MonthPickerView = props => {
1152
1154
  return _el$76;
1153
1155
  })()
1154
1156
  }));
1155
- _$effect(() => _$setAttribute(_el$51, "data-drop-preview", movePreview()?.start && calendar.formatDateKey(movePreview().start, dateConfig()) === dayKey ? "true" : undefined));
1157
+ _$effect(_p$ => {
1158
+ var _v$5 = isWeekendKey(dayKey, dateConfig().locale) ? "true" : undefined,
1159
+ _v$6 = movePreview()?.start && calendar.formatDateKey(movePreview().start, dateConfig()) === dayKey ? "true" : undefined;
1160
+ _v$5 !== _p$.e && _$setAttribute(_el$51, "data-weekend", _p$.e = _v$5);
1161
+ _v$6 !== _p$.t && _$setAttribute(_el$51, "data-drop-preview", _p$.t = _v$6);
1162
+ return _p$;
1163
+ }, {
1164
+ e: undefined,
1165
+ t: undefined
1166
+ });
1156
1167
  return _el$51;
1157
1168
  })();
1158
1169
  }
@@ -1253,6 +1264,7 @@ const MonthView = props => {
1253
1264
  equals: (previous, next) => previous.map(week => week[0]?.key).join() === next.map(week => week[0]?.key).join()
1254
1265
  });
1255
1266
  const weekdays = createMemo(() => calendar.weekdays(dateConfig()));
1267
+ const weekendColumn = index => isWeekendColumn(index, dateConfig().firstDayOfWeek ?? 1, dateConfig().locale);
1256
1268
  const todayKey = createMemo(() => calendar.formatDateKey(props.now, dateConfig()));
1257
1269
  const items = createMemo(() => monthItems(props.events));
1258
1270
  const [capacities, setCapacities] = createSignal([]);
@@ -2117,9 +2129,9 @@ const MonthView = props => {
2117
2129
  select(key, current);
2118
2130
  focusCell(current);
2119
2131
  const range = orderedSelection(key, current);
2120
- openCreate(range, {
2132
+ afterPointerRelease(() => openCreate(range, {
2121
2133
  active: range.first !== range.last
2122
- });
2134
+ }));
2123
2135
  },
2124
2136
  onCancel: () => select(key)
2125
2137
  });
@@ -2336,14 +2348,14 @@ const MonthView = props => {
2336
2348
  _el$83.$$click = () => openView(week()[0].key, "week");
2337
2349
  _$insert(_el$83, weekNumber);
2338
2350
  _$effect(_p$ => {
2339
- var _v$1 = calendarMessages().calendarOpenWeekNumber({
2351
+ var _v$11 = calendarMessages().calendarOpenWeekNumber({
2340
2352
  week: weekNumber()
2341
2353
  }),
2342
- _v$10 = calendarMessages().calendarOpenWeekNumber({
2354
+ _v$12 = calendarMessages().calendarOpenWeekNumber({
2343
2355
  week: weekNumber()
2344
2356
  });
2345
- _v$1 !== _p$.e && _$setAttribute(_el$83, "title", _p$.e = _v$1);
2346
- _v$10 !== _p$.t && _$setAttribute(_el$83, "aria-label", _p$.t = _v$10);
2357
+ _v$11 !== _p$.e && _$setAttribute(_el$83, "title", _p$.e = _v$11);
2358
+ _v$12 !== _p$.t && _$setAttribute(_el$83, "aria-label", _p$.t = _v$12);
2347
2359
  return _p$;
2348
2360
  }, {
2349
2361
  e: undefined,
@@ -2582,18 +2594,18 @@ const MonthView = props => {
2582
2594
  }));
2583
2595
  _$insert(_el$92, () => cell().hidden, _el$95, _co$24);
2584
2596
  _$effect(_p$ => {
2585
- var _v$11 = String(cell().top + cell().shown.length),
2586
- _v$12 = calendarMessages().calendarMoreEventsOn({
2597
+ var _v$13 = String(cell().top + cell().shown.length),
2598
+ _v$14 = calendarMessages().calendarMoreEventsOn({
2587
2599
  count: cell().hidden,
2588
2600
  label
2589
2601
  }),
2590
- _v$13 = (() => {
2602
+ _v$15 = (() => {
2591
2603
  const current = popover();
2592
2604
  return current?.kind === "day" && current.dayKey === key;
2593
2605
  })();
2594
- _v$11 !== _p$.e && _$setStyleProperty(_el$90, "--k2b-calendar-row", _p$.e = _v$11);
2595
- _v$12 !== _p$.t && _$setAttribute(_el$90, "aria-label", _p$.t = _v$12);
2596
- _v$13 !== _p$.a && _$setAttribute(_el$90, "aria-expanded", _p$.a = _v$13);
2606
+ _v$13 !== _p$.e && _$setStyleProperty(_el$90, "--k2b-calendar-row", _p$.e = _v$13);
2607
+ _v$14 !== _p$.t && _$setAttribute(_el$90, "aria-label", _p$.t = _v$14);
2608
+ _v$15 !== _p$.a && _$setAttribute(_el$90, "aria-expanded", _p$.a = _v$15);
2597
2609
  return _p$;
2598
2610
  }, {
2599
2611
  e: undefined,
@@ -2605,32 +2617,32 @@ const MonthView = props => {
2605
2617
  }
2606
2618
  }), _el$101, _co$27);
2607
2619
  _$effect(_p$ => {
2608
- var _v$14 = rovingKey() === key ? 0 : -1,
2609
- _v$15 = within(selection(), key) ? "true" : "false",
2610
- _v$16 = key === todayKey() ? "date" : undefined,
2611
- _v$17 = !sameMonth() ? "true" : undefined,
2612
- _v$18 = continuous() && key.endsWith("-01") ? "true" : undefined,
2613
- _v$19 = continuous() && Number(key.slice(8)) <= 7 ? "true" : undefined,
2614
- _v$20 = column() > 4 ? "true" : undefined,
2615
- _v$21 = key < todayKey() ? "true" : undefined,
2616
- _v$22 = selectionPart(key),
2617
- _v$23 = within(dropRange(), key) ? "true" : undefined,
2618
- _v$24 = continuous() && pulseKey() === key ? "true" : undefined,
2619
- _v$25 = key === todayKey() ? "true" : undefined,
2620
- _v$26 = !sameMonth() ? "true" : undefined;
2621
- _v$14 !== _p$.e && _$setAttribute(_el$84, "tabindex", _p$.e = _v$14);
2622
- _v$15 !== _p$.t && _$setAttribute(_el$84, "aria-selected", _p$.t = _v$15);
2623
- _v$16 !== _p$.a && _$setAttribute(_el$84, "aria-current", _p$.a = _v$16);
2624
- _v$17 !== _p$.o && _$setAttribute(_el$84, "data-outside", _p$.o = _v$17);
2625
- _v$18 !== _p$.i && _$setAttribute(_el$84, "data-month-first", _p$.i = _v$18);
2626
- _v$19 !== _p$.n && _$setAttribute(_el$84, "data-month-top", _p$.n = _v$19);
2627
- _v$20 !== _p$.s && _$setAttribute(_el$84, "data-weekend", _p$.s = _v$20);
2628
- _v$21 !== _p$.h && _$setAttribute(_el$84, "data-past", _p$.h = _v$21);
2629
- _v$22 !== _p$.r && _$setAttribute(_el$84, "data-selected", _p$.r = _v$22);
2630
- _v$23 !== _p$.d && _$setAttribute(_el$84, "data-drop-preview", _p$.d = _v$23);
2631
- _v$24 !== _p$.l && _$setAttribute(_el$86, "data-pulse", _p$.l = _v$24);
2632
- _v$25 !== _p$.u && _$setAttribute(_el$86, "data-today", _p$.u = _v$25);
2633
- _v$26 !== _p$.c && _$setAttribute(_el$86, "data-outside", _p$.c = _v$26);
2620
+ var _v$16 = rovingKey() === key ? 0 : -1,
2621
+ _v$17 = within(selection(), key) ? "true" : "false",
2622
+ _v$18 = key === todayKey() ? "date" : undefined,
2623
+ _v$19 = !sameMonth() ? "true" : undefined,
2624
+ _v$20 = continuous() && key.endsWith("-01") ? "true" : undefined,
2625
+ _v$21 = continuous() && Number(key.slice(8)) <= 7 ? "true" : undefined,
2626
+ _v$22 = isWeekendKey(key, dateConfig().locale) ? "true" : undefined,
2627
+ _v$23 = key < todayKey() ? "true" : undefined,
2628
+ _v$24 = selectionPart(key),
2629
+ _v$25 = within(dropRange(), key) ? "true" : undefined,
2630
+ _v$26 = continuous() && pulseKey() === key ? "true" : undefined,
2631
+ _v$27 = key === todayKey() ? "true" : undefined,
2632
+ _v$28 = !sameMonth() ? "true" : undefined;
2633
+ _v$16 !== _p$.e && _$setAttribute(_el$84, "tabindex", _p$.e = _v$16);
2634
+ _v$17 !== _p$.t && _$setAttribute(_el$84, "aria-selected", _p$.t = _v$17);
2635
+ _v$18 !== _p$.a && _$setAttribute(_el$84, "aria-current", _p$.a = _v$18);
2636
+ _v$19 !== _p$.o && _$setAttribute(_el$84, "data-outside", _p$.o = _v$19);
2637
+ _v$20 !== _p$.i && _$setAttribute(_el$84, "data-month-first", _p$.i = _v$20);
2638
+ _v$21 !== _p$.n && _$setAttribute(_el$84, "data-month-top", _p$.n = _v$21);
2639
+ _v$22 !== _p$.s && _$setAttribute(_el$84, "data-weekend", _p$.s = _v$22);
2640
+ _v$23 !== _p$.h && _$setAttribute(_el$84, "data-past", _p$.h = _v$23);
2641
+ _v$24 !== _p$.r && _$setAttribute(_el$84, "data-selected", _p$.r = _v$24);
2642
+ _v$25 !== _p$.d && _$setAttribute(_el$84, "data-drop-preview", _p$.d = _v$25);
2643
+ _v$26 !== _p$.l && _$setAttribute(_el$86, "data-pulse", _p$.l = _v$26);
2644
+ _v$27 !== _p$.u && _$setAttribute(_el$86, "data-today", _p$.u = _v$27);
2645
+ _v$28 !== _p$.c && _$setAttribute(_el$86, "data-outside", _p$.c = _v$28);
2634
2646
  return _p$;
2635
2647
  }, {
2636
2648
  e: undefined,
@@ -2653,16 +2665,16 @@ const MonthView = props => {
2653
2665
  }
2654
2666
  }), _el$82, _co$22);
2655
2667
  _$effect(_p$ => {
2656
- var _v$7 = continuous() ? week()[0]?.key : undefined,
2657
- _v$8 = continuous() ? weekIndex() + 2 : undefined,
2658
- _v$9 = continuous() ? {
2668
+ var _v$9 = continuous() ? week()[0]?.key : undefined,
2669
+ _v$0 = continuous() ? weekIndex() + 2 : undefined,
2670
+ _v$1 = continuous() ? {
2659
2671
  "--k2b-calendar-week-index": String(weekIndex())
2660
2672
  } : undefined,
2661
- _v$0 = props.owner.withWeekNumbers ? "true" : undefined;
2662
- _v$7 !== _p$.e && _$setAttribute(_el$77, "data-week-key", _p$.e = _v$7);
2663
- _v$8 !== _p$.t && _$setAttribute(_el$77, "aria-rowindex", _p$.t = _v$8);
2664
- _p$.a = _$style(_el$77, _v$9, _p$.a);
2665
- _v$0 !== _p$.o && _$setAttribute(_el$77, "data-week-numbers", _p$.o = _v$0);
2673
+ _v$10 = props.owner.withWeekNumbers ? "true" : undefined;
2674
+ _v$9 !== _p$.e && _$setAttribute(_el$77, "data-week-key", _p$.e = _v$9);
2675
+ _v$0 !== _p$.t && _$setAttribute(_el$77, "aria-rowindex", _p$.t = _v$0);
2676
+ _p$.a = _$style(_el$77, _v$1, _p$.a);
2677
+ _v$10 !== _p$.o && _$setAttribute(_el$77, "data-week-numbers", _p$.o = _v$10);
2666
2678
  return _p$;
2667
2679
  }, {
2668
2680
  e: undefined,
@@ -2698,7 +2710,7 @@ const MonthView = props => {
2698
2710
  children: (day, index) => (() => {
2699
2711
  var _el$116 = _$getNextElement(_tmpl$28);
2700
2712
  _$insert(_el$116, day);
2701
- _$effect(() => _$setAttribute(_el$116, "data-weekend", index() > 4 ? "true" : undefined));
2713
+ _$effect(() => _$setAttribute(_el$116, "data-weekend", weekendColumn(index()) ? "true" : undefined));
2702
2714
  return _el$116;
2703
2715
  })()
2704
2716
  }), _el$115, _co$31);
@@ -2719,10 +2731,10 @@ const MonthView = props => {
2719
2731
  children: (week, index) => weekRow(() => week, index)
2720
2732
  }), _el$121, _co$33);
2721
2733
  _$effect(_p$ => {
2722
- var _v$27 = formatMonth(props.date, dateConfig()),
2723
- _v$28 = `auto repeat(${weeks().length}, minmax(5rem, 1fr))`;
2724
- _v$27 !== _p$.e && _$setAttribute(_el$117, "aria-label", _p$.e = _v$27);
2725
- _v$28 !== _p$.t && _$setStyleProperty(_el$117, "grid-template-rows", _p$.t = _v$28);
2734
+ var _v$29 = formatMonth(props.date, dateConfig()),
2735
+ _v$30 = `auto repeat(${weeks().length}, minmax(5rem, 1fr))`;
2736
+ _v$29 !== _p$.e && _$setAttribute(_el$117, "aria-label", _p$.e = _v$29);
2737
+ _v$30 !== _p$.t && _$setStyleProperty(_el$117, "grid-template-rows", _p$.t = _v$30);
2726
2738
  return _p$;
2727
2739
  }, {
2728
2740
  e: undefined,
@@ -2769,14 +2781,14 @@ const MonthView = props => {
2769
2781
  }));
2770
2782
  _$insert(_el$127, () => formatMonth(parseKey(focusMonthKey()), dateConfig()));
2771
2783
  _$effect(_p$ => {
2772
- var _v$29 = formatMonth(parseKey(focusMonthKey()), dateConfig()),
2773
- _v$30 = trackWeeks().length + 1,
2774
- _v$31 = String(trackWeeks().length),
2775
- _v$32 = labelShown() ? "true" : "false";
2776
- _v$29 !== _p$.e && _$setAttribute(_el$123, "aria-label", _p$.e = _v$29);
2777
- _v$30 !== _p$.t && _$setAttribute(_el$123, "aria-rowcount", _p$.t = _v$30);
2778
- _v$31 !== _p$.a && _$setStyleProperty(_el$124, "--k2b-calendar-weeks", _p$.a = _v$31);
2779
- _v$32 !== _p$.o && _$setAttribute(_el$127, "data-show", _p$.o = _v$32);
2784
+ var _v$31 = formatMonth(parseKey(focusMonthKey()), dateConfig()),
2785
+ _v$32 = trackWeeks().length + 1,
2786
+ _v$33 = String(trackWeeks().length),
2787
+ _v$34 = labelShown() ? "true" : "false";
2788
+ _v$31 !== _p$.e && _$setAttribute(_el$123, "aria-label", _p$.e = _v$31);
2789
+ _v$32 !== _p$.t && _$setAttribute(_el$123, "aria-rowcount", _p$.t = _v$32);
2790
+ _v$33 !== _p$.a && _$setStyleProperty(_el$124, "--k2b-calendar-weeks", _p$.a = _v$33);
2791
+ _v$34 !== _p$.o && _$setAttribute(_el$127, "data-show", _p$.o = _v$34);
2780
2792
  return _p$;
2781
2793
  }, {
2782
2794
  e: undefined,
@@ -2961,16 +2973,16 @@ const MonthView = props => {
2961
2973
  }) : dayList(value.dayKey)
2962
2974
  }));
2963
2975
  _$effect(_p$ => {
2964
- var _v$33 = (() => {
2976
+ var _v$35 = (() => {
2965
2977
  const current = popover();
2966
2978
  if (current?.kind === "day") return dayLabel(parseKey(current.dayKey));
2967
2979
  return calendarMessages().calendarQuickCreate;
2968
2980
  })(),
2969
- _v$34 = popover()?.kind,
2970
- _v$35 = popover()?.kind === "create" && !createActive() ? "true" : undefined;
2971
- _v$33 !== _p$.e && _$setAttribute(_el$143, "aria-label", _p$.e = _v$33);
2972
- _v$34 !== _p$.t && _$setAttribute(_el$143, "data-kind", _p$.t = _v$34);
2973
- _v$35 !== _p$.a && _$setAttribute(_el$143, "data-quiet", _p$.a = _v$35);
2981
+ _v$36 = popover()?.kind,
2982
+ _v$37 = popover()?.kind === "create" && !createActive() ? "true" : undefined;
2983
+ _v$35 !== _p$.e && _$setAttribute(_el$143, "aria-label", _p$.e = _v$35);
2984
+ _v$36 !== _p$.t && _$setAttribute(_el$143, "data-kind", _p$.t = _v$36);
2985
+ _v$37 !== _p$.a && _$setAttribute(_el$143, "data-quiet", _p$.a = _v$37);
2974
2986
  return _p$;
2975
2987
  }, {
2976
2988
  e: undefined,
@@ -3245,8 +3257,11 @@ const TimeGridView = props => {
3245
3257
  get href() {
3246
3258
  return props.owner.getDateHref?.(day, "day") ?? "#";
3247
3259
  },
3248
- anchorProps: {
3249
- class: "k2b-calendar-time-grid__day"
3260
+ get anchorProps() {
3261
+ return {
3262
+ class: "k2b-calendar-time-grid__day",
3263
+ "data-weekend": isWeekendKey(calendar.formatDateKey(day, dateConfig()), dateConfig().locale) ? "true" : undefined
3264
+ };
3250
3265
  },
3251
3266
  get children() {
3252
3267
  return [(() => {
@@ -3310,6 +3325,9 @@ const TimeGridView = props => {
3310
3325
  [_el$172, _co$45] = _$getNextMarker(_el$171.nextSibling);
3311
3326
  _$setAttribute(_el$167, "data-calendar-day-key", dayKey);
3312
3327
  _$spread(_el$167, _$mergeProps({
3328
+ get ["data-weekend"]() {
3329
+ return isWeekendKey(dayKey, dateConfig().locale) ? "true" : undefined;
3330
+ },
3313
3331
  get ["data-drop-preview"]() {
3314
3332
  return timePreview()?.allDay && calendar.formatDateKey(timePreview().start, dateConfig()) === dayKey ? "true" : undefined;
3315
3333
  },
@@ -3359,10 +3377,10 @@ const TimeGridView = props => {
3359
3377
  }
3360
3378
  }), _el$152, _co$39);
3361
3379
  _$effect(_p$ => {
3362
- var _v$36 = columnTemplate(),
3363
- _v$37 = `${props.owner.allDayMaxHeightRem ?? 7}rem`;
3364
- _v$36 !== _p$.e && _$setStyleProperty(_el$149, "grid-template-columns", _p$.e = _v$36);
3365
- _v$37 !== _p$.t && _$setStyleProperty(_el$149, "max-height", _p$.t = _v$37);
3380
+ var _v$38 = columnTemplate(),
3381
+ _v$39 = `${props.owner.allDayMaxHeightRem ?? 7}rem`;
3382
+ _v$38 !== _p$.e && _$setStyleProperty(_el$149, "grid-template-columns", _p$.e = _v$38);
3383
+ _v$39 !== _p$.t && _$setStyleProperty(_el$149, "max-height", _p$.t = _v$39);
3366
3384
  return _p$;
3367
3385
  }, {
3368
3386
  e: undefined,
@@ -3483,10 +3501,10 @@ const TimeGridView = props => {
3483
3501
  _$insert(_el$194, () => formatTime(event.startDate, dateConfig()), _el$197, _co$52);
3484
3502
  _$insert(_el$194, () => formatTime(event.endDate, dateConfig()), _el$199, _co$53);
3485
3503
  _$effect(_p$ => {
3486
- var _v$42 = `${layout.top}%`,
3487
- _v$43 = `${layout.height}%`;
3488
- _v$42 !== _p$.e && _$setStyleProperty(_el$191, "top", _p$.e = _v$42);
3489
- _v$43 !== _p$.t && _$setStyleProperty(_el$191, "height", _p$.t = _v$43);
3504
+ var _v$46 = `${layout.top}%`,
3505
+ _v$47 = `${layout.height}%`;
3506
+ _v$46 !== _p$.e && _$setStyleProperty(_el$191, "top", _p$.e = _v$46);
3507
+ _v$47 !== _p$.t && _$setStyleProperty(_el$191, "height", _p$.t = _v$47);
3490
3508
  return _p$;
3491
3509
  }, {
3492
3510
  e: undefined,
@@ -3576,16 +3594,16 @@ const TimeGridView = props => {
3576
3594
  }
3577
3595
  }), _el$208, _co$56);
3578
3596
  _$effect(_p$ => {
3579
- var _v$44 = `${layout.top}%`,
3580
- _v$45 = `${layout.height}%`,
3581
- _v$46 = position.left,
3582
- _v$47 = position.width,
3583
- _v$48 = String(20 + layoutItem.lane);
3584
- _v$44 !== _p$.e && _$setStyleProperty(_el$202, "top", _p$.e = _v$44);
3585
- _v$45 !== _p$.t && _$setStyleProperty(_el$202, "height", _p$.t = _v$45);
3586
- _v$46 !== _p$.a && _$setStyleProperty(_el$202, "left", _p$.a = _v$46);
3587
- _v$47 !== _p$.o && _$setStyleProperty(_el$202, "width", _p$.o = _v$47);
3588
- _v$48 !== _p$.i && _$setStyleProperty(_el$202, "z-index", _p$.i = _v$48);
3597
+ var _v$48 = `${layout.top}%`,
3598
+ _v$49 = `${layout.height}%`,
3599
+ _v$50 = position.left,
3600
+ _v$51 = position.width,
3601
+ _v$52 = String(20 + layoutItem.lane);
3602
+ _v$48 !== _p$.e && _$setStyleProperty(_el$202, "top", _p$.e = _v$48);
3603
+ _v$49 !== _p$.t && _$setStyleProperty(_el$202, "height", _p$.t = _v$49);
3604
+ _v$50 !== _p$.a && _$setStyleProperty(_el$202, "left", _p$.a = _v$50);
3605
+ _v$51 !== _p$.o && _$setStyleProperty(_el$202, "width", _p$.o = _v$51);
3606
+ _v$52 !== _p$.i && _$setStyleProperty(_el$202, "z-index", _p$.i = _v$52);
3589
3607
  return _p$;
3590
3608
  }, {
3591
3609
  e: undefined,
@@ -3618,16 +3636,16 @@ const TimeGridView = props => {
3618
3636
  };
3619
3637
  _$insert(_el$210, () => overflow.hiddenEvents.length, _el$213, _co$57);
3620
3638
  _$effect(_p$ => {
3621
- var _v$49 = `${layout.top}%`,
3622
- _v$50 = `${layout.height}%`,
3623
- _v$51 = hiddenTitle(),
3624
- _v$52 = calendarMessages().hiddenOverlappingEvents({
3639
+ var _v$53 = `${layout.top}%`,
3640
+ _v$54 = `${layout.height}%`,
3641
+ _v$55 = hiddenTitle(),
3642
+ _v$56 = calendarMessages().hiddenOverlappingEvents({
3625
3643
  count: overflow.hiddenEvents.length
3626
3644
  });
3627
- _v$49 !== _p$.e && _$setStyleProperty(_el$209, "top", _p$.e = _v$49);
3628
- _v$50 !== _p$.t && _$setStyleProperty(_el$209, "height", _p$.t = _v$50);
3629
- _v$51 !== _p$.a && _$setAttribute(_el$209, "title", _p$.a = _v$51);
3630
- _v$52 !== _p$.o && _$setAttribute(_el$209, "aria-label", _p$.o = _v$52);
3645
+ _v$53 !== _p$.e && _$setStyleProperty(_el$209, "top", _p$.e = _v$53);
3646
+ _v$54 !== _p$.t && _$setStyleProperty(_el$209, "height", _p$.t = _v$54);
3647
+ _v$55 !== _p$.a && _$setAttribute(_el$209, "title", _p$.a = _v$55);
3648
+ _v$56 !== _p$.o && _$setAttribute(_el$209, "aria-label", _p$.o = _v$56);
3631
3649
  return _p$;
3632
3650
  }, {
3633
3651
  e: undefined,
@@ -3674,20 +3692,29 @@ const TimeGridView = props => {
3674
3692
  })];
3675
3693
  }
3676
3694
  }), _el$189, _co$51);
3677
- _$effect(_$p => _$setStyleProperty(_el$178, "grid-template-rows", `repeat(${hours().length}, minmax(4rem, 1fr))`));
3695
+ _$effect(_p$ => {
3696
+ var _v$44 = isWeekendKey(dayKey, dateConfig().locale) ? "true" : undefined,
3697
+ _v$45 = `repeat(${hours().length}, minmax(4rem, 1fr))`;
3698
+ _v$44 !== _p$.e && _$setAttribute(_el$178, "data-weekend", _p$.e = _v$44);
3699
+ _v$45 !== _p$.t && _$setStyleProperty(_el$178, "grid-template-rows", _p$.t = _v$45);
3700
+ return _p$;
3701
+ }, {
3702
+ e: undefined,
3703
+ t: undefined
3704
+ });
3678
3705
  return _el$178;
3679
3706
  })();
3680
3707
  }
3681
3708
  }), _el$157, _co$40);
3682
3709
  _$effect(_p$ => {
3683
- var _v$38 = isDayView() ? "day" : "week",
3684
- _v$39 = columnTemplate(),
3685
- _v$40 = columnTemplate(),
3686
- _v$41 = `repeat(${hours().length}, minmax(4rem, 1fr))`;
3687
- _v$38 !== _p$.e && _$setAttribute(_el$144, "data-view", _p$.e = _v$38);
3688
- _v$39 !== _p$.t && _$setStyleProperty(_el$145, "grid-template-columns", _p$.t = _v$39);
3689
- _v$40 !== _p$.a && _$setStyleProperty(_el$154, "grid-template-columns", _p$.a = _v$40);
3690
- _v$41 !== _p$.o && _$setStyleProperty(_el$155, "grid-template-rows", _p$.o = _v$41);
3710
+ var _v$40 = isDayView() ? "day" : "week",
3711
+ _v$41 = columnTemplate(),
3712
+ _v$42 = columnTemplate(),
3713
+ _v$43 = `repeat(${hours().length}, minmax(4rem, 1fr))`;
3714
+ _v$40 !== _p$.e && _$setAttribute(_el$144, "data-view", _p$.e = _v$40);
3715
+ _v$41 !== _p$.t && _$setStyleProperty(_el$145, "grid-template-columns", _p$.t = _v$41);
3716
+ _v$42 !== _p$.a && _$setStyleProperty(_el$154, "grid-template-columns", _p$.a = _v$42);
3717
+ _v$43 !== _p$.o && _$setStyleProperty(_el$155, "grid-template-rows", _p$.o = _v$43);
3691
3718
  return _p$;
3692
3719
  }, {
3693
3720
  e: undefined,
@@ -3772,14 +3799,14 @@ const YearView = props => {
3772
3799
  children: event => (() => {
3773
3800
  var _el$227 = _$getNextElement(_tmpl$56);
3774
3801
  _$effect(_p$ => {
3775
- var _v$53 = event().colorHex ? undefined : event().color ?? "blue",
3776
- _v$54 = day.isToday ? "true" : undefined,
3777
- _v$55 = event().colorHex ? {
3802
+ var _v$57 = event().colorHex ? undefined : event().color ?? "blue",
3803
+ _v$58 = day.isToday ? "true" : undefined,
3804
+ _v$59 = event().colorHex ? {
3778
3805
  "background-color": day.isToday ? "white" : event().colorHex
3779
3806
  } : undefined;
3780
- _v$53 !== _p$.e && _$setAttribute(_el$227, "data-color", _p$.e = _v$53);
3781
- _v$54 !== _p$.t && _$setAttribute(_el$227, "data-today", _p$.t = _v$54);
3782
- _p$.a = _$style(_el$227, _v$55, _p$.a);
3807
+ _v$57 !== _p$.e && _$setAttribute(_el$227, "data-color", _p$.e = _v$57);
3808
+ _v$58 !== _p$.t && _$setAttribute(_el$227, "data-today", _p$.t = _v$58);
3809
+ _p$.a = _$style(_el$227, _v$59, _p$.a);
3783
3810
  return _p$;
3784
3811
  }, {
3785
3812
  e: undefined,
@@ -4265,10 +4292,10 @@ const CalendarRoot = props => {
4265
4292
  }
4266
4293
  }), _el$242, _co$64);
4267
4294
  _$effect(_p$ => {
4268
- var _v$56 = `k2b-content-calendar ${props.class ?? ""}`,
4269
- _v$57 = props.navigationPending ? "true" : undefined;
4270
- _v$56 !== _p$.e && _$className(_el$238, _p$.e = _v$56);
4271
- _v$57 !== _p$.t && _$setAttribute(_el$238, "aria-busy", _p$.t = _v$57);
4295
+ var _v$60 = `k2b-content-calendar ${props.class ?? ""}`,
4296
+ _v$61 = props.navigationPending ? "true" : undefined;
4297
+ _v$60 !== _p$.e && _$className(_el$238, _p$.e = _v$60);
4298
+ _v$61 !== _p$.t && _$setAttribute(_el$238, "aria-busy", _p$.t = _v$61);
4272
4299
  return _p$;
4273
4300
  }, {
4274
4301
  e: undefined,