@k2b/ui 0.27.0 → 0.29.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 (323) hide show
  1. package/README.md +1 -1
  2. package/dist/base.css +147 -2
  3. package/dist/browser/actions/ContextMenu.js +35 -4
  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 +184 -158
  8. package/dist/browser/actions/Dropdown.js.map +1 -1
  9. package/dist/browser/actions/GestureMenu.js +95 -139
  10. package/dist/browser/actions/GestureMenu.js.map +1 -1
  11. package/dist/browser/actions/Toolbar.js +379 -48
  12. package/dist/browser/actions/Toolbar.js.map +1 -1
  13. package/dist/browser/actions/drag-and-drop-messages.js +75 -0
  14. package/dist/browser/actions/drag-and-drop-messages.js.map +1 -0
  15. package/dist/browser/actions/drag-and-drop.js +692 -0
  16. package/dist/browser/actions/drag-and-drop.js.map +1 -0
  17. package/dist/browser/actions/index.js +1 -0
  18. package/dist/browser/actions/index.js.map +1 -1
  19. package/dist/browser/actions/menu-rows.js +15 -0
  20. package/dist/browser/actions/menu-rows.js.map +1 -0
  21. package/dist/browser/actions/menu-sheet.js +154 -0
  22. package/dist/browser/actions/menu-sheet.js.map +1 -0
  23. package/dist/browser/actions/toolbar-messages.js +20 -0
  24. package/dist/browser/actions/toolbar-messages.js.map +1 -0
  25. package/dist/browser/chart-inspection.js +3 -0
  26. package/dist/browser/chart-inspection.js.map +1 -0
  27. package/dist/browser/chat/ChatComposer.js +714 -410
  28. package/dist/browser/chat/ChatComposer.js.map +1 -1
  29. package/dist/browser/chat/ChatDecision.js +778 -0
  30. package/dist/browser/chat/ChatDecision.js.map +1 -0
  31. package/dist/browser/chat/ChatPrimitives.js +34 -28
  32. package/dist/browser/chat/ChatPrimitives.js.map +1 -1
  33. package/dist/browser/chat/ChatTimeline.js.map +1 -1
  34. package/dist/browser/chat/chat-messages.js +25 -1
  35. package/dist/browser/chat/chat-messages.js.map +1 -1
  36. package/dist/browser/chat/command-search.js +13 -3
  37. package/dist/browser/chat/command-search.js.map +1 -1
  38. package/dist/browser/chat/index.js +8 -1
  39. package/dist/browser/chat/index.js.map +1 -1
  40. package/dist/browser/chat/reaction-people.js +15 -0
  41. package/dist/browser/chat/reaction-people.js.map +1 -0
  42. package/dist/browser/chat/types.js.map +1 -1
  43. package/dist/browser/content/Calendar.js +3 -3
  44. package/dist/browser/content/Calendar.js.map +1 -1
  45. package/dist/browser/content/Chart.js +60 -86
  46. package/dist/browser/content/Chart.js.map +1 -1
  47. package/dist/browser/content/ChartSnapshotView.js +7 -10
  48. package/dist/browser/content/ChartSnapshotView.js.map +1 -1
  49. package/dist/browser/content/FileBrowser.js +2 -2
  50. package/dist/browser/content/FileBrowser.js.map +1 -1
  51. package/dist/browser/content/FileTree.js +42 -36
  52. package/dist/browser/content/FileTree.js.map +1 -1
  53. package/dist/browser/content/FileTypeIcon.js +72 -0
  54. package/dist/browser/content/FileTypeIcon.js.map +1 -0
  55. package/dist/browser/content/FileView.js +2 -2
  56. package/dist/browser/content/FileView.js.map +1 -1
  57. package/dist/browser/content/MessageRow.js +330 -448
  58. package/dist/browser/content/MessageRow.js.map +1 -1
  59. package/dist/browser/content/ReactionBar.js +419 -0
  60. package/dist/browser/content/ReactionBar.js.map +1 -0
  61. package/dist/browser/content/ReferenceChip.js +162 -0
  62. package/dist/browser/content/ReferenceChip.js.map +1 -0
  63. package/dist/browser/content/calendar-pointer.js +9 -0
  64. package/dist/browser/content/calendar-pointer.js.map +1 -1
  65. package/dist/browser/content/calendar-time-view.js +6 -3
  66. package/dist/browser/content/calendar-time-view.js.map +1 -1
  67. package/dist/browser/content/chart-inspection-core.js +557 -0
  68. package/dist/browser/content/chart-inspection-core.js.map +1 -0
  69. package/dist/browser/content/chart-inspection.js +10 -445
  70. package/dist/browser/content/chart-inspection.js.map +1 -1
  71. package/dist/browser/content/chart-line-gaps.js +1 -1
  72. package/dist/browser/content/chart-line-gaps.js.map +1 -1
  73. package/dist/browser/content/chart-snapshot.js +1 -1
  74. package/dist/browser/content/chart-snapshot.js.map +1 -1
  75. package/dist/browser/content/index.js +3 -0
  76. package/dist/browser/content/index.js.map +1 -1
  77. package/dist/browser/feedback/dialog-core.js +135 -23
  78. package/dist/browser/feedback/dialog-core.js.map +1 -1
  79. package/dist/browser/index.js +1 -0
  80. package/dist/browser/index.js.map +1 -1
  81. package/dist/browser/input-mode.js +40 -0
  82. package/dist/browser/input-mode.js.map +1 -0
  83. package/dist/browser/inputs/FileDropTarget.js +24 -9
  84. package/dist/browser/inputs/FileDropTarget.js.map +1 -1
  85. package/dist/browser/inputs/FileInputs.js +2 -2
  86. package/dist/browser/inputs/FileInputs.js.map +1 -1
  87. package/dist/browser/inputs/SelectChip.js +9 -0
  88. package/dist/browser/inputs/SelectChip.js.map +1 -1
  89. package/dist/browser/inputs/emoji/EmojiPicker.js +13 -0
  90. package/dist/browser/inputs/emoji/EmojiPicker.js.map +1 -1
  91. package/dist/browser/inputs/file-drop.js.map +1 -1
  92. package/dist/browser/layout/AppOverview.js +1 -1
  93. package/dist/browser/layout/AppOverview.js.map +1 -1
  94. package/dist/browser/layout/AppWorkspace.js +644 -445
  95. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  96. package/dist/browser/layout/DetailPanel.js +283 -197
  97. package/dist/browser/layout/DetailPanel.js.map +1 -1
  98. package/dist/browser/layout/Discussion.js +233 -185
  99. package/dist/browser/layout/Discussion.js.map +1 -1
  100. package/dist/browser/layout/PanelDialog.js +88 -86
  101. package/dist/browser/layout/PanelDialog.js.map +1 -1
  102. package/dist/browser/layout/ResizeSeparator.js +81 -0
  103. package/dist/browser/layout/ResizeSeparator.js.map +1 -0
  104. package/dist/browser/layout/SidebarSwitcher.js +9 -2
  105. package/dist/browser/layout/SidebarSwitcher.js.map +1 -1
  106. package/dist/browser/layout/TabBar.js +15 -12
  107. package/dist/browser/layout/TabBar.js.map +1 -1
  108. package/dist/browser/layout/TableOfContents.js +10 -2
  109. package/dist/browser/layout/TableOfContents.js.map +1 -1
  110. package/dist/browser/layout/app-workspace-controller.js +130 -17
  111. package/dist/browser/layout/app-workspace-controller.js.map +1 -1
  112. package/dist/browser/layout/detail-panel-messages.js +35 -0
  113. package/dist/browser/layout/detail-panel-messages.js.map +1 -0
  114. package/dist/browser/layout/index.js +3 -1
  115. package/dist/browser/layout/index.js.map +1 -1
  116. package/dist/browser/layout/resize-separator.js +90 -0
  117. package/dist/browser/layout/resize-separator.js.map +1 -0
  118. package/dist/browser/layout/workspace-messages.js +12 -2
  119. package/dist/browser/layout/workspace-messages.js.map +1 -1
  120. package/dist/browser/surfaces/Avatar.js +50 -20
  121. package/dist/browser/surfaces/Avatar.js.map +1 -1
  122. package/dist/browser/surfaces/AvatarStack.js +406 -0
  123. package/dist/browser/surfaces/AvatarStack.js.map +1 -0
  124. package/dist/browser/surfaces/LinkCard.js +1 -1
  125. package/dist/browser/surfaces/LinkCard.js.map +1 -1
  126. package/dist/browser/surfaces/Placeholder.js +14 -3
  127. package/dist/browser/surfaces/Placeholder.js.map +1 -1
  128. package/dist/browser/surfaces/StatCell.js +23 -0
  129. package/dist/browser/surfaces/StatCell.js.map +1 -1
  130. package/dist/browser/surfaces/avatar-messages.js +8 -2
  131. package/dist/browser/surfaces/avatar-messages.js.map +1 -1
  132. package/dist/browser/surfaces/index.js +1 -0
  133. package/dist/browser/surfaces/index.js.map +1 -1
  134. package/dist/browser/widgets/Widget.js +1 -1
  135. package/dist/browser/widgets/Widget.js.map +1 -1
  136. package/dist/ssr/actions/ContextMenu.js +26 -3
  137. package/dist/ssr/actions/ContextMenu.js.map +1 -1
  138. package/dist/ssr/actions/DragAndDrop.js +63 -0
  139. package/dist/ssr/actions/DragAndDrop.js.map +1 -0
  140. package/dist/ssr/actions/Dropdown.js +140 -72
  141. package/dist/ssr/actions/Dropdown.js.map +1 -1
  142. package/dist/ssr/actions/GestureMenu.js +76 -107
  143. package/dist/ssr/actions/GestureMenu.js.map +1 -1
  144. package/dist/ssr/actions/Toolbar.js +294 -14
  145. package/dist/ssr/actions/Toolbar.js.map +1 -1
  146. package/dist/ssr/actions/drag-and-drop-messages.js +75 -0
  147. package/dist/ssr/actions/drag-and-drop-messages.js.map +1 -0
  148. package/dist/ssr/actions/drag-and-drop.js +692 -0
  149. package/dist/ssr/actions/drag-and-drop.js.map +1 -0
  150. package/dist/ssr/actions/index.js +1 -0
  151. package/dist/ssr/actions/index.js.map +1 -1
  152. package/dist/ssr/actions/menu-rows.js +15 -0
  153. package/dist/ssr/actions/menu-rows.js.map +1 -0
  154. package/dist/ssr/actions/menu-sheet.js +138 -0
  155. package/dist/ssr/actions/menu-sheet.js.map +1 -0
  156. package/dist/ssr/actions/toolbar-messages.js +20 -0
  157. package/dist/ssr/actions/toolbar-messages.js.map +1 -0
  158. package/dist/ssr/chart-inspection.js +3 -0
  159. package/dist/ssr/chart-inspection.js.map +1 -0
  160. package/dist/ssr/chat/ChatComposer.js +393 -102
  161. package/dist/ssr/chat/ChatComposer.js.map +1 -1
  162. package/dist/ssr/chat/ChatDecision.js +465 -0
  163. package/dist/ssr/chat/ChatDecision.js.map +1 -0
  164. package/dist/ssr/chat/ChatPrimitives.js +2 -2
  165. package/dist/ssr/chat/ChatPrimitives.js.map +1 -1
  166. package/dist/ssr/chat/ChatTimeline.js.map +1 -1
  167. package/dist/ssr/chat/chat-messages.js +25 -1
  168. package/dist/ssr/chat/chat-messages.js.map +1 -1
  169. package/dist/ssr/chat/command-search.js +13 -3
  170. package/dist/ssr/chat/command-search.js.map +1 -1
  171. package/dist/ssr/chat/index.js +8 -1
  172. package/dist/ssr/chat/index.js.map +1 -1
  173. package/dist/ssr/chat/reaction-people.js +15 -0
  174. package/dist/ssr/chat/reaction-people.js.map +1 -0
  175. package/dist/ssr/chat/types.js.map +1 -1
  176. package/dist/ssr/content/Calendar.js +3 -3
  177. package/dist/ssr/content/Calendar.js.map +1 -1
  178. package/dist/ssr/content/Chart.js +25 -38
  179. package/dist/ssr/content/Chart.js.map +1 -1
  180. package/dist/ssr/content/ChartSnapshotView.js +7 -10
  181. package/dist/ssr/content/ChartSnapshotView.js.map +1 -1
  182. package/dist/ssr/content/FileBrowser.js +2 -2
  183. package/dist/ssr/content/FileBrowser.js.map +1 -1
  184. package/dist/ssr/content/FileTree.js +21 -14
  185. package/dist/ssr/content/FileTree.js.map +1 -1
  186. package/dist/ssr/content/FileTypeIcon.js +50 -0
  187. package/dist/ssr/content/FileTypeIcon.js.map +1 -0
  188. package/dist/ssr/content/FileView.js +2 -2
  189. package/dist/ssr/content/FileView.js.map +1 -1
  190. package/dist/ssr/content/MessageRow.js +98 -152
  191. package/dist/ssr/content/MessageRow.js.map +1 -1
  192. package/dist/ssr/content/ReactionBar.js +304 -0
  193. package/dist/ssr/content/ReactionBar.js.map +1 -0
  194. package/dist/ssr/content/ReferenceChip.js +121 -0
  195. package/dist/ssr/content/ReferenceChip.js.map +1 -0
  196. package/dist/ssr/content/calendar-pointer.js +9 -0
  197. package/dist/ssr/content/calendar-pointer.js.map +1 -1
  198. package/dist/ssr/content/calendar-time-view.js +6 -3
  199. package/dist/ssr/content/calendar-time-view.js.map +1 -1
  200. package/dist/ssr/content/chart-inspection-core.js +557 -0
  201. package/dist/ssr/content/chart-inspection-core.js.map +1 -0
  202. package/dist/ssr/content/chart-inspection.js +10 -445
  203. package/dist/ssr/content/chart-inspection.js.map +1 -1
  204. package/dist/ssr/content/chart-line-gaps.js +1 -1
  205. package/dist/ssr/content/chart-line-gaps.js.map +1 -1
  206. package/dist/ssr/content/chart-snapshot.js +1 -1
  207. package/dist/ssr/content/chart-snapshot.js.map +1 -1
  208. package/dist/ssr/content/index.js +3 -0
  209. package/dist/ssr/content/index.js.map +1 -1
  210. package/dist/ssr/feedback/dialog-core.js +135 -23
  211. package/dist/ssr/feedback/dialog-core.js.map +1 -1
  212. package/dist/ssr/index.js +1 -0
  213. package/dist/ssr/index.js.map +1 -1
  214. package/dist/ssr/input-mode.js +40 -0
  215. package/dist/ssr/input-mode.js.map +1 -0
  216. package/dist/ssr/inputs/FileDropTarget.js +17 -5
  217. package/dist/ssr/inputs/FileDropTarget.js.map +1 -1
  218. package/dist/ssr/inputs/FileInputs.js +2 -2
  219. package/dist/ssr/inputs/FileInputs.js.map +1 -1
  220. package/dist/ssr/inputs/SelectChip.js +9 -0
  221. package/dist/ssr/inputs/SelectChip.js.map +1 -1
  222. package/dist/ssr/inputs/emoji/EmojiPicker.js +12 -0
  223. package/dist/ssr/inputs/emoji/EmojiPicker.js.map +1 -1
  224. package/dist/ssr/inputs/file-drop.js.map +1 -1
  225. package/dist/ssr/layout/AppOverview.js +1 -1
  226. package/dist/ssr/layout/AppOverview.js.map +1 -1
  227. package/dist/ssr/layout/AppWorkspace.js +272 -95
  228. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  229. package/dist/ssr/layout/DetailPanel.js +112 -58
  230. package/dist/ssr/layout/DetailPanel.js.map +1 -1
  231. package/dist/ssr/layout/Discussion.js +63 -36
  232. package/dist/ssr/layout/Discussion.js.map +1 -1
  233. package/dist/ssr/layout/PanelDialog.js +7 -6
  234. package/dist/ssr/layout/PanelDialog.js.map +1 -1
  235. package/dist/ssr/layout/ResizeSeparator.js +45 -0
  236. package/dist/ssr/layout/ResizeSeparator.js.map +1 -0
  237. package/dist/ssr/layout/SidebarSwitcher.js +9 -2
  238. package/dist/ssr/layout/SidebarSwitcher.js.map +1 -1
  239. package/dist/ssr/layout/TabBar.js +1 -1
  240. package/dist/ssr/layout/TabBar.js.map +1 -1
  241. package/dist/ssr/layout/TableOfContents.js +10 -2
  242. package/dist/ssr/layout/TableOfContents.js.map +1 -1
  243. package/dist/ssr/layout/app-workspace-controller.js +130 -17
  244. package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
  245. package/dist/ssr/layout/detail-panel-messages.js +35 -0
  246. package/dist/ssr/layout/detail-panel-messages.js.map +1 -0
  247. package/dist/ssr/layout/index.js +3 -1
  248. package/dist/ssr/layout/index.js.map +1 -1
  249. package/dist/ssr/layout/resize-separator.js +90 -0
  250. package/dist/ssr/layout/resize-separator.js.map +1 -0
  251. package/dist/ssr/layout/workspace-messages.js +12 -2
  252. package/dist/ssr/layout/workspace-messages.js.map +1 -1
  253. package/dist/ssr/surfaces/Avatar.js +20 -2
  254. package/dist/ssr/surfaces/Avatar.js.map +1 -1
  255. package/dist/ssr/surfaces/AvatarStack.js +286 -0
  256. package/dist/ssr/surfaces/AvatarStack.js.map +1 -0
  257. package/dist/ssr/surfaces/LinkCard.js +1 -1
  258. package/dist/ssr/surfaces/LinkCard.js.map +1 -1
  259. package/dist/ssr/surfaces/Placeholder.js +4 -2
  260. package/dist/ssr/surfaces/Placeholder.js.map +1 -1
  261. package/dist/ssr/surfaces/StatCell.js +23 -0
  262. package/dist/ssr/surfaces/StatCell.js.map +1 -1
  263. package/dist/ssr/surfaces/avatar-messages.js +8 -2
  264. package/dist/ssr/surfaces/avatar-messages.js.map +1 -1
  265. package/dist/ssr/surfaces/index.js +1 -0
  266. package/dist/ssr/surfaces/index.js.map +1 -1
  267. package/dist/ssr/widgets/Widget.js +1 -1
  268. package/dist/ssr/widgets/Widget.js.map +1 -1
  269. package/dist/styles.css +1 -1
  270. package/dist/types/actions/ContextMenu.d.ts +9 -0
  271. package/dist/types/actions/DragAndDrop.d.ts +29 -0
  272. package/dist/types/actions/Dropdown.d.ts +12 -5
  273. package/dist/types/actions/GestureMenu.d.ts +6 -4
  274. package/dist/types/actions/Toolbar.d.ts +20 -0
  275. package/dist/types/actions/drag-and-drop-messages.d.ts +35 -0
  276. package/dist/types/actions/drag-and-drop.d.ts +36 -0
  277. package/dist/types/actions/index.d.ts +3 -1
  278. package/dist/types/actions/menu-rows.d.ts +5 -0
  279. package/dist/types/actions/menu-sheet.d.ts +22 -0
  280. package/dist/types/actions/toolbar-messages.d.ts +8 -0
  281. package/dist/types/chart-inspection.d.ts +2 -0
  282. package/dist/types/chat/ChatComposer.d.ts +26 -1
  283. package/dist/types/chat/ChatDecision.d.ts +133 -0
  284. package/dist/types/chat/ChatPrimitives.d.ts +4 -1
  285. package/dist/types/chat/ChatTimeline.d.ts +2 -1
  286. package/dist/types/chat/chat-messages.d.ts +13 -2
  287. package/dist/types/chat/command-search.d.ts +5 -0
  288. package/dist/types/chat/index.d.ts +25 -1
  289. package/dist/types/chat/reaction-people.d.ts +9 -0
  290. package/dist/types/chat/types.d.ts +54 -1
  291. package/dist/types/content/Chart.d.ts +11 -5
  292. package/dist/types/content/FileTypeIcon.d.ts +27 -0
  293. package/dist/types/content/MessageRow.d.ts +3 -10
  294. package/dist/types/content/ReactionBar.d.ts +32 -0
  295. package/dist/types/content/ReferenceChip.d.ts +49 -0
  296. package/dist/types/content/calendar-pointer.d.ts +6 -0
  297. package/dist/types/content/chart-inspection-core.d.ts +61 -0
  298. package/dist/types/content/chart-inspection.d.ts +4 -20
  299. package/dist/types/content/chart-snapshot.d.ts +1 -1
  300. package/dist/types/content/index.d.ts +5 -1
  301. package/dist/types/feedback/dialog-core.d.ts +16 -1
  302. package/dist/types/index.d.ts +1 -0
  303. package/dist/types/input-mode.d.ts +7 -0
  304. package/dist/types/inputs/FileDropTarget.d.ts +6 -3
  305. package/dist/types/inputs/SelectChip.d.ts +2 -0
  306. package/dist/types/inputs/file-drop.d.ts +2 -0
  307. package/dist/types/layout/AppWorkspace.d.ts +5 -3
  308. package/dist/types/layout/DetailPanel.d.ts +11 -0
  309. package/dist/types/layout/Discussion.d.ts +8 -0
  310. package/dist/types/layout/ResizeSeparator.d.ts +9 -0
  311. package/dist/types/layout/TabBar.d.ts +7 -0
  312. package/dist/types/layout/TableOfContents.d.ts +2 -0
  313. package/dist/types/layout/app-workspace-controller.d.ts +2 -0
  314. package/dist/types/layout/detail-panel-messages.d.ts +15 -0
  315. package/dist/types/layout/index.d.ts +3 -1
  316. package/dist/types/layout/resize-separator.d.ts +18 -0
  317. package/dist/types/layout/workspace-messages.d.ts +5 -0
  318. package/dist/types/surfaces/Avatar.d.ts +12 -0
  319. package/dist/types/surfaces/AvatarStack.d.ts +41 -0
  320. package/dist/types/surfaces/StatCell.d.ts +6 -0
  321. package/dist/types/surfaces/avatar-messages.d.ts +3 -0
  322. package/dist/types/surfaces/index.d.ts +3 -1
  323. package/package.json +7 -2
@@ -5,11 +5,9 @@ import { createComponent as _$createComponent } from "solid-js/web";
5
5
  import { ssr as _$ssr } from "solid-js/web";
6
6
  import { escape as _$escape } from "solid-js/web";
7
7
  var _tmpl$ = ["<i class=\"", "\" aria-hidden=\"true\"></i>"],
8
- _tmpl$2 = "<span class=\"k2b-chart__anchor\" aria-hidden=\"true\"></span>",
9
- _tmpl$3 = ["<span", " role=\"tooltip\" popover=\"manual\" data-instant=\"true\" class=\"k2b-tooltip k2b-chart__tooltip\"></span>"],
10
- _tmpl$4 = ["<div class=\"k2b-chart__controls\">", "", "", "</div>"],
11
- _tmpl$5 = ["<div class=\"", "\"", " style=\"", "\" role=\"group\"", "><div class=\"k2b-chart__svg\"", " style=\"", "\">", "</div>", "", "</div>"],
12
- _tmpl$6 = ["<div class=\"", "\" style=\"", "\">", "</div>"];
8
+ _tmpl$2 = ["<div class=\"k2b-chart__controls\">", "", "", "</div>"],
9
+ _tmpl$3 = ["<div class=\"", "\"", " data-interactive=\"true\" style=\"", "\" role=\"group\"", " tabindex=\"0\"><div class=\"k2b-chart__svg\"", " style=\"", "\">", "</div><span class=\"k2b-chart__anchor\" aria-hidden=\"true\"></span><span", " role=\"tooltip\" popover=\"manual\" data-instant=\"true\" class=\"k2b-tooltip k2b-chart__tooltip\"></span>", "</div>"],
10
+ _tmpl$4 = ["<div class=\"", "\" style=\"", "\">", "</div>"];
13
11
  import { charts } from "@k2b/stdlib";
14
12
  import { createEffect, createMemo, createSignal, createUniqueId, onCleanup, onMount, Show, splitProps, untrack } from "solid-js";
15
13
  import { isServer } from "solid-js/web";
@@ -18,6 +16,7 @@ import { suppressTextSelection } from "../internal/text-selection";
18
16
  import { useLocale } from "../intl/locale";
19
17
  import { useUiMessages } from "../intl/messages";
20
18
  import { createChartInspection } from "./chart-inspection";
19
+ import { closeChartInspectionOnOutside } from "./chart-inspection-core";
21
20
  import { lineGapsSvg } from "./chart-line-gaps";
22
21
  import { DEFAULT_MAP_VIEWPORT, normalizeMapViewport, panMapViewport, zoomMapViewport } from "./chart-map-viewport";
23
22
  import { useChartMessages } from "./chart-messages";
@@ -46,9 +45,9 @@ import { useViewportMessages } from "./viewport-messages";
46
45
  * **Why so thin.** The props are a discriminated union over each
47
46
  * stdlib chart function — `kind: "line"` brings in exactly the params
48
47
  * `charts.line` expects, `kind: "bar"` brings in `charts.bar`'s, etc.
49
- * Options stay aligned with stdlib without renaming. Shared interactive
50
- * layers add bounded pan / zoom controls to maps and state timelines, plus
51
- * renderer-owned inspection, tooltips and optional selection for all chart kinds.
48
+ * Options stay aligned with stdlib without renaming. Every chart provides
49
+ * renderer-owned inspection, tooltips and optional selection by default.
50
+ * `interactive` adds bounded pan / zoom and reset controls to maps and state timelines.
52
51
  * If stdlib gains a new option, it's automatically available at every
53
52
  * callsite.
54
53
  *
@@ -116,7 +115,7 @@ export const renderChartSvg = (props, width, height, mapViewport, timelineViewpo
116
115
  width,
117
116
  height,
118
117
  viewport: timelineViewport,
119
- interactive: props.interactive
118
+ interactive: true
120
119
  }));
121
120
  }
122
121
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -127,7 +126,7 @@ export const renderChartSvg = (props, width, height, mapViewport, timelineViewpo
127
126
  } : {}),
128
127
  width,
129
128
  height,
130
- inspect: props.interactive === true || props.kind === "line" && props.maxGap !== undefined
129
+ inspect: true
131
130
  });
132
131
  if (props.kind === "line" && props.maxGap !== undefined) {
133
132
  if (props.area || props.errorBand) throw new Error("Chart maxGap does not support area or errorBand fills");
@@ -189,10 +188,15 @@ const Chart = props => {
189
188
  let pendingPointer;
190
189
  const interactiveMap = () => props.kind === "map" && props.interactive === true;
191
190
  const interactiveTimeline = () => props.kind === "stateTimeline" && props.interactive === true;
192
- const interactiveLine = () => props.kind === "line" && props.interactive === true;
193
- const interactive = () => props.interactive === true;
194
191
  const draggable = () => interactiveMap() || interactiveTimeline();
195
192
  const labels = () => props.labels ?? {};
193
+ const accessibleName = () => {
194
+ const override = props.kind === "map" ? labels().interactiveMap : props.kind === "stateTimeline" ? labels().interactiveTimeline : props.kind === "line" ? labels().interactiveLine : labels().interactiveChart;
195
+ const title = "title" in props && typeof props.title === "string" && props.title.trim() ? props.title : undefined;
196
+ const valueLabel = (props.kind === "stat" || props.kind === "gauge") && props.label?.trim() ? props.label : undefined;
197
+ const fallback = props.kind === "map" ? chartMessages().interactiveMap : props.kind === "stateTimeline" ? chartMessages().interactiveTimeline : props.kind === "line" ? chartMessages().interactiveLineChart : chartMessages().interactiveChart;
198
+ return override ?? title ?? valueLabel ?? fallback;
199
+ };
196
200
  const timelineFullDomain = () => props.kind === "stateTimeline" ? stateTimelineDomain(props.rows, props.domain) : [0, 1];
197
201
  createEffect(() => {
198
202
  if (props.kind === "map") {
@@ -379,7 +383,7 @@ const Chart = props => {
379
383
  tooltip: () => chartTooltipRef,
380
384
  anchor: () => lineAnchorRef,
381
385
  kind: () => props.kind,
382
- enabled: interactive,
386
+ enabled: () => !isEmpty(props),
383
387
  select: selection => props.onSelect?.(selection),
384
388
  format: selection => {
385
389
  if (props.tooltip) return props.tooltip(selection);
@@ -414,21 +418,11 @@ const Chart = props => {
414
418
  });
415
419
  onMount(() => {
416
420
  if (!containerRef) return;
417
- const outside = event => {
418
- if (event.target instanceof Node && !containerRef?.contains(event.target)) closeChartTooltip();
419
- };
420
- window.addEventListener("pointerdown", outside);
421
- const scroll = event => {
422
- if (event.target instanceof Node && chartTooltipRef?.contains(event.target)) return;
423
- closeChartTooltip();
424
- };
425
- window.addEventListener("scroll", scroll, true);
426
- window.addEventListener("resize", closeChartTooltip);
427
- onCleanup(() => {
428
- window.removeEventListener("pointerdown", outside);
429
- window.removeEventListener("scroll", scroll, true);
430
- window.removeEventListener("resize", closeChartTooltip);
431
- });
421
+ onCleanup(closeChartInspectionOnOutside({
422
+ container: () => containerRef,
423
+ tooltip: () => chartTooltipRef,
424
+ close: closeChartTooltip
425
+ }));
432
426
  });
433
427
  const chartStyle = () => props.style ?? (props.kind === "stateTimeline" ? {
434
428
  height: `${stateTimelineHeight(props.rows.length, props.legend !== false)}px`
@@ -447,22 +441,15 @@ const Chart = props => {
447
441
  return !isEmpty(props);
448
442
  },
449
443
  get fallback() {
450
- return _$ssr(_tmpl$6, `k2b-chart k2b-chart__empty ${_$escape(props.class ?? "", true)}`, _$ssrStyle(chartStyle()), _$escape(labels().empty ?? messages().noData));
444
+ return _$ssr(_tmpl$4, `k2b-chart k2b-chart__empty ${_$escape(props.class ?? "", true)}`, _$ssrStyle(chartStyle()), _$escape(labels().empty ?? messages().noData));
451
445
  },
452
446
  get children() {
453
- return _$ssr(_tmpl$5, `k2b-chart ${_$escape(props.class ?? "", true)}`, _$ssrAttribute("data-chart-kind", _$escape(props.kind, true), false) + _$ssrAttribute("data-drag", draggable() ? dragging() ? "active" : "idle" : _$escape(undefined, true), false) + _$ssrAttribute("data-crosshair", !draggable() && interactiveLine() ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-interactive", interactive() ? "true" : _$escape(undefined, true), false), _$ssrStyle(chartStyle()), _$ssrAttribute("aria-label", interactiveMap() ? _$escape(labels().interactiveMap ?? chartMessages().interactiveMap, true) : interactiveTimeline() ? _$escape(labels().interactiveTimeline ?? chartMessages().interactiveTimeline, true) : interactiveLine() ? _$escape(labels().interactiveLine ?? chartMessages().interactiveLineChart, true) : interactive() ? _$escape(labels().interactiveChart ?? chartMessages().interactiveChart, true) : _$escape(undefined, true), false) + _$ssrAttribute("aria-description", interactive() ? _$escape(chartMessages().interactiveChart, true) : _$escape(undefined, true), false) + _$ssrAttribute("tabindex", interactive() ? 0 : _$escape(undefined, true), false), _$ssrAttribute("data-stretch", !preservesAspectRatio(props.kind) ? "true" : _$escape(undefined, true), false), _$ssrStyleProperty("--k2b-chart-width:", `${_$escape(size().width, true)}px`) + _$ssrStyleProperty(";--k2b-chart-height:", `${_$escape(size().height, true)}px`) + _$ssrStyleProperty(";aspect-ratio:", `${_$escape(size().width, true)} / ${_$escape(size().height, true)}`), isServer ? selectedChartSvg(svgMarkup(), props.selected) : svgMarkup(), _$escape(_$createComponent(Show, {
454
- get when() {
455
- return interactive();
456
- },
457
- get children() {
458
- return [_$ssr(_tmpl$2), _$ssr(_tmpl$3, _$ssrAttribute("id", _$escape(chartTooltipId, true), false))];
459
- }
460
- })), _$escape(_$createComponent(Show, {
447
+ return _$ssr(_tmpl$3, `k2b-chart ${_$escape(props.class ?? "", true)}`, _$ssrAttribute("data-chart-kind", _$escape(props.kind, true), false) + _$ssrAttribute("data-drag", draggable() ? dragging() ? "active" : "idle" : _$escape(undefined, true), false) + _$ssrAttribute("data-crosshair", !draggable() && props.kind === "line" ? "true" : _$escape(undefined, true), false), _$ssrStyle(chartStyle()), _$ssrAttribute("aria-label", _$escape(accessibleName(), true), false) + _$ssrAttribute("aria-description", accessibleName() !== chartMessages().interactiveChart ? _$escape(chartMessages().interactiveChart, true) : _$escape(undefined, true), false), _$ssrAttribute("data-stretch", !preservesAspectRatio(props.kind) ? "true" : _$escape(undefined, true), false), _$ssrStyleProperty("--k2b-chart-width:", `${_$escape(size().width, true)}px`) + _$ssrStyleProperty(";--k2b-chart-height:", `${_$escape(size().height, true)}px`) + _$ssrStyleProperty(";aspect-ratio:", `${_$escape(size().width, true)} / ${_$escape(size().height, true)}`), isServer ? selectedChartSvg(svgMarkup(), props.selected) : svgMarkup(), _$ssrAttribute("id", _$escape(chartTooltipId, true), false), _$escape(_$createComponent(Show, {
461
448
  get when() {
462
449
  return draggable();
463
450
  },
464
451
  get children() {
465
- return _$ssr(_tmpl$4, _$escape(control(labels().zoomIn ?? viewportMessages().zoomIn, "+", "ti-plus", () => zoom(1))), _$escape(control(labels().zoomOut ?? viewportMessages().zoomOut, "-", "ti-minus", () => zoom(-1))), _$escape(control(interactiveMap() ? labels().resetMap ?? chartMessages().resetMapView : labels().resetTimeline ?? chartMessages().resetTimelineView, "0", "ti-focus-centered", reset)));
452
+ return _$ssr(_tmpl$2, _$escape(control(labels().zoomIn ?? viewportMessages().zoomIn, "+", "ti-plus", () => zoom(1))), _$escape(control(labels().zoomOut ?? viewportMessages().zoomOut, "-", "ti-minus", () => zoom(-1))), _$escape(control(interactiveMap() ? labels().resetMap ?? chartMessages().resetMapView : labels().resetTimeline ?? chartMessages().resetTimelineView, "0", "ti-focus-centered", reset)));
466
453
  }
467
454
  })));
468
455
  }
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["content/Chart.tsx"],"sourcesContent":["import type { MapViewport } from \"@k2b/stdlib\";\nimport { charts } from \"@k2b/stdlib\";\nimport type { JSX } from \"solid-js\";\nimport { createEffect, createMemo, createSignal, createUniqueId, onCleanup, onMount, Show, splitProps, untrack } from \"solid-js\";\nimport { isServer } from \"solid-js/web\";\nimport { IconButton } from \"../actions/Button\";\nimport { suppressTextSelection } from \"../internal/text-selection\";\nimport { useLocale } from \"../intl/locale\";\nimport { useUiMessages } from \"../intl/messages\";\nimport type { ChartCursor } from \"./chart-cursor\";\nimport { type ChartDatumRef, type ChartSelection, type ChartTooltipFormatter, createChartInspection } from \"./chart-inspection\";\nimport { lineGapsSvg } from \"./chart-line-gaps\";\nimport { DEFAULT_MAP_VIEWPORT, normalizeMapViewport, panMapViewport, zoomMapViewport } from \"./chart-map-viewport\";\nimport { useChartMessages } from \"./chart-messages\";\nimport {\n panStateTimelineViewport,\n renderStateTimelineSvg,\n type StateTimelineChartOptions,\n type StateTimelineDomain,\n stateTimelineDomain,\n stateTimelineHeight,\n zoomStateTimelineViewport,\n} from \"./chart-state-timeline\";\nimport { responsiveChartSvg, responsiveMapSvg, selectedChartSvg } from \"./chart-svg\";\nimport { useViewportMessages } from \"./viewport-messages\";\n\n/**\n * Chart — minimal Solid wrapper around `stdlib.charts`.\n *\n * **Live-update story.** `charts.<kind>(opts)` returns an SVG string;\n * Solid's `innerHTML` is reactive, so any time a prop (signal, store\n * slice, derived value) changes, the SVG re-renders. No manual\n * subscription, no imperative DOM patching. Trade-off: every change\n * is a full SVG re-build, not a diff — fine for dashboard cadences\n * (poll, websocket, store updates). Don't use this for 60fps streaming.\n *\n * **Sizing.** The server and browser render the same logical viewBox. CSS\n * fits Cartesian plots to the container and preserves text/marker sizes;\n * maps fit the whole world and zoom uniformly across the full plot; pies, donuts and gauges retain\n * their aspect ratio. No measurement\n * or hydration redraw is needed. The caller sizes the wrapper, for example\n * `style={{ height: \"14rem\" }}`. State timelines derive their default height\n * from the row count and legend via `stateTimelineHeight()`.\n *\n * **Why so thin.** The props are a discriminated union over each\n * stdlib chart function — `kind: \"line\"` brings in exactly the params\n * `charts.line` expects, `kind: \"bar\"` brings in `charts.bar`'s, etc.\n * Options stay aligned with stdlib without renaming. Shared interactive\n * layers add bounded pan / zoom controls to maps and state timelines, plus\n * renderer-owned inspection, tooltips and optional selection for all chart kinds.\n * If stdlib gains a new option, it's automatically available at every\n * callsite.\n *\n * **Theming.** stdlib charts use `currentColor` for axes / ticks /\n * tick labels — set the wrapping element's `color` and everything\n * inherits. Series colors come from `--stdlib-chart-c1..c8` CSS\n * custom properties; override on the parent for per-chart palettes.\n *\n * ```tsx\n * <Chart kind=\"line\" style={{ height: \"12rem\" }}\n * series={[{ data: points() }]}\n * yAxis={{ format: v => `€${v}k` }} />\n *\n * <Chart kind=\"donut\" style={{ height: \"12rem\" }} data={slices()} />\n *\n * <Chart kind=\"sparkline\" style={{ width: \"6rem\", height: \"1.5rem\" }} data={trend()} />\n *\n * <Chart kind=\"map\" style={{ height: \"16rem\" }} series={locations()} interactive />\n * ```\n */\n\n/** All chart kinds shipped by `stdlib.charts`. */\nexport type ChartKind = keyof typeof charts;\n\nexport type ChartLabels = Partial<{\n empty: string;\n series: string;\n interactiveMap: string;\n interactiveTimeline: string;\n interactiveLine: string;\n interactiveChart: string;\n zoomIn: string;\n zoomOut: string;\n resetMap: string;\n resetTimeline: string;\n}>;\n\n/**\n * Per-kind props: `kind` discriminator + the exact options that\n * `charts.<kind>` accepts, **minus** `width` / `height` (the wrapper\n * owns those — CSS fits a stable coordinate space to the box). Solid's\n * component model handles discriminated unions natively, so callsites\n * get full type safety.\n */\nexport type ChartProps = {\n [K in ChartKind]: {\n kind: K;\n class?: string;\n style?: JSX.CSSProperties | string;\n labels?: ChartLabels;\n interactive?: boolean;\n onSelect?: (selection: ChartSelection) => void;\n /** Controlled highlight; indices belong to this exact input snapshot. */\n selected?: ChartDatumRef | null;\n tooltip?: ChartTooltipFormatter;\n /** Optional shared X cursor for line charts. */\n cursor?: ChartCursor;\n } & (K extends \"map\"\n ? {\n /** Target when zooming in from the world view. Defaults to Europe (50, 10). */\n zoomFocus?: Pick<MapViewport, \"latitude\" | \"longitude\">;\n }\n : {}) &\n (K extends \"line\" ? { /** Largest connected X distance; positive, finite, without area/errorBand fills. */ maxGap?: number } : {}) &\n (K extends \"stateTimeline\" ? StateTimelineChartOptions : Omit<Parameters<(typeof charts)[K]>[0], \"width\" | \"height\" | \"inspect\">);\n}[ChartKind];\n\n/** Pure renderer options: component layout, events and inspection are configured elsewhere. */\nexport type ChartRenderOptions = {\n [K in ChartKind]: Omit<\n Extract<ChartProps, { kind: K }>,\n \"class\" | \"style\" | \"labels\" | \"interactive\" | \"onSelect\" | \"selected\" | \"tooltip\" | \"cursor\"\n >;\n}[ChartKind];\n\n/** Keep the fixed 28-unit bar-gauge rows inside the shared SSR/browser coordinate space. */\nexport const chartRenderHeight = (props: ChartRenderOptions): number => {\n if (props.kind === \"stateTimeline\") return stateTimelineHeight(props.rows.length, props.legend !== false);\n if (props.kind === \"barGauge\") return Math.max(280, (props.title || props.subtitle ? 42 : 16) + props.data.length * 28 + 14);\n return 280;\n};\n\n/**\n * Internal — strips wrapper-only keys from props and forwards the\n * rest (plus logical size) to `charts[kind]`. The `any` is the\n * price for dispatching one function call across 14 different option\n * types; an explicit per-kind switch would type it but balloon the\n * component for no runtime benefit.\n */\nexport const renderChartSvg = (\n props: ChartProps,\n width: number,\n height: number,\n mapViewport?: MapViewport,\n timelineViewport?: StateTimelineDomain,\n): string => {\n const {\n kind,\n class: _class,\n style: _style,\n labels: _labels,\n interactive: _interactive,\n onSelect: _onSelect,\n selected: _selected,\n tooltip: _tooltip,\n cursor: _cursor,\n zoomFocus: _zoomFocus,\n ...opts\n } = props as ChartProps & { interactive?: boolean; zoomFocus?: Pick<MapViewport, \"latitude\" | \"longitude\"> };\n if (kind === \"stateTimeline\") {\n return responsiveChartSvg(\n renderStateTimelineSvg({\n ...(opts as StateTimelineChartOptions),\n width,\n height,\n viewport: timelineViewport,\n interactive: props.interactive,\n }),\n );\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let svg = (charts[kind] as (o: unknown) => string)({\n ...(opts as any),\n ...(kind === \"map\" ? { viewport: DEFAULT_MAP_VIEWPORT } : {}),\n width,\n height,\n inspect: props.interactive === true || (props.kind === \"line\" && props.maxGap !== undefined),\n });\n if (props.kind === \"line\" && props.maxGap !== undefined) {\n if (props.area || props.errorBand) throw new Error(\"Chart maxGap does not support area or errorBand fills\");\n svg = lineGapsSvg(svg, props.maxGap, props);\n }\n if (props.kind === \"map\") return responsiveMapSvg(svg, width, height, normalizeMapViewport(mapViewport ?? props.viewport));\n return preservesAspectRatio(kind) ? svg : responsiveChartSvg(svg);\n};\n\nconst preservesAspectRatio = (kind: ChartKind) => kind === \"map\" || kind === \"pie\" || kind === \"donut\" || kind === \"gauge\";\n\n/** Empty-data short-circuit. Kept per-kind because stdlib's payload\n * key differs (series vs data vs groups). We're conservative: only\n * block on truly empty inputs; partially-filled series get rendered\n * as-is and stdlib handles the gaps. */\nconst isEmpty = (props: ChartProps): boolean => {\n if (props.kind === \"line\" || props.kind === \"scatter\") {\n return !props.series?.length || props.series.every((s) => !s.data.length);\n }\n if (props.kind === \"bar\" || props.kind === \"donut\" || props.kind === \"pie\") {\n return !props.data?.length;\n }\n if (props.kind === \"histogram\" || props.kind === \"sparkline\") {\n return !props.data?.length;\n }\n if (props.kind === \"boxplot\") {\n return !props.groups?.length;\n }\n if (props.kind === \"stateTimeline\") {\n return !props.rows?.length || props.rows.every((row) => !row.intervals.length);\n }\n return false;\n};\n\nconst Chart = (props: ChartProps): JSX.Element => {\n const [, drawingProps] = splitProps(props, [\"selected\", \"onSelect\", \"tooltip\", \"cursor\"]);\n const messages = useUiMessages();\n const chartMessages = useChartMessages();\n const viewportMessages = useViewportMessages();\n const locale = useLocale();\n let containerRef: HTMLDivElement | undefined;\n let chartTooltipRef: HTMLSpanElement | undefined;\n let lineAnchorRef: HTMLSpanElement | undefined;\n // One deterministic coordinate space on the server and client. CSS fits the\n // SVG to its box; hydration must never replace it with measured geometry.\n const size = () => ({\n width: 480,\n height: chartRenderHeight(props),\n });\n const dimensions = () => containerRef?.getBoundingClientRect() ?? size();\n const initialMapViewport = props.kind === \"map\" ? normalizeMapViewport(props.viewport) : DEFAULT_MAP_VIEWPORT;\n const [mapViewport, setMapViewport] = createSignal<MapViewport>(initialMapViewport);\n const initialTimelineViewport =\n props.kind === \"stateTimeline\" ? stateTimelineDomain(props.rows, props.domain) : ([0, 1] as StateTimelineDomain);\n const [timelineViewport, setTimelineViewport] = createSignal<StateTimelineDomain>(initialTimelineViewport);\n const [dragging, setDragging] = createSignal(false);\n const chartTooltipId = `k2b-chart-tooltip-${createUniqueId()}`;\n let timelineViewportLocallyChanged = false;\n let drag:\n | {\n pointerId: number;\n x: number;\n y: number;\n width: number;\n height: number;\n viewport: MapViewport;\n }\n | undefined;\n let timelineDrag:\n | {\n pointerId: number;\n x: number;\n width: number;\n viewport: StateTimelineDomain;\n }\n | undefined;\n let pointerFrame: number | undefined;\n let pendingPointer: { pointerId: number; clientX: number; clientY: number } | undefined;\n\n const interactiveMap = () => props.kind === \"map\" && props.interactive === true;\n const interactiveTimeline = () => props.kind === \"stateTimeline\" && props.interactive === true;\n const interactiveLine = () => props.kind === \"line\" && props.interactive === true;\n const interactive = () => props.interactive === true;\n const draggable = () => interactiveMap() || interactiveTimeline();\n const labels = () => props.labels ?? {};\n const timelineFullDomain = (): StateTimelineDomain =>\n props.kind === \"stateTimeline\" ? stateTimelineDomain(props.rows, props.domain) : [0, 1];\n\n createEffect(() => {\n if (props.kind === \"map\") {\n setMapViewport(normalizeMapViewport(props.viewport));\n }\n });\n\n createEffect(() => {\n if (props.kind === \"stateTimeline\" && !timelineViewportLocallyChanged) {\n setTimelineViewport(timelineFullDomain());\n }\n });\n\n const updateTimelineViewport = (update: (current: StateTimelineDomain) => StateTimelineDomain) => {\n timelineViewportLocallyChanged = true;\n setTimelineViewport(update);\n };\n\n const mapDimensions = () => {\n const viewportElement = containerRef?.querySelector<SVGSVGElement>(\".stdlib-chart-map-viewport\");\n const matrix = viewportElement?.getScreenCTM?.();\n const box = viewportElement?.viewBox?.baseVal;\n if (matrix && box?.width && box.height) {\n return { width: box.width * Math.hypot(matrix.a, matrix.b), height: box.height * Math.hypot(matrix.c, matrix.d) };\n }\n const rect = viewportElement?.getBoundingClientRect();\n if (rect && rect.width > 0 && rect.height > 0) {\n return { width: rect.width, height: rect.height };\n }\n return dimensions();\n };\n\n const zoom = (delta: number) => {\n closeChartTooltip();\n if (interactiveMap()) {\n setMapViewport((current) => zoomMapViewport(current, delta, props.kind === \"map\" ? props.zoomFocus : undefined));\n } else if (interactiveTimeline()) {\n updateTimelineViewport((current) => zoomStateTimelineViewport(current, timelineFullDomain(), delta));\n }\n };\n\n const reset = () => {\n closeChartTooltip();\n if (interactiveMap() && props.kind === \"map\") {\n setMapViewport(normalizeMapViewport(props.viewport));\n }\n if (interactiveTimeline()) {\n timelineViewportLocallyChanged = false;\n setTimelineViewport(timelineFullDomain());\n }\n };\n\n const handlePointerDown: JSX.EventHandlerUnion<HTMLDivElement, PointerEvent> = (event) => {\n inspection.down(event);\n if (!draggable() || event.button !== 0 || (event.target as Element).closest(\"button, a\")) {\n return;\n }\n closeChartTooltip();\n // The pointer's own pointerup or pointercancel ends the hold.\n suppressTextSelection(event.pointerId);\n if (interactiveTimeline()) {\n timelineDrag = {\n pointerId: event.pointerId,\n x: event.clientX,\n width: Math.max(1, event.currentTarget.getBoundingClientRect().width),\n viewport: timelineViewport(),\n };\n event.currentTarget.setPointerCapture(event.pointerId);\n setDragging(true);\n return;\n }\n const dimensions = mapDimensions();\n drag = {\n pointerId: event.pointerId,\n x: event.clientX,\n y: event.clientY,\n width: dimensions.width,\n height: dimensions.height,\n viewport: mapViewport(),\n };\n event.currentTarget.setPointerCapture(event.pointerId);\n setDragging(true);\n };\n\n const flushPointerMove = () => {\n if (pointerFrame !== undefined) {\n cancelAnimationFrame(pointerFrame);\n pointerFrame = undefined;\n }\n const sample = pendingPointer;\n pendingPointer = undefined;\n if (!sample) return;\n const start = timelineDrag ?? drag;\n if (start && Math.hypot(sample.clientX - start.x, sample.clientY - (\"y\" in start ? start.y : sample.clientY)) <= 6) return;\n const activeTimelineDrag = timelineDrag;\n if (activeTimelineDrag?.pointerId === sample.pointerId) {\n updateTimelineViewport(() =>\n panStateTimelineViewport(\n activeTimelineDrag.viewport,\n timelineFullDomain(),\n sample.clientX - activeTimelineDrag.x,\n activeTimelineDrag.width,\n ),\n );\n return;\n }\n if (!drag || drag.pointerId !== sample.pointerId) return;\n setMapViewport(panMapViewport(drag.viewport, sample.clientX - drag.x, sample.clientY - drag.y, drag.width, drag.height));\n };\n\n const handlePointerMove: JSX.EventHandlerUnion<HTMLDivElement, PointerEvent> = (event) => {\n inspection.move(event);\n if (timelineDrag?.pointerId !== event.pointerId && drag?.pointerId !== event.pointerId) return;\n pendingPointer = { pointerId: event.pointerId, clientX: event.clientX, clientY: event.clientY };\n if (pointerFrame !== undefined) return;\n pointerFrame = requestAnimationFrame(flushPointerMove);\n };\n\n const stopDragging: JSX.EventHandlerUnion<HTMLDivElement, PointerEvent> = (event) => {\n if (pendingPointer?.pointerId === event.pointerId) flushPointerMove();\n if (timelineDrag?.pointerId === event.pointerId) {\n if (event.currentTarget.hasPointerCapture(event.pointerId)) {\n event.currentTarget.releasePointerCapture(event.pointerId);\n }\n timelineDrag = undefined;\n setDragging(false);\n return;\n }\n if (!drag || drag.pointerId !== event.pointerId) return;\n if (event.currentTarget.hasPointerCapture(event.pointerId)) {\n event.currentTarget.releasePointerCapture(event.pointerId);\n }\n drag = undefined;\n setDragging(false);\n };\n\n const handleWheel: JSX.EventHandlerUnion<HTMLDivElement, WheelEvent> = (event) => {\n if (interactiveMap() && (event.ctrlKey || event.metaKey)) {\n event.preventDefault();\n zoom(event.deltaY < 0 ? 1 : -1);\n return;\n }\n if (!interactiveTimeline()) return;\n if (event.ctrlKey || event.metaKey) {\n event.preventDefault();\n const rect = event.currentTarget.getBoundingClientRect();\n const anchor = rect.width > 0 ? (event.clientX - rect.left) / rect.width : 0.5;\n updateTimelineViewport((current) => zoomStateTimelineViewport(current, timelineFullDomain(), event.deltaY < 0 ? 1 : -1, anchor));\n } else if (event.shiftKey) {\n event.preventDefault();\n updateTimelineViewport((current) =>\n panStateTimelineViewport(current, timelineFullDomain(), -event.deltaY, event.currentTarget.getBoundingClientRect().width),\n );\n }\n };\n\n const handleKeyDown: JSX.EventHandlerUnion<HTMLDivElement, KeyboardEvent> = (event) => {\n if (inspection.key(event)) return;\n if (!draggable() || event.target !== containerRef) return;\n if (event.key === \"+\" || event.key === \"=\") {\n event.preventDefault();\n zoom(1);\n return;\n }\n if (event.key === \"-\" || event.key === \"_\") {\n event.preventDefault();\n zoom(-1);\n return;\n }\n if (event.key === \"0\" || event.key === \"Home\") {\n event.preventDefault();\n reset();\n return;\n }\n if (interactiveTimeline() && (event.key === \"ArrowLeft\" || event.key === \"ArrowRight\")) {\n event.preventDefault();\n updateTimelineViewport((current) =>\n panStateTimelineViewport(\n current,\n timelineFullDomain(),\n event.key === \"ArrowLeft\" ? 80 : -80,\n event.currentTarget.getBoundingClientRect().width,\n ),\n );\n return;\n }\n const delta: readonly [number, number] | undefined = {\n ArrowLeft: [40, 0],\n ArrowRight: [-40, 0],\n ArrowUp: [0, 40],\n ArrowDown: [0, -40],\n }[event.key] as readonly [number, number] | undefined;\n if (!delta) return;\n event.preventDefault();\n const dimensions = mapDimensions();\n setMapViewport((current) => panMapViewport(current, delta[0], delta[1], dimensions.width, dimensions.height));\n };\n\n const inspection = createChartInspection({\n container: () => containerRef,\n cursor: () => props.cursor,\n tooltip: () => chartTooltipRef,\n anchor: () => lineAnchorRef,\n kind: () => props.kind,\n enabled: interactive,\n select: (selection) => props.onSelect?.(selection),\n format: (selection) => {\n if (props.tooltip) return props.tooltip(selection);\n const fields = chartMessages().chartFields;\n const format = new Intl.NumberFormat(locale(), { maximumFractionDigits: 6 });\n return {\n title:\n selection.datum.label ??\n (selection.datum.seriesIndex !== undefined\n ? `${labels().series ?? chartMessages().series} ${selection.datum.seriesIndex + 1}`\n : undefined),\n rows: selection.datum.values.map((field) => ({\n label:\n selection.kind === \"line\" && field.key === \"y\"\n ? (selection.datum.label ?? labels().series ?? chartMessages().series)\n : fields({ key: field.key }),\n value:\n field.formatted ??\n (field.key === \"upperInclusive\"\n ? field.value === \"true\"\n ? messages().yes\n : messages().no\n : typeof field.value === \"number\"\n ? `${format.format(field.value)}${field.key === \"percent\" ? \"%\" : \"\"}`\n : field.value),\n })),\n };\n },\n });\n const closeChartTooltip = () => inspection.close();\n const svgMarkup = createMemo(() =>\n renderChartSvg(\n drawingProps,\n size().width,\n size().height,\n interactiveMap() ? mapViewport() : undefined,\n interactiveTimeline() ? timelineViewport() : undefined,\n ),\n );\n createEffect(() => {\n svgMarkup();\n inspection.invalidate();\n untrack(() => inspection.selectDatum(props.selected));\n });\n\n createEffect(() => inspection.selectDatum(props.selected));\n\n onCleanup(() => {\n inspection.close();\n if (pointerFrame !== undefined) cancelAnimationFrame(pointerFrame);\n pointerFrame = undefined;\n pendingPointer = undefined;\n });\n\n onMount(() => {\n if (!containerRef) return;\n const outside = (event: PointerEvent) => {\n if (event.target instanceof Node && !containerRef?.contains(event.target)) closeChartTooltip();\n };\n window.addEventListener(\"pointerdown\", outside);\n const scroll = (event: Event) => {\n if (event.target instanceof Node && chartTooltipRef?.contains(event.target)) return;\n closeChartTooltip();\n };\n window.addEventListener(\"scroll\", scroll, true);\n window.addEventListener(\"resize\", closeChartTooltip);\n onCleanup(() => {\n window.removeEventListener(\"pointerdown\", outside);\n window.removeEventListener(\"scroll\", scroll, true);\n window.removeEventListener(\"resize\", closeChartTooltip);\n });\n });\n\n const chartStyle = () =>\n props.style ??\n (props.kind === \"stateTimeline\"\n ? {\n height: `${stateTimelineHeight(props.rows.length, props.legend !== false)}px`,\n }\n : undefined);\n\n const control = (label: string, shortcut: string, icon: string, action: () => void) => (\n <IconButton variant=\"secondary\" label={label} tooltip={`${label} (${shortcut})`} onClick={action}>\n <i class={`ti ${icon}`} aria-hidden=\"true\" />\n </IconButton>\n );\n\n return (\n <Show\n when={!isEmpty(props)}\n fallback={\n <div ref={containerRef} class={`k2b-chart k2b-chart__empty ${props.class ?? \"\"}`} style={chartStyle()}>\n {labels().empty ?? messages().noData}\n </div>\n }\n >\n {/* CSS fits the server-rendered SVG to the caller's box. Only changes\n to chart data/options rebuild the SVG; resizing does not. */}\n <div\n ref={containerRef}\n class={`k2b-chart ${props.class ?? \"\"}`}\n data-chart-kind={props.kind}\n data-drag={draggable() ? (dragging() ? \"active\" : \"idle\") : undefined}\n data-crosshair={!draggable() && interactiveLine() ? \"true\" : undefined}\n data-interactive={interactive() ? \"true\" : undefined}\n style={chartStyle()}\n role=\"group\"\n aria-label={\n interactiveMap()\n ? (labels().interactiveMap ?? chartMessages().interactiveMap)\n : interactiveTimeline()\n ? (labels().interactiveTimeline ?? chartMessages().interactiveTimeline)\n : interactiveLine()\n ? (labels().interactiveLine ?? chartMessages().interactiveLineChart)\n : interactive()\n ? (labels().interactiveChart ?? chartMessages().interactiveChart)\n : undefined\n }\n aria-description={interactive() ? chartMessages().interactiveChart : undefined}\n tabIndex={interactive() ? 0 : undefined}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={stopDragging}\n onPointerCancel={stopDragging}\n onClick={inspection.click}\n onPointerLeave={inspection.leave}\n onFocusIn={inspection.focus}\n onFocusOut={closeChartTooltip}\n onWheel={handleWheel}\n onKeyDown={handleKeyDown}\n >\n <div\n class=\"k2b-chart__svg\"\n data-stretch={!preservesAspectRatio(props.kind) ? \"true\" : undefined}\n style={{\n \"--k2b-chart-width\": `${size().width}px`,\n \"--k2b-chart-height\": `${size().height}px`,\n \"aspect-ratio\": `${size().width} / ${size().height}`,\n }}\n innerHTML={isServer ? selectedChartSvg(svgMarkup(), props.selected) : svgMarkup()}\n />\n <Show when={interactive()}>\n <span ref={lineAnchorRef} class=\"k2b-chart__anchor\" aria-hidden=\"true\" />\n <span\n id={chartTooltipId}\n ref={chartTooltipRef}\n role=\"tooltip\"\n popover=\"manual\"\n data-instant=\"true\"\n class=\"k2b-tooltip k2b-chart__tooltip\"\n />\n </Show>\n <Show when={draggable()}>\n <div class=\"k2b-chart__controls\">\n {control(labels().zoomIn ?? viewportMessages().zoomIn, \"+\", \"ti-plus\", () => zoom(1))}\n {control(labels().zoomOut ?? viewportMessages().zoomOut, \"-\", \"ti-minus\", () => zoom(-1))}\n {control(\n interactiveMap()\n ? (labels().resetMap ?? chartMessages().resetMapView)\n : (labels().resetTimeline ?? chartMessages().resetTimelineView),\n \"0\",\n \"ti-focus-centered\",\n reset,\n )}\n </div>\n </Show>\n </div>\n </Show>\n );\n};\n\nexport default Chart;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["content/Chart.tsx"],"sourcesContent":["import type { MapViewport } from \"@k2b/stdlib\";\nimport { charts } from \"@k2b/stdlib\";\nimport type { JSX } from \"solid-js\";\nimport { createEffect, createMemo, createSignal, createUniqueId, onCleanup, onMount, Show, splitProps, untrack } from \"solid-js\";\nimport { isServer } from \"solid-js/web\";\nimport { IconButton } from \"../actions/Button\";\nimport { suppressTextSelection } from \"../internal/text-selection\";\nimport { useLocale } from \"../intl/locale\";\nimport { useUiMessages } from \"../intl/messages\";\nimport type { ChartCursor } from \"./chart-cursor\";\nimport { createChartInspection } from \"./chart-inspection\";\nimport {\n type ChartDatumRef,\n type ChartKind,\n type ChartSelection,\n type ChartTooltipFormatter,\n closeChartInspectionOnOutside,\n} from \"./chart-inspection-core\";\nimport { lineGapsSvg } from \"./chart-line-gaps\";\nimport { DEFAULT_MAP_VIEWPORT, normalizeMapViewport, panMapViewport, zoomMapViewport } from \"./chart-map-viewport\";\nimport { useChartMessages } from \"./chart-messages\";\nimport {\n panStateTimelineViewport,\n renderStateTimelineSvg,\n type StateTimelineChartOptions,\n type StateTimelineDomain,\n stateTimelineDomain,\n stateTimelineHeight,\n zoomStateTimelineViewport,\n} from \"./chart-state-timeline\";\nimport { responsiveChartSvg, responsiveMapSvg, selectedChartSvg } from \"./chart-svg\";\nimport { useViewportMessages } from \"./viewport-messages\";\n\n/**\n * Chart — minimal Solid wrapper around `stdlib.charts`.\n *\n * **Live-update story.** `charts.<kind>(opts)` returns an SVG string;\n * Solid's `innerHTML` is reactive, so any time a prop (signal, store\n * slice, derived value) changes, the SVG re-renders. No manual\n * subscription, no imperative DOM patching. Trade-off: every change\n * is a full SVG re-build, not a diff — fine for dashboard cadences\n * (poll, websocket, store updates). Don't use this for 60fps streaming.\n *\n * **Sizing.** The server and browser render the same logical viewBox. CSS\n * fits Cartesian plots to the container and preserves text/marker sizes;\n * maps fit the whole world and zoom uniformly across the full plot; pies, donuts and gauges retain\n * their aspect ratio. No measurement\n * or hydration redraw is needed. The caller sizes the wrapper, for example\n * `style={{ height: \"14rem\" }}`. State timelines derive their default height\n * from the row count and legend via `stateTimelineHeight()`.\n *\n * **Why so thin.** The props are a discriminated union over each\n * stdlib chart function — `kind: \"line\"` brings in exactly the params\n * `charts.line` expects, `kind: \"bar\"` brings in `charts.bar`'s, etc.\n * Options stay aligned with stdlib without renaming. Every chart provides\n * renderer-owned inspection, tooltips and optional selection by default.\n * `interactive` adds bounded pan / zoom and reset controls to maps and state timelines.\n * If stdlib gains a new option, it's automatically available at every\n * callsite.\n *\n * **Theming.** stdlib charts use `currentColor` for axes / ticks /\n * tick labels — set the wrapping element's `color` and everything\n * inherits. Series colors come from `--stdlib-chart-c1..c8` CSS\n * custom properties; override on the parent for per-chart palettes.\n *\n * ```tsx\n * <Chart kind=\"line\" style={{ height: \"12rem\" }}\n * series={[{ data: points() }]}\n * yAxis={{ format: v => `€${v}k` }} />\n *\n * <Chart kind=\"donut\" style={{ height: \"12rem\" }} data={slices()} />\n *\n * <Chart kind=\"sparkline\" style={{ width: \"6rem\", height: \"1.5rem\" }} data={trend()} />\n *\n * <Chart kind=\"map\" style={{ height: \"16rem\" }} series={locations()} interactive />\n * ```\n */\n\n/** All chart kinds shipped by `stdlib.charts`. */\nexport type { ChartKind } from \"./chart-inspection-core\";\n\nexport type ChartLabels = Partial<{\n empty: string;\n series: string;\n interactiveMap: string;\n interactiveTimeline: string;\n interactiveLine: string;\n interactiveChart: string;\n zoomIn: string;\n zoomOut: string;\n resetMap: string;\n resetTimeline: string;\n}>;\n\n/**\n * Per-kind props: `kind` discriminator + the exact options that\n * `charts.<kind>` accepts, **minus** `width` / `height` (the wrapper\n * owns those — CSS fits a stable coordinate space to the box). Solid's\n * component model handles discriminated unions natively, so callsites\n * get full type safety.\n */\nexport type ChartProps = {\n [K in ChartKind]: {\n kind: K;\n class?: string;\n style?: JSX.CSSProperties | string;\n labels?: ChartLabels;\n /**\n * Navigation for maps and state timelines: pan, zoom and reset controls.\n * Arrows pan; Alt+arrows inspect. Every chart shows tooltips and keyboard\n * inspection without this prop.\n */\n interactive?: boolean;\n onSelect?: (selection: ChartSelection) => void;\n /** Controlled highlight; indices belong to this exact input snapshot. */\n selected?: ChartDatumRef | null;\n /** Customize the always-on tooltip with a title and labeled text rows. */\n tooltip?: ChartTooltipFormatter;\n /** Optional shared X cursor for line charts. */\n cursor?: ChartCursor;\n } & (K extends \"map\"\n ? {\n /** Target when zooming in from the world view. Defaults to Europe (50, 10). */\n zoomFocus?: Pick<MapViewport, \"latitude\" | \"longitude\">;\n }\n : {}) &\n (K extends \"line\" ? { /** Largest connected X distance; positive, finite, without area/errorBand fills. */ maxGap?: number } : {}) &\n (K extends \"stateTimeline\" ? StateTimelineChartOptions : Omit<Parameters<(typeof charts)[K]>[0], \"width\" | \"height\" | \"inspect\">);\n}[ChartKind];\n\n/** Pure renderer options: component layout, events and inspection are configured elsewhere. */\nexport type ChartRenderOptions = {\n [K in ChartKind]: Omit<\n Extract<ChartProps, { kind: K }>,\n \"class\" | \"style\" | \"labels\" | \"interactive\" | \"onSelect\" | \"selected\" | \"tooltip\" | \"cursor\"\n >;\n}[ChartKind];\n\n/** Keep the fixed 28-unit bar-gauge rows inside the shared SSR/browser coordinate space. */\nexport const chartRenderHeight = (props: ChartRenderOptions): number => {\n if (props.kind === \"stateTimeline\") return stateTimelineHeight(props.rows.length, props.legend !== false);\n if (props.kind === \"barGauge\") return Math.max(280, (props.title || props.subtitle ? 42 : 16) + props.data.length * 28 + 14);\n return 280;\n};\n\n/**\n * Internal — strips wrapper-only keys from props and forwards the\n * rest (plus logical size) to `charts[kind]`. The `any` is the\n * price for dispatching one function call across 14 different option\n * types; an explicit per-kind switch would type it but balloon the\n * component for no runtime benefit.\n */\nexport const renderChartSvg = (\n props: ChartProps,\n width: number,\n height: number,\n mapViewport?: MapViewport,\n timelineViewport?: StateTimelineDomain,\n): string => {\n const {\n kind,\n class: _class,\n style: _style,\n labels: _labels,\n interactive: _interactive,\n onSelect: _onSelect,\n selected: _selected,\n tooltip: _tooltip,\n cursor: _cursor,\n zoomFocus: _zoomFocus,\n ...opts\n } = props as ChartProps & { interactive?: boolean; zoomFocus?: Pick<MapViewport, \"latitude\" | \"longitude\"> };\n if (kind === \"stateTimeline\") {\n return responsiveChartSvg(\n renderStateTimelineSvg({\n ...(opts as StateTimelineChartOptions),\n width,\n height,\n viewport: timelineViewport,\n interactive: true,\n }),\n );\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let svg = (charts[kind] as (o: unknown) => string)({\n ...(opts as any),\n ...(kind === \"map\" ? { viewport: DEFAULT_MAP_VIEWPORT } : {}),\n width,\n height,\n inspect: true,\n });\n if (props.kind === \"line\" && props.maxGap !== undefined) {\n if (props.area || props.errorBand) throw new Error(\"Chart maxGap does not support area or errorBand fills\");\n svg = lineGapsSvg(svg, props.maxGap, props);\n }\n if (props.kind === \"map\") return responsiveMapSvg(svg, width, height, normalizeMapViewport(mapViewport ?? props.viewport));\n return preservesAspectRatio(kind) ? svg : responsiveChartSvg(svg);\n};\n\nconst preservesAspectRatio = (kind: ChartKind) => kind === \"map\" || kind === \"pie\" || kind === \"donut\" || kind === \"gauge\";\n\n/** Empty-data short-circuit. Kept per-kind because stdlib's payload\n * key differs (series vs data vs groups). We're conservative: only\n * block on truly empty inputs; partially-filled series get rendered\n * as-is and stdlib handles the gaps. */\nconst isEmpty = (props: ChartProps): boolean => {\n if (props.kind === \"line\" || props.kind === \"scatter\") {\n return !props.series?.length || props.series.every((s) => !s.data.length);\n }\n if (props.kind === \"bar\" || props.kind === \"donut\" || props.kind === \"pie\") {\n return !props.data?.length;\n }\n if (props.kind === \"histogram\" || props.kind === \"sparkline\") {\n return !props.data?.length;\n }\n if (props.kind === \"boxplot\") {\n return !props.groups?.length;\n }\n if (props.kind === \"stateTimeline\") {\n return !props.rows?.length || props.rows.every((row) => !row.intervals.length);\n }\n return false;\n};\n\nconst Chart = (props: ChartProps): JSX.Element => {\n const [, drawingProps] = splitProps(props, [\"selected\", \"onSelect\", \"tooltip\", \"cursor\"]);\n const messages = useUiMessages();\n const chartMessages = useChartMessages();\n const viewportMessages = useViewportMessages();\n const locale = useLocale();\n let containerRef: HTMLDivElement | undefined;\n let chartTooltipRef: HTMLSpanElement | undefined;\n let lineAnchorRef: HTMLSpanElement | undefined;\n // One deterministic coordinate space on the server and client. CSS fits the\n // SVG to its box; hydration must never replace it with measured geometry.\n const size = () => ({\n width: 480,\n height: chartRenderHeight(props),\n });\n const dimensions = () => containerRef?.getBoundingClientRect() ?? size();\n const initialMapViewport = props.kind === \"map\" ? normalizeMapViewport(props.viewport) : DEFAULT_MAP_VIEWPORT;\n const [mapViewport, setMapViewport] = createSignal<MapViewport>(initialMapViewport);\n const initialTimelineViewport =\n props.kind === \"stateTimeline\" ? stateTimelineDomain(props.rows, props.domain) : ([0, 1] as StateTimelineDomain);\n const [timelineViewport, setTimelineViewport] = createSignal<StateTimelineDomain>(initialTimelineViewport);\n const [dragging, setDragging] = createSignal(false);\n const chartTooltipId = `k2b-chart-tooltip-${createUniqueId()}`;\n let timelineViewportLocallyChanged = false;\n let drag:\n | {\n pointerId: number;\n x: number;\n y: number;\n width: number;\n height: number;\n viewport: MapViewport;\n }\n | undefined;\n let timelineDrag:\n | {\n pointerId: number;\n x: number;\n width: number;\n viewport: StateTimelineDomain;\n }\n | undefined;\n let pointerFrame: number | undefined;\n let pendingPointer: { pointerId: number; clientX: number; clientY: number } | undefined;\n\n const interactiveMap = () => props.kind === \"map\" && props.interactive === true;\n const interactiveTimeline = () => props.kind === \"stateTimeline\" && props.interactive === true;\n const draggable = () => interactiveMap() || interactiveTimeline();\n const labels = () => props.labels ?? {};\n const accessibleName = () => {\n const override =\n props.kind === \"map\"\n ? labels().interactiveMap\n : props.kind === \"stateTimeline\"\n ? labels().interactiveTimeline\n : props.kind === \"line\"\n ? labels().interactiveLine\n : labels().interactiveChart;\n const title = \"title\" in props && typeof props.title === \"string\" && props.title.trim() ? props.title : undefined;\n const valueLabel = (props.kind === \"stat\" || props.kind === \"gauge\") && props.label?.trim() ? props.label : undefined;\n const fallback =\n props.kind === \"map\"\n ? chartMessages().interactiveMap\n : props.kind === \"stateTimeline\"\n ? chartMessages().interactiveTimeline\n : props.kind === \"line\"\n ? chartMessages().interactiveLineChart\n : chartMessages().interactiveChart;\n return override ?? title ?? valueLabel ?? fallback;\n };\n const timelineFullDomain = (): StateTimelineDomain =>\n props.kind === \"stateTimeline\" ? stateTimelineDomain(props.rows, props.domain) : [0, 1];\n\n createEffect(() => {\n if (props.kind === \"map\") {\n setMapViewport(normalizeMapViewport(props.viewport));\n }\n });\n\n createEffect(() => {\n if (props.kind === \"stateTimeline\" && !timelineViewportLocallyChanged) {\n setTimelineViewport(timelineFullDomain());\n }\n });\n\n const updateTimelineViewport = (update: (current: StateTimelineDomain) => StateTimelineDomain) => {\n timelineViewportLocallyChanged = true;\n setTimelineViewport(update);\n };\n\n const mapDimensions = () => {\n const viewportElement = containerRef?.querySelector<SVGSVGElement>(\".stdlib-chart-map-viewport\");\n const matrix = viewportElement?.getScreenCTM?.();\n const box = viewportElement?.viewBox?.baseVal;\n if (matrix && box?.width && box.height) {\n return { width: box.width * Math.hypot(matrix.a, matrix.b), height: box.height * Math.hypot(matrix.c, matrix.d) };\n }\n const rect = viewportElement?.getBoundingClientRect();\n if (rect && rect.width > 0 && rect.height > 0) {\n return { width: rect.width, height: rect.height };\n }\n return dimensions();\n };\n\n const zoom = (delta: number) => {\n closeChartTooltip();\n if (interactiveMap()) {\n setMapViewport((current) => zoomMapViewport(current, delta, props.kind === \"map\" ? props.zoomFocus : undefined));\n } else if (interactiveTimeline()) {\n updateTimelineViewport((current) => zoomStateTimelineViewport(current, timelineFullDomain(), delta));\n }\n };\n\n const reset = () => {\n closeChartTooltip();\n if (interactiveMap() && props.kind === \"map\") {\n setMapViewport(normalizeMapViewport(props.viewport));\n }\n if (interactiveTimeline()) {\n timelineViewportLocallyChanged = false;\n setTimelineViewport(timelineFullDomain());\n }\n };\n\n const handlePointerDown: JSX.EventHandlerUnion<HTMLDivElement, PointerEvent> = (event) => {\n inspection.down(event);\n if (!draggable() || event.button !== 0 || (event.target as Element).closest(\"button, a\")) {\n return;\n }\n closeChartTooltip();\n // The pointer's own pointerup or pointercancel ends the hold.\n suppressTextSelection(event.pointerId);\n if (interactiveTimeline()) {\n timelineDrag = {\n pointerId: event.pointerId,\n x: event.clientX,\n width: Math.max(1, event.currentTarget.getBoundingClientRect().width),\n viewport: timelineViewport(),\n };\n event.currentTarget.setPointerCapture(event.pointerId);\n setDragging(true);\n return;\n }\n const dimensions = mapDimensions();\n drag = {\n pointerId: event.pointerId,\n x: event.clientX,\n y: event.clientY,\n width: dimensions.width,\n height: dimensions.height,\n viewport: mapViewport(),\n };\n event.currentTarget.setPointerCapture(event.pointerId);\n setDragging(true);\n };\n\n const flushPointerMove = () => {\n if (pointerFrame !== undefined) {\n cancelAnimationFrame(pointerFrame);\n pointerFrame = undefined;\n }\n const sample = pendingPointer;\n pendingPointer = undefined;\n if (!sample) return;\n const start = timelineDrag ?? drag;\n if (start && Math.hypot(sample.clientX - start.x, sample.clientY - (\"y\" in start ? start.y : sample.clientY)) <= 6) return;\n const activeTimelineDrag = timelineDrag;\n if (activeTimelineDrag?.pointerId === sample.pointerId) {\n updateTimelineViewport(() =>\n panStateTimelineViewport(\n activeTimelineDrag.viewport,\n timelineFullDomain(),\n sample.clientX - activeTimelineDrag.x,\n activeTimelineDrag.width,\n ),\n );\n return;\n }\n if (!drag || drag.pointerId !== sample.pointerId) return;\n setMapViewport(panMapViewport(drag.viewport, sample.clientX - drag.x, sample.clientY - drag.y, drag.width, drag.height));\n };\n\n const handlePointerMove: JSX.EventHandlerUnion<HTMLDivElement, PointerEvent> = (event) => {\n inspection.move(event);\n if (timelineDrag?.pointerId !== event.pointerId && drag?.pointerId !== event.pointerId) return;\n pendingPointer = { pointerId: event.pointerId, clientX: event.clientX, clientY: event.clientY };\n if (pointerFrame !== undefined) return;\n pointerFrame = requestAnimationFrame(flushPointerMove);\n };\n\n const stopDragging: JSX.EventHandlerUnion<HTMLDivElement, PointerEvent> = (event) => {\n if (pendingPointer?.pointerId === event.pointerId) flushPointerMove();\n if (timelineDrag?.pointerId === event.pointerId) {\n if (event.currentTarget.hasPointerCapture(event.pointerId)) {\n event.currentTarget.releasePointerCapture(event.pointerId);\n }\n timelineDrag = undefined;\n setDragging(false);\n return;\n }\n if (!drag || drag.pointerId !== event.pointerId) return;\n if (event.currentTarget.hasPointerCapture(event.pointerId)) {\n event.currentTarget.releasePointerCapture(event.pointerId);\n }\n drag = undefined;\n setDragging(false);\n };\n\n const handleWheel: JSX.EventHandlerUnion<HTMLDivElement, WheelEvent> = (event) => {\n if (interactiveMap() && (event.ctrlKey || event.metaKey)) {\n event.preventDefault();\n zoom(event.deltaY < 0 ? 1 : -1);\n return;\n }\n if (!interactiveTimeline()) return;\n if (event.ctrlKey || event.metaKey) {\n event.preventDefault();\n const rect = event.currentTarget.getBoundingClientRect();\n const anchor = rect.width > 0 ? (event.clientX - rect.left) / rect.width : 0.5;\n updateTimelineViewport((current) => zoomStateTimelineViewport(current, timelineFullDomain(), event.deltaY < 0 ? 1 : -1, anchor));\n } else if (event.shiftKey) {\n event.preventDefault();\n updateTimelineViewport((current) =>\n panStateTimelineViewport(current, timelineFullDomain(), -event.deltaY, event.currentTarget.getBoundingClientRect().width),\n );\n }\n };\n\n const handleKeyDown: JSX.EventHandlerUnion<HTMLDivElement, KeyboardEvent> = (event) => {\n if (inspection.key(event)) return;\n if (!draggable() || event.target !== containerRef) return;\n if (event.key === \"+\" || event.key === \"=\") {\n event.preventDefault();\n zoom(1);\n return;\n }\n if (event.key === \"-\" || event.key === \"_\") {\n event.preventDefault();\n zoom(-1);\n return;\n }\n if (event.key === \"0\" || event.key === \"Home\") {\n event.preventDefault();\n reset();\n return;\n }\n if (interactiveTimeline() && (event.key === \"ArrowLeft\" || event.key === \"ArrowRight\")) {\n event.preventDefault();\n updateTimelineViewport((current) =>\n panStateTimelineViewport(\n current,\n timelineFullDomain(),\n event.key === \"ArrowLeft\" ? 80 : -80,\n event.currentTarget.getBoundingClientRect().width,\n ),\n );\n return;\n }\n const delta: readonly [number, number] | undefined = {\n ArrowLeft: [40, 0],\n ArrowRight: [-40, 0],\n ArrowUp: [0, 40],\n ArrowDown: [0, -40],\n }[event.key] as readonly [number, number] | undefined;\n if (!delta) return;\n event.preventDefault();\n const dimensions = mapDimensions();\n setMapViewport((current) => panMapViewport(current, delta[0], delta[1], dimensions.width, dimensions.height));\n };\n\n const inspection = createChartInspection({\n container: () => containerRef,\n cursor: () => props.cursor,\n tooltip: () => chartTooltipRef,\n anchor: () => lineAnchorRef,\n kind: () => props.kind,\n enabled: () => !isEmpty(props),\n select: (selection) => props.onSelect?.(selection),\n format: (selection) => {\n if (props.tooltip) return props.tooltip(selection);\n const fields = chartMessages().chartFields;\n const format = new Intl.NumberFormat(locale(), { maximumFractionDigits: 6 });\n return {\n title:\n selection.datum.label ??\n (selection.datum.seriesIndex !== undefined\n ? `${labels().series ?? chartMessages().series} ${selection.datum.seriesIndex + 1}`\n : undefined),\n rows: selection.datum.values.map((field) => ({\n label:\n selection.kind === \"line\" && field.key === \"y\"\n ? (selection.datum.label ?? labels().series ?? chartMessages().series)\n : fields({ key: field.key }),\n value:\n field.formatted ??\n (field.key === \"upperInclusive\"\n ? field.value === \"true\"\n ? messages().yes\n : messages().no\n : typeof field.value === \"number\"\n ? `${format.format(field.value)}${field.key === \"percent\" ? \"%\" : \"\"}`\n : field.value),\n })),\n };\n },\n });\n const closeChartTooltip = () => inspection.close();\n const svgMarkup = createMemo(() =>\n renderChartSvg(\n drawingProps,\n size().width,\n size().height,\n interactiveMap() ? mapViewport() : undefined,\n interactiveTimeline() ? timelineViewport() : undefined,\n ),\n );\n createEffect(() => {\n svgMarkup();\n inspection.invalidate();\n untrack(() => inspection.selectDatum(props.selected));\n });\n\n createEffect(() => inspection.selectDatum(props.selected));\n\n onCleanup(() => {\n inspection.close();\n if (pointerFrame !== undefined) cancelAnimationFrame(pointerFrame);\n pointerFrame = undefined;\n pendingPointer = undefined;\n });\n\n onMount(() => {\n if (!containerRef) return;\n onCleanup(\n closeChartInspectionOnOutside({\n container: () => containerRef,\n tooltip: () => chartTooltipRef,\n close: closeChartTooltip,\n }),\n );\n });\n\n const chartStyle = () =>\n props.style ??\n (props.kind === \"stateTimeline\"\n ? {\n height: `${stateTimelineHeight(props.rows.length, props.legend !== false)}px`,\n }\n : undefined);\n\n const control = (label: string, shortcut: string, icon: string, action: () => void) => (\n <IconButton variant=\"secondary\" label={label} tooltip={`${label} (${shortcut})`} onClick={action}>\n <i class={`ti ${icon}`} aria-hidden=\"true\" />\n </IconButton>\n );\n\n return (\n <Show\n when={!isEmpty(props)}\n fallback={\n <div ref={containerRef} class={`k2b-chart k2b-chart__empty ${props.class ?? \"\"}`} style={chartStyle()}>\n {labels().empty ?? messages().noData}\n </div>\n }\n >\n {/* CSS fits the server-rendered SVG to the caller's box. Only changes\n to chart data/options rebuild the SVG; resizing does not. */}\n <div\n ref={containerRef}\n class={`k2b-chart ${props.class ?? \"\"}`}\n data-chart-kind={props.kind}\n data-drag={draggable() ? (dragging() ? \"active\" : \"idle\") : undefined}\n data-crosshair={!draggable() && props.kind === \"line\" ? \"true\" : undefined}\n data-interactive=\"true\"\n style={chartStyle()}\n role=\"group\"\n aria-label={accessibleName()}\n aria-description={accessibleName() !== chartMessages().interactiveChart ? chartMessages().interactiveChart : undefined}\n tabIndex={0}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={stopDragging}\n onPointerCancel={stopDragging}\n onClick={inspection.click}\n onPointerLeave={inspection.leave}\n onFocusIn={inspection.focus}\n onFocusOut={closeChartTooltip}\n onWheel={handleWheel}\n onKeyDown={handleKeyDown}\n >\n <div\n class=\"k2b-chart__svg\"\n data-stretch={!preservesAspectRatio(props.kind) ? \"true\" : undefined}\n style={{\n \"--k2b-chart-width\": `${size().width}px`,\n \"--k2b-chart-height\": `${size().height}px`,\n \"aspect-ratio\": `${size().width} / ${size().height}`,\n }}\n innerHTML={isServer ? selectedChartSvg(svgMarkup(), props.selected) : svgMarkup()}\n />\n <span ref={lineAnchorRef} class=\"k2b-chart__anchor\" aria-hidden=\"true\" />\n <span\n id={chartTooltipId}\n ref={chartTooltipRef}\n role=\"tooltip\"\n popover=\"manual\"\n data-instant=\"true\"\n class=\"k2b-tooltip k2b-chart__tooltip\"\n />\n <Show when={draggable()}>\n <div class=\"k2b-chart__controls\">\n {control(labels().zoomIn ?? viewportMessages().zoomIn, \"+\", \"ti-plus\", () => zoom(1))}\n {control(labels().zoomOut ?? viewportMessages().zoomOut, \"-\", \"ti-minus\", () => zoom(-1))}\n {control(\n interactiveMap()\n ? (labels().resetMap ?? chartMessages().resetMapView)\n : (labels().resetTimeline ?? chartMessages().resetTimelineView),\n \"0\",\n \"ti-focus-centered\",\n reset,\n )}\n </div>\n </Show>\n </div>\n </Show>\n );\n};\n\nexport default Chart;\n"],"mappings":"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","ignoreList":[]}
@@ -6,7 +6,8 @@ import { escape as _$escape } from "solid-js/web";
6
6
  var _tmpl$ = ["<div class=\"k2b-chart\"", " data-interactive=\"true\" style=\"", "\" role=\"group\"", " tabindex=\"0\"><div class=\"k2b-chart__svg\"", " style=\"", "\">", "</div><span class=\"k2b-chart__anchor\" aria-hidden=\"true\"></span><span", " class=\"k2b-chart__tooltip k2b-tooltip\" role=\"tooltip\" popover=\"manual\" data-instant=\"true\"></span></div>"];
7
7
  import { createEffect, createUniqueId, onCleanup, onMount } from "solid-js";
8
8
  import { isServer } from "solid-js/web";
9
- import { createChartInspection, sameChartDatum } from "./chart-inspection";
9
+ import { createChartInspection } from "./chart-inspection";
10
+ import { closeChartInspectionOnOutside, sameChartDatum } from "./chart-inspection-core";
10
11
  import { useChartMessages } from "./chart-messages";
11
12
  import { selectedChartSvg } from "./chart-svg";
12
13
 
@@ -42,15 +43,11 @@ export function ChartSnapshotView(props) {
42
43
  });
43
44
  createEffect(() => inspection.selectData(props.snapshot.marks.filter(m => m.rowKey === props.selectedKey).map(m => m.datum)));
44
45
  onMount(() => {
45
- const outside = event => {
46
- if (event.target instanceof Node && !container?.contains(event.target)) inspection.close();
47
- };
48
- window.addEventListener("pointerdown", outside);
49
- window.addEventListener("scroll", inspection.close, true);
50
- onCleanup(() => {
51
- window.removeEventListener("pointerdown", outside);
52
- window.removeEventListener("scroll", inspection.close, true);
53
- });
46
+ onCleanup(closeChartInspectionOnOutside({
47
+ container: () => container,
48
+ tooltip: () => tooltip,
49
+ close: inspection.close
50
+ }));
54
51
  });
55
52
  onCleanup(inspection.close);
56
53
  return _$ssr(_tmpl$, _$ssrAttribute("data-chart-kind", _$escape(props.snapshot.kind, true), false), _$ssrStyle(props.style), _$ssrAttribute("aria-label", _$escape(chartMessages().interactiveChart, true), false), _$ssrAttribute("data-stretch", props.snapshot.stretch ? "true" : _$escape(undefined, true), false), _$ssrStyleProperty("--k2b-chart-width:", `${_$escape(props.snapshot.width, true)}px`) + _$ssrStyleProperty(";--k2b-chart-height:", `${_$escape(props.snapshot.height, true)}px`) + _$ssrStyleProperty(";aspect-ratio:", `${_$escape(props.snapshot.width, true)}/${_$escape(props.snapshot.height, true)}`), isServer ? selectedChartSvg(props.snapshot.svg, props.snapshot.marks.filter(m => m.rowKey === props.selectedKey).map(m => m.datum)) : props.snapshot.svg, _$ssrAttribute("id", _$escape(id, true), false));
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["content/ChartSnapshotView.tsx"],"sourcesContent":["import { createEffect, createUniqueId, type JSX, onCleanup, onMount } from \"solid-js\";\nimport { isServer } from \"solid-js/web\";\nimport type { ChartCursor } from \"./chart-cursor\";\nimport { createChartInspection, sameChartDatum } from \"./chart-inspection\";\nimport { useChartMessages } from \"./chart-messages\";\nimport type { ChartSnapshot } from \"./chart-snapshot\";\nimport { selectedChartSvg } from \"./chart-svg\";\n\n/** Internal display for server-prepared geometry. Viewports are snapshot-owned. */\nexport function ChartSnapshotView(props: {\n snapshot: ChartSnapshot;\n cursor?: ChartCursor;\n selectedKey: string | null;\n onSelect: (key: string) => void;\n style?: JSX.CSSProperties;\n}) {\n const chartMessages = useChartMessages();\n let container: HTMLDivElement | undefined;\n let tooltip: HTMLSpanElement | undefined;\n let anchor: HTMLSpanElement | undefined;\n const id = `k2b-chart-tooltip-${createUniqueId()}`;\n const inspection = createChartInspection({\n container: () => container,\n cursor: () => props.cursor,\n tooltip: () => tooltip,\n anchor: () => anchor,\n kind: () => props.snapshot.kind,\n enabled: () => true,\n format: ({ datum }) => props.snapshot.marks.find((m) => sameChartDatum(m.datum, datum))?.tooltip ?? { rows: [] },\n select: ({ datum }) => {\n const mark = props.snapshot.marks.find((m) => sameChartDatum(m.datum, datum));\n if (mark) props.onSelect(mark.rowKey);\n },\n });\n createEffect(() => {\n props.snapshot;\n inspection.invalidate();\n });\n createEffect(() => inspection.selectData(props.snapshot.marks.filter((m) => m.rowKey === props.selectedKey).map((m) => m.datum)));\n onMount(() => {\n const outside = (event: Event) => {\n if (event.target instanceof Node && !container?.contains(event.target)) inspection.close();\n };\n window.addEventListener(\"pointerdown\", outside);\n window.addEventListener(\"scroll\", inspection.close, true);\n onCleanup(() => {\n window.removeEventListener(\"pointerdown\", outside);\n window.removeEventListener(\"scroll\", inspection.close, true);\n });\n });\n onCleanup(inspection.close);\n return (\n <div\n ref={container}\n class=\"k2b-chart\"\n data-chart-kind={props.snapshot.kind}\n data-interactive=\"true\"\n style={props.style}\n role=\"group\"\n aria-label={chartMessages().interactiveChart}\n tabIndex={0}\n onPointerDown={inspection.down}\n onPointerMove={inspection.move}\n onClick={inspection.click}\n onPointerLeave={inspection.leave}\n onFocusIn={inspection.focus}\n onFocusOut={inspection.close}\n onKeyDown={inspection.key}\n >\n <div\n class=\"k2b-chart__svg\"\n data-stretch={props.snapshot.stretch ? \"true\" : undefined}\n style={{\n \"--k2b-chart-width\": `${props.snapshot.width}px`,\n \"--k2b-chart-height\": `${props.snapshot.height}px`,\n \"aspect-ratio\": `${props.snapshot.width}/${props.snapshot.height}`,\n }}\n innerHTML={\n isServer\n ? selectedChartSvg(\n props.snapshot.svg,\n props.snapshot.marks.filter((m) => m.rowKey === props.selectedKey).map((m) => m.datum),\n )\n : props.snapshot.svg\n }\n />\n <span ref={anchor} class=\"k2b-chart__anchor\" aria-hidden=\"true\" />\n <span ref={tooltip} id={id} class=\"k2b-chart__tooltip k2b-tooltip\" role=\"tooltip\" popover=\"manual\" data-instant=\"true\" />\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["content/ChartSnapshotView.tsx"],"sourcesContent":["import { createEffect, createUniqueId, type JSX, onCleanup, onMount } from \"solid-js\";\nimport { isServer } from \"solid-js/web\";\nimport type { ChartCursor } from \"./chart-cursor\";\nimport { createChartInspection } from \"./chart-inspection\";\nimport { closeChartInspectionOnOutside, sameChartDatum } from \"./chart-inspection-core\";\nimport { useChartMessages } from \"./chart-messages\";\nimport type { ChartSnapshot } from \"./chart-snapshot\";\nimport { selectedChartSvg } from \"./chart-svg\";\n\n/** Internal display for server-prepared geometry. Viewports are snapshot-owned. */\nexport function ChartSnapshotView(props: {\n snapshot: ChartSnapshot;\n cursor?: ChartCursor;\n selectedKey: string | null;\n onSelect: (key: string) => void;\n style?: JSX.CSSProperties;\n}) {\n const chartMessages = useChartMessages();\n let container: HTMLDivElement | undefined;\n let tooltip: HTMLSpanElement | undefined;\n let anchor: HTMLSpanElement | undefined;\n const id = `k2b-chart-tooltip-${createUniqueId()}`;\n const inspection = createChartInspection({\n container: () => container,\n cursor: () => props.cursor,\n tooltip: () => tooltip,\n anchor: () => anchor,\n kind: () => props.snapshot.kind,\n enabled: () => true,\n format: ({ datum }) => props.snapshot.marks.find((m) => sameChartDatum(m.datum, datum))?.tooltip ?? { rows: [] },\n select: ({ datum }) => {\n const mark = props.snapshot.marks.find((m) => sameChartDatum(m.datum, datum));\n if (mark) props.onSelect(mark.rowKey);\n },\n });\n createEffect(() => {\n props.snapshot;\n inspection.invalidate();\n });\n createEffect(() => inspection.selectData(props.snapshot.marks.filter((m) => m.rowKey === props.selectedKey).map((m) => m.datum)));\n onMount(() => {\n onCleanup(\n closeChartInspectionOnOutside({\n container: () => container,\n tooltip: () => tooltip,\n close: inspection.close,\n }),\n );\n });\n onCleanup(inspection.close);\n return (\n <div\n ref={container}\n class=\"k2b-chart\"\n data-chart-kind={props.snapshot.kind}\n data-interactive=\"true\"\n style={props.style}\n role=\"group\"\n aria-label={chartMessages().interactiveChart}\n tabIndex={0}\n onPointerDown={inspection.down}\n onPointerMove={inspection.move}\n onClick={inspection.click}\n onPointerLeave={inspection.leave}\n onFocusIn={inspection.focus}\n onFocusOut={inspection.close}\n onKeyDown={inspection.key}\n >\n <div\n class=\"k2b-chart__svg\"\n data-stretch={props.snapshot.stretch ? \"true\" : undefined}\n style={{\n \"--k2b-chart-width\": `${props.snapshot.width}px`,\n \"--k2b-chart-height\": `${props.snapshot.height}px`,\n \"aspect-ratio\": `${props.snapshot.width}/${props.snapshot.height}`,\n }}\n innerHTML={\n isServer\n ? selectedChartSvg(\n props.snapshot.svg,\n props.snapshot.marks.filter((m) => m.rowKey === props.selectedKey).map((m) => m.datum),\n )\n : props.snapshot.svg\n }\n />\n <span ref={anchor} class=\"k2b-chart__anchor\" aria-hidden=\"true\" />\n <span ref={tooltip} id={id} class=\"k2b-chart__tooltip k2b-tooltip\" role=\"tooltip\" popover=\"manual\" data-instant=\"true\" />\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -272,7 +272,7 @@ export function FileBrowserPanel(props) {
272
272
  },
273
273
  get children() {
274
274
  return _$createComponent(Placeholder, {
275
- icon: "ti ti-loader-2",
275
+ state: "loading",
276
276
  get title() {
277
277
  return fileBrowserMessages().loadingFiles;
278
278
  }
@@ -284,7 +284,7 @@ export function FileBrowserPanel(props) {
284
284
  },
285
285
  get children() {
286
286
  return _$createComponent(Placeholder, {
287
- icon: "ti ti-alert-circle",
287
+ state: "error",
288
288
  get title() {
289
289
  return fileInputMessages().failedLoadFiles;
290
290
  },
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["content/FileBrowser.tsx"],"sourcesContent":["/**\n * FileBrowser — FileTree + FileView over a FileSource adapter. One dialog\n * serves every file surface (conversation VFS, skills, later the Files app):\n * the source decides the capabilities, optional methods enable the matching\n * UI (write → edit/save, remove → delete, rename → rename, upload → upload).\n * Fixed-height IDE-style layout: both panes scroll, the shell never jumps.\n */\nimport { createZip, downloadFileFromContent } from \"@k2b/stdlib/browser\";\nimport { mutation } from \"@k2b/stdlib/solid\";\nimport { createEffect, createMemo, createResource, createSignal, Match, onCleanup, Show, Switch, untrack } from \"solid-js\";\nimport Dropdown from \"../actions/Dropdown\";\nimport { dialogCore } from \"../feedback/dialog-core\";\nimport { prompts } from \"../feedback/prompts\";\nimport { useFileInputMessages } from \"../inputs/file-input-messages\";\nimport { useUiMessages } from \"../intl/messages\";\nimport PanelDialog, { panelDialogOptions } from \"../layout/PanelDialog\";\nimport Placeholder from \"../surfaces/Placeholder\";\nimport FileTree, { type FileTreeEntry } from \"./FileTree\";\nimport FileView, { type FileViewContent, type FileViewRenderer } from \"./FileView\";\nimport { resolveFileBrowserMessages, useFileBrowserMessages } from \"./file-browser-messages\";\n\nexport type FileSource = {\n previewPreferencesKey?: string;\n list(): Promise<FileTreeEntry[]>;\n read(path: string): Promise<FileViewContent>;\n write?(path: string, content: string, encoding?: \"utf8\" | \"base64\"): Promise<void>;\n remove?(path: string): Promise<void>;\n rename?(from: string, to: string): Promise<void>;\n upload?(dirPath: string, files: File[]): Promise<void>;\n downloadHref?(path: string): string | null;\n /** Paths matching this predicate stay read-only even when the source can write (e.g. /input). */\n isReadOnly?(path: string): boolean;\n};\n\nexport type FileBrowserPanelProps = {\n source: FileSource;\n /** Hide every mutating affordance while retaining file selection and downloads. */\n readOnly?: boolean;\n /** Refetch entries when this host-controlled value changes. */\n refreshKey?: unknown;\n /** Preselect a file once entries are loaded. */\n initialPath?: string;\n /** Mirrors file selection into route state when the host needs durable navigation. */\n onSelectedPathChange?: (path: string | null) => void;\n /** Per-instance preview extensions forwarded to FileView. */\n renderers?: readonly FileViewRenderer[];\n /** Optional host copy/policy for leaving an unsaved file. */\n confirmDiscard?: (path: string, nextPath: string | null) => boolean | Promise<boolean>;\n /** Fixed shell height — the panes scroll inside it. */\n class?: string;\n /** Optional imperative refresh used by realtime owners that must await the visible update. */\n registerRefresh?: (refresh: () => Promise<void>) => void | (() => void);\n};\n\nconst parentOf = (path: string): string => {\n const index = path.lastIndexOf(\"/\");\n return index <= 0 ? \"/\" : path.slice(0, index);\n};\n\nexport function FileBrowserPanel(props: FileBrowserPanelProps) {\n const messages = useUiMessages();\n const fileBrowserMessages = useFileBrowserMessages();\n const fileInputMessages = useFileInputMessages();\n // FileSource is an imperative adapter. Its methods may read host signals,\n // but refreshes stay owned by this component (`refetch` / `refreshKey`);\n // tracking those implementation details can otherwise feed a write back\n // into its own list request indefinitely.\n const [entries, { refetch }] = createResource(async () => untrack(() => props.source.list()));\n const [selectedPath, setSelectedPath] = createSignal<string | null>(props.initialPath ?? null);\n const [selectedDirty, setSelectedDirty] = createSignal(false);\n // Folders exist implicitly through file paths — freshly created (still empty)\n // ones live here until their first file makes them real.\n const [pendingFolders, setPendingFolders] = createSignal<string[]>([]);\n let uploadInputRef: HTMLInputElement | undefined;\n let uploadDir = \"/\";\n let previousRefreshKey = props.refreshKey;\n let refreshPreview = async (): Promise<void> => undefined;\n\n createEffect(() => {\n if (!props.registerRefresh) return;\n const unregister = props.registerRefresh(async () => {\n await Promise.all([refetch(), refreshPreview()]);\n });\n if (unregister) onCleanup(unregister);\n });\n\n createEffect(() => {\n const next = props.initialPath ?? null;\n if (!selectedDirty() && next !== selectedPath()) setSelectedPath(next);\n });\n createEffect(() => props.onSelectedPathChange?.(selectedPath()));\n createEffect(() => {\n const refreshKey = props.refreshKey;\n if (Object.is(refreshKey, previousRefreshKey)) return;\n previousRefreshKey = refreshKey;\n void refetch();\n });\n\n const allEntries = createMemo<FileTreeEntry[]>(() => {\n const loaded = entries() ?? [];\n const real = new Set(loaded.map((entry) => entry.path));\n return [\n ...loaded,\n ...pendingFolders()\n .filter((path) => !real.has(path))\n .map((path) => ({ path, kind: \"folder\" as const })),\n ];\n });\n const selectedEntry = createMemo(() => allEntries().find((entry) => entry.path === selectedPath()) ?? null);\n const fileMutation = mutation.create<void, () => Promise<void>>({\n mutation: (work) => work(),\n onSuccess: () => void refetch(),\n onError: (error) => void prompts.error(error.message),\n });\n const pathMutable = (path: string) => !fileMutation.loading() && !props.readOnly && !props.source.isReadOnly?.(path);\n const pathWritable = (path: string) => pathMutable(path) && Boolean(props.source.write);\n const run = (work: () => Promise<void>) => void fileMutation.mutate(work);\n const canLeaveCurrent = async (nextPath: string | null): Promise<boolean> => {\n const current = selectedPath();\n if (nextPath === current || !selectedDirty() || !current) return true;\n if (selectedDirty() && current) {\n const confirmed = props.confirmDiscard\n ? await props.confirmDiscard(current, nextPath)\n : await prompts.confirm(fileBrowserMessages().discardUnsavedFile, {\n title: fileBrowserMessages().discardChanges,\n variant: \"danger\",\n });\n if (!confirmed) return false;\n }\n return true;\n };\n const selectPath = async (nextPath: string | null) => {\n if (!(await canLeaveCurrent(nextPath))) return;\n setSelectedDirty(false);\n setSelectedPath(nextPath);\n };\n\n const removeFile = (path: string) =>\n run(async () => {\n const confirmed = await prompts.confirm(`Delete ${path}?`, { title: \"Delete file\", variant: \"danger\" });\n if (!confirmed) return;\n await props.source.remove!(path);\n setPendingFolders((folders) => folders.filter((candidate) => candidate !== path && !candidate.startsWith(`${path}/`)));\n const selected = selectedPath();\n if (selected === path || selected?.startsWith(`${path}/`)) setSelectedPath(null);\n });\n\n const renameFile = (path: string, nextName: string) =>\n run(async () => {\n const target = `${parentOf(path) === \"/\" ? \"\" : parentOf(path)}/${nextName}`;\n await props.source.rename!(path, target);\n if (selectedPath() === path) setSelectedPath(target);\n });\n\n const createFile = (dirPath: string) =>\n run(async () => {\n const name = await prompts.prompt(fileBrowserMessages().newFileName, \"\", { title: fileBrowserMessages().newFile });\n if (!name || typeof name !== \"string\" || !name.trim() || name.includes(\"/\")) return;\n const path = `${dirPath === \"/\" ? \"\" : dirPath}/${name.trim()}`;\n if (!(await canLeaveCurrent(path))) return;\n await props.source.write!(path, \"\");\n setSelectedDirty(false);\n setSelectedPath(path);\n });\n\n const createFolder = (dirPath: string) =>\n void (async () => {\n const name = await prompts.prompt(fileBrowserMessages().newFolderName, \"\", { title: fileBrowserMessages().newFolder });\n if (!name || typeof name !== \"string\" || !name.trim() || name.includes(\"/\")) return;\n const path = `${dirPath === \"/\" ? \"\" : dirPath}/${name.trim()}`;\n setPendingFolders((folders) => [...folders, path]);\n })();\n\n const pickUpload = (dirPath: string) => {\n uploadDir = dirPath;\n uploadInputRef?.click();\n };\n\n const onUploadPicked = (input: HTMLInputElement) => {\n const files = Array.from(input.files ?? []);\n input.value = \"\";\n if (files.length > 0) run(() => props.source.upload!(uploadDir, files));\n };\n\n const baseName = (path: string) => path.slice(path.lastIndexOf(\"/\") + 1);\n\n /** Concrete file paths behind an entry: the file itself, or everything under a folder. */\n const filesBehind = (path: string): string[] => {\n const list = entries() ?? [];\n if (list.some((entry) => entry.path === path && entry.kind !== \"folder\")) return [path];\n const prefix = `${path}/`;\n return list.filter((entry) => entry.path.startsWith(prefix) && entry.kind !== \"folder\").map((entry) => entry.path);\n };\n\n /** Move a file OR a whole folder subtree (per-file renames preserve the structure). */\n const moveEntry = (path: string, targetDir: string) =>\n run(async () => {\n const destBase = `${targetDir === \"/\" ? \"\" : targetDir}/${baseName(path)}`;\n const files = filesBehind(path);\n if (files.length === 0) {\n // Still-empty pending folder — relocating it is a purely local affair.\n setPendingFolders((folders) => folders.map((candidate) => (candidate === path ? destBase : candidate)));\n return;\n }\n for (const file of files) {\n await props.source.rename!(file, `${destBase}${file.slice(path.length)}`);\n }\n const selected = selectedPath();\n if (selected && (selected === path || selected.startsWith(`${path}/`))) {\n setSelectedPath(`${destBase}${selected.slice(path.length)}`);\n }\n });\n\n const contentBytes = async (path: string): Promise<Uint8Array> => {\n const content = await props.source.read(path);\n return content.encoding === \"utf8\"\n ? new TextEncoder().encode(content.content)\n : Uint8Array.from(atob(content.content), (char) => char.charCodeAt(0));\n };\n\n const downloadEntry = (path: string, isFolder: boolean) =>\n void (async () => {\n try {\n if (!isFolder) {\n const href = props.source.downloadHref?.(path);\n if (href) {\n const anchor = document.createElement(\"a\");\n anchor.href = href;\n anchor.download = baseName(path);\n anchor.click();\n return;\n }\n const content = await props.source.read(path);\n downloadFileFromContent(await contentBytes(path), baseName(path), content.mediaType || \"application/octet-stream\");\n return;\n }\n const files = filesBehind(path);\n if (files.length === 0) throw new Error(fileBrowserMessages().folderEmpty);\n const zipEntries = await Promise.all(\n files.map(async (file) => ({ filename: file.slice(path.length + 1), source: await contentBytes(file) })),\n );\n downloadFileFromContent(await createZip(zipEntries), `${baseName(path) || \"files\"}.zip`, \"application/zip\");\n } catch (error) {\n void prompts.error(error instanceof Error ? error.message : fileBrowserMessages().downloadFailed);\n }\n })();\n\n const treeActions = () => ({\n ...(!props.readOnly && props.source.rename\n ? { rename: (path: string, next: string) => (pathMutable(path) ? renameFile(path, next) : undefined) }\n : {}),\n ...(!props.readOnly && props.source.remove ? { remove: (path: string) => (pathMutable(path) ? removeFile(path) : undefined) } : {}),\n ...(!props.readOnly && props.source.write ? { createFile: (dir: string) => (pathWritable(dir) ? createFile(dir) : undefined) } : {}),\n ...(!props.readOnly && props.source.write\n ? { createFolder: (dir: string) => (pathWritable(dir) ? createFolder(dir) : undefined) }\n : {}),\n ...(!props.readOnly && props.source.rename\n ? { move: (path: string, dir: string) => (pathMutable(path) && pathMutable(dir) ? moveEntry(path, dir) : undefined) }\n : {}),\n download: (path: string, isFolder: boolean) => downloadEntry(path, isFolder),\n });\n\n const addMenuItems = () => [\n ...(pathWritable(\"/\") ? [{ icon: \"ti ti-file-plus\", label: fileBrowserMessages().newFile, action: () => createFile(\"/\") }] : []),\n ...(pathWritable(\"/\") ? [{ icon: \"ti ti-folder-plus\", label: fileBrowserMessages().newFolder, action: () => createFolder(\"/\") }] : []),\n ...(pathMutable(\"/\") && props.source.upload\n ? [{ icon: \"ti ti-upload\", label: fileBrowserMessages().uploadFiles, action: () => pickUpload(\"/\") }]\n : []),\n ];\n\n return (\n <div class={`k2b-content-file-browser ${props.class ?? \"\"}`} data-default-height={props.class ? undefined : \"true\"}>\n <div class=\"k2b-content-file-browser__sidebar\">\n <div class=\"k2b-content-file-browser__header\">\n <p class=\"k2b-content-file-browser__title\">{fileBrowserMessages().files}</p>\n <Show when={addMenuItems().length > 0}>\n <Dropdown.Root position=\"bottom-left\" items={addMenuItems()} label={fileBrowserMessages().addFileFolderUpload}>\n <Dropdown.Trigger\n appearance=\"plain\"\n class=\"k2b-content-file-browser__add\"\n label={fileBrowserMessages().addFileFolderUpload}\n tooltip={messages().add}\n >\n <i class=\"ti ti-plus\" aria-hidden=\"true\" />\n <span class=\"k2b-sr-only\">{fileBrowserMessages().addFileFolderUpload}</span>\n </Dropdown.Trigger>\n </Dropdown.Root>\n </Show>\n </div>\n <Switch>\n <Match when={entries.loading && entries() === undefined}>\n <Placeholder icon=\"ti ti-loader-2\" title={fileBrowserMessages().loadingFiles} />\n </Match>\n <Match when={entries.error}>\n <Placeholder\n icon=\"ti ti-alert-circle\"\n title={fileInputMessages().failedLoadFiles}\n description={String(entries.error?.message ?? entries.error ?? \"\")}\n />\n </Match>\n <Match when={allEntries().length > 0}>\n <FileTree\n class=\"k2b-content-file-browser__tree\"\n entries={allEntries()}\n selectedPath={selectedPath()}\n onSelect={(entry) => void selectPath(entry.path)}\n actions={treeActions()}\n />\n </Match>\n <Match when={true}>\n <Placeholder icon=\"ti ti-folder-open\" title={fileBrowserMessages().noFiles} description={fileBrowserMessages().spaceEmpty} />\n </Match>\n </Switch>\n <input\n ref={uploadInputRef}\n type=\"file\"\n multiple\n class=\"k2b-content-file-browser__upload\"\n onChange={(event) => onUploadPicked(event.currentTarget)}\n />\n </div>\n\n <Switch\n fallback={\n <Placeholder icon=\"ti ti-file\" title={fileBrowserMessages().selectFile} description={fileBrowserMessages().pickFileFromTree} />\n }\n >\n <Match when={selectedEntry()?.kind === \"folder\"}>\n <Placeholder\n icon=\"ti ti-folder\"\n title={fileBrowserMessages().folderSelected}\n description={fileBrowserMessages().chooseFileToPreview}\n />\n </Match>\n <Match when={selectedEntry()}>\n {(entry) => (\n <FileView\n previewPreferencesKey={props.source.previewPreferencesKey}\n file={{ path: entry().path, mediaType: entry().mediaType, size: entry().size }}\n load={() => props.source.read(entry().path)}\n revision={props.refreshKey}\n registerRefresh={(refresh) => {\n refreshPreview = refresh;\n return () => {\n refreshPreview = async () => undefined;\n };\n }}\n renderers={props.renderers}\n onDirtyChange={setSelectedDirty}\n save={\n pathWritable(entry().path)\n ? async (content) => {\n await props.source.write!(entry().path, content);\n await refetch();\n }\n : undefined\n }\n downloadHref={props.source.downloadHref?.(entry().path) ?? null}\n />\n )}\n </Match>\n </Switch>\n </div>\n );\n}\n\n/** Open the file browser as a dialog. Returns when the dialog closes. */\nexport const openFileBrowser = (options: { source: FileSource; title?: string; subtitle?: string; icon?: string }): Promise<void> => {\n const fileBrowserMessages = resolveFileBrowserMessages();\n return dialogCore.open<void>(\n (close) => (\n <PanelDialog>\n <PanelDialog.Header\n title={options.title ?? fileBrowserMessages.files}\n subtitle={options.subtitle}\n icon={options.icon ?? \"ti ti-folder\"}\n close={() => close()}\n />\n <PanelDialog.Body>\n <FileBrowserPanel source={options.source} />\n </PanelDialog.Body>\n </PanelDialog>\n ),\n panelDialogOptions,\n );\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["content/FileBrowser.tsx"],"sourcesContent":["/**\n * FileBrowser — FileTree + FileView over a FileSource adapter. One dialog\n * serves every file surface (conversation VFS, skills, later the Files app):\n * the source decides the capabilities, optional methods enable the matching\n * UI (write → edit/save, remove → delete, rename → rename, upload → upload).\n * Fixed-height IDE-style layout: both panes scroll, the shell never jumps.\n */\nimport { createZip, downloadFileFromContent } from \"@k2b/stdlib/browser\";\nimport { mutation } from \"@k2b/stdlib/solid\";\nimport { createEffect, createMemo, createResource, createSignal, Match, onCleanup, Show, Switch, untrack } from \"solid-js\";\nimport Dropdown from \"../actions/Dropdown\";\nimport { dialogCore } from \"../feedback/dialog-core\";\nimport { prompts } from \"../feedback/prompts\";\nimport { useFileInputMessages } from \"../inputs/file-input-messages\";\nimport { useUiMessages } from \"../intl/messages\";\nimport PanelDialog, { panelDialogOptions } from \"../layout/PanelDialog\";\nimport Placeholder from \"../surfaces/Placeholder\";\nimport FileTree, { type FileTreeEntry } from \"./FileTree\";\nimport FileView, { type FileViewContent, type FileViewRenderer } from \"./FileView\";\nimport { resolveFileBrowserMessages, useFileBrowserMessages } from \"./file-browser-messages\";\n\nexport type FileSource = {\n previewPreferencesKey?: string;\n list(): Promise<FileTreeEntry[]>;\n read(path: string): Promise<FileViewContent>;\n write?(path: string, content: string, encoding?: \"utf8\" | \"base64\"): Promise<void>;\n remove?(path: string): Promise<void>;\n rename?(from: string, to: string): Promise<void>;\n upload?(dirPath: string, files: File[]): Promise<void>;\n downloadHref?(path: string): string | null;\n /** Paths matching this predicate stay read-only even when the source can write (e.g. /input). */\n isReadOnly?(path: string): boolean;\n};\n\nexport type FileBrowserPanelProps = {\n source: FileSource;\n /** Hide every mutating affordance while retaining file selection and downloads. */\n readOnly?: boolean;\n /** Refetch entries when this host-controlled value changes. */\n refreshKey?: unknown;\n /** Preselect a file once entries are loaded. */\n initialPath?: string;\n /** Mirrors file selection into route state when the host needs durable navigation. */\n onSelectedPathChange?: (path: string | null) => void;\n /** Per-instance preview extensions forwarded to FileView. */\n renderers?: readonly FileViewRenderer[];\n /** Optional host copy/policy for leaving an unsaved file. */\n confirmDiscard?: (path: string, nextPath: string | null) => boolean | Promise<boolean>;\n /** Fixed shell height — the panes scroll inside it. */\n class?: string;\n /** Optional imperative refresh used by realtime owners that must await the visible update. */\n registerRefresh?: (refresh: () => Promise<void>) => void | (() => void);\n};\n\nconst parentOf = (path: string): string => {\n const index = path.lastIndexOf(\"/\");\n return index <= 0 ? \"/\" : path.slice(0, index);\n};\n\nexport function FileBrowserPanel(props: FileBrowserPanelProps) {\n const messages = useUiMessages();\n const fileBrowserMessages = useFileBrowserMessages();\n const fileInputMessages = useFileInputMessages();\n // FileSource is an imperative adapter. Its methods may read host signals,\n // but refreshes stay owned by this component (`refetch` / `refreshKey`);\n // tracking those implementation details can otherwise feed a write back\n // into its own list request indefinitely.\n const [entries, { refetch }] = createResource(async () => untrack(() => props.source.list()));\n const [selectedPath, setSelectedPath] = createSignal<string | null>(props.initialPath ?? null);\n const [selectedDirty, setSelectedDirty] = createSignal(false);\n // Folders exist implicitly through file paths — freshly created (still empty)\n // ones live here until their first file makes them real.\n const [pendingFolders, setPendingFolders] = createSignal<string[]>([]);\n let uploadInputRef: HTMLInputElement | undefined;\n let uploadDir = \"/\";\n let previousRefreshKey = props.refreshKey;\n let refreshPreview = async (): Promise<void> => undefined;\n\n createEffect(() => {\n if (!props.registerRefresh) return;\n const unregister = props.registerRefresh(async () => {\n await Promise.all([refetch(), refreshPreview()]);\n });\n if (unregister) onCleanup(unregister);\n });\n\n createEffect(() => {\n const next = props.initialPath ?? null;\n if (!selectedDirty() && next !== selectedPath()) setSelectedPath(next);\n });\n createEffect(() => props.onSelectedPathChange?.(selectedPath()));\n createEffect(() => {\n const refreshKey = props.refreshKey;\n if (Object.is(refreshKey, previousRefreshKey)) return;\n previousRefreshKey = refreshKey;\n void refetch();\n });\n\n const allEntries = createMemo<FileTreeEntry[]>(() => {\n const loaded = entries() ?? [];\n const real = new Set(loaded.map((entry) => entry.path));\n return [\n ...loaded,\n ...pendingFolders()\n .filter((path) => !real.has(path))\n .map((path) => ({ path, kind: \"folder\" as const })),\n ];\n });\n const selectedEntry = createMemo(() => allEntries().find((entry) => entry.path === selectedPath()) ?? null);\n const fileMutation = mutation.create<void, () => Promise<void>>({\n mutation: (work) => work(),\n onSuccess: () => void refetch(),\n onError: (error) => void prompts.error(error.message),\n });\n const pathMutable = (path: string) => !fileMutation.loading() && !props.readOnly && !props.source.isReadOnly?.(path);\n const pathWritable = (path: string) => pathMutable(path) && Boolean(props.source.write);\n const run = (work: () => Promise<void>) => void fileMutation.mutate(work);\n const canLeaveCurrent = async (nextPath: string | null): Promise<boolean> => {\n const current = selectedPath();\n if (nextPath === current || !selectedDirty() || !current) return true;\n if (selectedDirty() && current) {\n const confirmed = props.confirmDiscard\n ? await props.confirmDiscard(current, nextPath)\n : await prompts.confirm(fileBrowserMessages().discardUnsavedFile, {\n title: fileBrowserMessages().discardChanges,\n variant: \"danger\",\n });\n if (!confirmed) return false;\n }\n return true;\n };\n const selectPath = async (nextPath: string | null) => {\n if (!(await canLeaveCurrent(nextPath))) return;\n setSelectedDirty(false);\n setSelectedPath(nextPath);\n };\n\n const removeFile = (path: string) =>\n run(async () => {\n const confirmed = await prompts.confirm(`Delete ${path}?`, { title: \"Delete file\", variant: \"danger\" });\n if (!confirmed) return;\n await props.source.remove!(path);\n setPendingFolders((folders) => folders.filter((candidate) => candidate !== path && !candidate.startsWith(`${path}/`)));\n const selected = selectedPath();\n if (selected === path || selected?.startsWith(`${path}/`)) setSelectedPath(null);\n });\n\n const renameFile = (path: string, nextName: string) =>\n run(async () => {\n const target = `${parentOf(path) === \"/\" ? \"\" : parentOf(path)}/${nextName}`;\n await props.source.rename!(path, target);\n if (selectedPath() === path) setSelectedPath(target);\n });\n\n const createFile = (dirPath: string) =>\n run(async () => {\n const name = await prompts.prompt(fileBrowserMessages().newFileName, \"\", { title: fileBrowserMessages().newFile });\n if (!name || typeof name !== \"string\" || !name.trim() || name.includes(\"/\")) return;\n const path = `${dirPath === \"/\" ? \"\" : dirPath}/${name.trim()}`;\n if (!(await canLeaveCurrent(path))) return;\n await props.source.write!(path, \"\");\n setSelectedDirty(false);\n setSelectedPath(path);\n });\n\n const createFolder = (dirPath: string) =>\n void (async () => {\n const name = await prompts.prompt(fileBrowserMessages().newFolderName, \"\", { title: fileBrowserMessages().newFolder });\n if (!name || typeof name !== \"string\" || !name.trim() || name.includes(\"/\")) return;\n const path = `${dirPath === \"/\" ? \"\" : dirPath}/${name.trim()}`;\n setPendingFolders((folders) => [...folders, path]);\n })();\n\n const pickUpload = (dirPath: string) => {\n uploadDir = dirPath;\n uploadInputRef?.click();\n };\n\n const onUploadPicked = (input: HTMLInputElement) => {\n const files = Array.from(input.files ?? []);\n input.value = \"\";\n if (files.length > 0) run(() => props.source.upload!(uploadDir, files));\n };\n\n const baseName = (path: string) => path.slice(path.lastIndexOf(\"/\") + 1);\n\n /** Concrete file paths behind an entry: the file itself, or everything under a folder. */\n const filesBehind = (path: string): string[] => {\n const list = entries() ?? [];\n if (list.some((entry) => entry.path === path && entry.kind !== \"folder\")) return [path];\n const prefix = `${path}/`;\n return list.filter((entry) => entry.path.startsWith(prefix) && entry.kind !== \"folder\").map((entry) => entry.path);\n };\n\n /** Move a file OR a whole folder subtree (per-file renames preserve the structure). */\n const moveEntry = (path: string, targetDir: string) =>\n run(async () => {\n const destBase = `${targetDir === \"/\" ? \"\" : targetDir}/${baseName(path)}`;\n const files = filesBehind(path);\n if (files.length === 0) {\n // Still-empty pending folder — relocating it is a purely local affair.\n setPendingFolders((folders) => folders.map((candidate) => (candidate === path ? destBase : candidate)));\n return;\n }\n for (const file of files) {\n await props.source.rename!(file, `${destBase}${file.slice(path.length)}`);\n }\n const selected = selectedPath();\n if (selected && (selected === path || selected.startsWith(`${path}/`))) {\n setSelectedPath(`${destBase}${selected.slice(path.length)}`);\n }\n });\n\n const contentBytes = async (path: string): Promise<Uint8Array> => {\n const content = await props.source.read(path);\n return content.encoding === \"utf8\"\n ? new TextEncoder().encode(content.content)\n : Uint8Array.from(atob(content.content), (char) => char.charCodeAt(0));\n };\n\n const downloadEntry = (path: string, isFolder: boolean) =>\n void (async () => {\n try {\n if (!isFolder) {\n const href = props.source.downloadHref?.(path);\n if (href) {\n const anchor = document.createElement(\"a\");\n anchor.href = href;\n anchor.download = baseName(path);\n anchor.click();\n return;\n }\n const content = await props.source.read(path);\n downloadFileFromContent(await contentBytes(path), baseName(path), content.mediaType || \"application/octet-stream\");\n return;\n }\n const files = filesBehind(path);\n if (files.length === 0) throw new Error(fileBrowserMessages().folderEmpty);\n const zipEntries = await Promise.all(\n files.map(async (file) => ({ filename: file.slice(path.length + 1), source: await contentBytes(file) })),\n );\n downloadFileFromContent(await createZip(zipEntries), `${baseName(path) || \"files\"}.zip`, \"application/zip\");\n } catch (error) {\n void prompts.error(error instanceof Error ? error.message : fileBrowserMessages().downloadFailed);\n }\n })();\n\n const treeActions = () => ({\n ...(!props.readOnly && props.source.rename\n ? { rename: (path: string, next: string) => (pathMutable(path) ? renameFile(path, next) : undefined) }\n : {}),\n ...(!props.readOnly && props.source.remove ? { remove: (path: string) => (pathMutable(path) ? removeFile(path) : undefined) } : {}),\n ...(!props.readOnly && props.source.write ? { createFile: (dir: string) => (pathWritable(dir) ? createFile(dir) : undefined) } : {}),\n ...(!props.readOnly && props.source.write\n ? { createFolder: (dir: string) => (pathWritable(dir) ? createFolder(dir) : undefined) }\n : {}),\n ...(!props.readOnly && props.source.rename\n ? { move: (path: string, dir: string) => (pathMutable(path) && pathMutable(dir) ? moveEntry(path, dir) : undefined) }\n : {}),\n download: (path: string, isFolder: boolean) => downloadEntry(path, isFolder),\n });\n\n const addMenuItems = () => [\n ...(pathWritable(\"/\") ? [{ icon: \"ti ti-file-plus\", label: fileBrowserMessages().newFile, action: () => createFile(\"/\") }] : []),\n ...(pathWritable(\"/\") ? [{ icon: \"ti ti-folder-plus\", label: fileBrowserMessages().newFolder, action: () => createFolder(\"/\") }] : []),\n ...(pathMutable(\"/\") && props.source.upload\n ? [{ icon: \"ti ti-upload\", label: fileBrowserMessages().uploadFiles, action: () => pickUpload(\"/\") }]\n : []),\n ];\n\n return (\n <div class={`k2b-content-file-browser ${props.class ?? \"\"}`} data-default-height={props.class ? undefined : \"true\"}>\n <div class=\"k2b-content-file-browser__sidebar\">\n <div class=\"k2b-content-file-browser__header\">\n <p class=\"k2b-content-file-browser__title\">{fileBrowserMessages().files}</p>\n <Show when={addMenuItems().length > 0}>\n <Dropdown.Root position=\"bottom-left\" items={addMenuItems()} label={fileBrowserMessages().addFileFolderUpload}>\n <Dropdown.Trigger\n appearance=\"plain\"\n class=\"k2b-content-file-browser__add\"\n label={fileBrowserMessages().addFileFolderUpload}\n tooltip={messages().add}\n >\n <i class=\"ti ti-plus\" aria-hidden=\"true\" />\n <span class=\"k2b-sr-only\">{fileBrowserMessages().addFileFolderUpload}</span>\n </Dropdown.Trigger>\n </Dropdown.Root>\n </Show>\n </div>\n <Switch>\n <Match when={entries.loading && entries() === undefined}>\n <Placeholder state=\"loading\" title={fileBrowserMessages().loadingFiles} />\n </Match>\n <Match when={entries.error}>\n <Placeholder\n state=\"error\"\n title={fileInputMessages().failedLoadFiles}\n description={String(entries.error?.message ?? entries.error ?? \"\")}\n />\n </Match>\n <Match when={allEntries().length > 0}>\n <FileTree\n class=\"k2b-content-file-browser__tree\"\n entries={allEntries()}\n selectedPath={selectedPath()}\n onSelect={(entry) => void selectPath(entry.path)}\n actions={treeActions()}\n />\n </Match>\n <Match when={true}>\n <Placeholder icon=\"ti ti-folder-open\" title={fileBrowserMessages().noFiles} description={fileBrowserMessages().spaceEmpty} />\n </Match>\n </Switch>\n <input\n ref={uploadInputRef}\n type=\"file\"\n multiple\n class=\"k2b-content-file-browser__upload\"\n onChange={(event) => onUploadPicked(event.currentTarget)}\n />\n </div>\n\n <Switch\n fallback={\n <Placeholder icon=\"ti ti-file\" title={fileBrowserMessages().selectFile} description={fileBrowserMessages().pickFileFromTree} />\n }\n >\n <Match when={selectedEntry()?.kind === \"folder\"}>\n <Placeholder\n icon=\"ti ti-folder\"\n title={fileBrowserMessages().folderSelected}\n description={fileBrowserMessages().chooseFileToPreview}\n />\n </Match>\n <Match when={selectedEntry()}>\n {(entry) => (\n <FileView\n previewPreferencesKey={props.source.previewPreferencesKey}\n file={{ path: entry().path, mediaType: entry().mediaType, size: entry().size }}\n load={() => props.source.read(entry().path)}\n revision={props.refreshKey}\n registerRefresh={(refresh) => {\n refreshPreview = refresh;\n return () => {\n refreshPreview = async () => undefined;\n };\n }}\n renderers={props.renderers}\n onDirtyChange={setSelectedDirty}\n save={\n pathWritable(entry().path)\n ? async (content) => {\n await props.source.write!(entry().path, content);\n await refetch();\n }\n : undefined\n }\n downloadHref={props.source.downloadHref?.(entry().path) ?? null}\n />\n )}\n </Match>\n </Switch>\n </div>\n );\n}\n\n/** Open the file browser as a dialog. Returns when the dialog closes. */\nexport const openFileBrowser = (options: { source: FileSource; title?: string; subtitle?: string; icon?: string }): Promise<void> => {\n const fileBrowserMessages = resolveFileBrowserMessages();\n return dialogCore.open<void>(\n (close) => (\n <PanelDialog>\n <PanelDialog.Header\n title={options.title ?? fileBrowserMessages.files}\n subtitle={options.subtitle}\n icon={options.icon ?? \"ti ti-folder\"}\n close={() => close()}\n />\n <PanelDialog.Body>\n <FileBrowserPanel source={options.source} />\n </PanelDialog.Body>\n </PanelDialog>\n ),\n panelDialogOptions,\n );\n};\n"],"mappings":"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","ignoreList":[]}