@agimon-ai/doompi-web-components 0.0.1-alpha.4 → 0.0.1-alpha.41

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 (503) hide show
  1. package/README.md +7 -7
  2. package/dist/index.cjs +1 -1
  3. package/dist/index.d.mts +18 -6
  4. package/dist/index.mjs +1 -1
  5. package/dist/src/components/Accordion.cjs +1 -1
  6. package/dist/src/components/Accordion.cjs.map +1 -1
  7. package/dist/src/components/Accordion.d.mts +5 -5
  8. package/dist/src/components/Accordion.d.mts.map +1 -1
  9. package/dist/src/components/Accordion.mjs +1 -1
  10. package/dist/src/components/Accordion.mjs.map +1 -1
  11. package/dist/src/components/AnsiText.cjs +4 -0
  12. package/dist/src/components/AnsiText.cjs.map +1 -0
  13. package/dist/src/components/AnsiText.d.mts +16 -0
  14. package/dist/src/components/AnsiText.d.mts.map +1 -0
  15. package/dist/src/components/AnsiText.mjs +4 -0
  16. package/dist/src/components/AnsiText.mjs.map +1 -0
  17. package/dist/src/components/Avatar.cjs +1 -1
  18. package/dist/src/components/Avatar.cjs.map +1 -1
  19. package/dist/src/components/Avatar.d.mts +4 -4
  20. package/dist/src/components/Avatar.d.mts.map +1 -1
  21. package/dist/src/components/Avatar.mjs +1 -1
  22. package/dist/src/components/Avatar.mjs.map +1 -1
  23. package/dist/src/components/Badge.cjs +1 -1
  24. package/dist/src/components/Badge.cjs.map +1 -1
  25. package/dist/src/components/Badge.d.mts +5 -6
  26. package/dist/src/components/Badge.d.mts.map +1 -1
  27. package/dist/src/components/Badge.mjs +1 -1
  28. package/dist/src/components/Badge.mjs.map +1 -1
  29. package/dist/src/components/Breadcrumb.cjs +1 -1
  30. package/dist/src/components/Breadcrumb.cjs.map +1 -1
  31. package/dist/src/components/Breadcrumb.d.mts +4 -5
  32. package/dist/src/components/Breadcrumb.d.mts.map +1 -1
  33. package/dist/src/components/Breadcrumb.mjs +1 -1
  34. package/dist/src/components/Breadcrumb.mjs.map +1 -1
  35. package/dist/src/components/Button.cjs +1 -1
  36. package/dist/src/components/Button.cjs.map +1 -1
  37. package/dist/src/components/Button.d.mts +6 -7
  38. package/dist/src/components/Button.d.mts.map +1 -1
  39. package/dist/src/components/Button.mjs +1 -1
  40. package/dist/src/components/Button.mjs.map +1 -1
  41. package/dist/src/components/Checkbox.cjs +1 -1
  42. package/dist/src/components/Checkbox.cjs.map +1 -1
  43. package/dist/src/components/Checkbox.d.mts +1 -1
  44. package/dist/src/components/Checkbox.d.mts.map +1 -1
  45. package/dist/src/components/Checkbox.mjs +1 -1
  46. package/dist/src/components/Checkbox.mjs.map +1 -1
  47. package/dist/src/components/CodeBlock.cjs +2 -0
  48. package/dist/src/components/CodeBlock.cjs.map +1 -0
  49. package/dist/src/components/CodeBlock.mjs +2 -0
  50. package/dist/src/components/CodeBlock.mjs.map +1 -0
  51. package/dist/src/components/CodeEditor.cjs +1 -1
  52. package/dist/src/components/CodeEditor.cjs.map +1 -1
  53. package/dist/src/components/CodeEditor.d.mts +1 -2
  54. package/dist/src/components/CodeEditor.d.mts.map +1 -1
  55. package/dist/src/components/CodeEditor.mjs +1 -1
  56. package/dist/src/components/CodeEditor.mjs.map +1 -1
  57. package/dist/src/components/CodeEditorView.cjs +1 -1
  58. package/dist/src/components/CodeEditorView.cjs.map +1 -1
  59. package/dist/src/components/CodeEditorView.mjs +1 -1
  60. package/dist/src/components/CodeEditorView.mjs.map +1 -1
  61. package/dist/src/components/Collapsible.cjs +1 -1
  62. package/dist/src/components/Collapsible.cjs.map +1 -1
  63. package/dist/src/components/Collapsible.d.mts +4 -4
  64. package/dist/src/components/Collapsible.d.mts.map +1 -1
  65. package/dist/src/components/Collapsible.mjs +1 -1
  66. package/dist/src/components/Collapsible.mjs.map +1 -1
  67. package/dist/src/components/Command.cjs +1 -1
  68. package/dist/src/components/Command.cjs.map +1 -1
  69. package/dist/src/components/Command.d.mts +11 -12
  70. package/dist/src/components/Command.d.mts.map +1 -1
  71. package/dist/src/components/Command.mjs +1 -1
  72. package/dist/src/components/Command.mjs.map +1 -1
  73. package/dist/src/components/CopyButton.cjs +2 -0
  74. package/dist/src/components/CopyButton.cjs.map +1 -0
  75. package/dist/src/components/CopyButton.mjs +2 -0
  76. package/dist/src/components/CopyButton.mjs.map +1 -0
  77. package/dist/src/components/Dialog.cjs +1 -1
  78. package/dist/src/components/Dialog.cjs.map +1 -1
  79. package/dist/src/components/Dialog.d.mts +15 -15
  80. package/dist/src/components/Dialog.d.mts.map +1 -1
  81. package/dist/src/components/Dialog.mjs +1 -1
  82. package/dist/src/components/Dialog.mjs.map +1 -1
  83. package/dist/src/components/Dot.cjs +1 -1
  84. package/dist/src/components/Dot.cjs.map +1 -1
  85. package/dist/src/components/Dot.d.mts +5 -6
  86. package/dist/src/components/Dot.d.mts.map +1 -1
  87. package/dist/src/components/Dot.mjs +1 -1
  88. package/dist/src/components/Dot.mjs.map +1 -1
  89. package/dist/src/components/Drawer.cjs +2 -0
  90. package/dist/src/components/Drawer.cjs.map +1 -0
  91. package/dist/src/components/Drawer.d.mts +17 -0
  92. package/dist/src/components/Drawer.d.mts.map +1 -0
  93. package/dist/src/components/Drawer.mjs +2 -0
  94. package/dist/src/components/Drawer.mjs.map +1 -0
  95. package/dist/src/components/DropdownMenu.cjs +1 -1
  96. package/dist/src/components/DropdownMenu.cjs.map +1 -1
  97. package/dist/src/components/DropdownMenu.d.mts +20 -20
  98. package/dist/src/components/DropdownMenu.d.mts.map +1 -1
  99. package/dist/src/components/DropdownMenu.mjs +1 -1
  100. package/dist/src/components/DropdownMenu.mjs.map +1 -1
  101. package/dist/src/components/EmptyState.cjs +1 -1
  102. package/dist/src/components/EmptyState.cjs.map +1 -1
  103. package/dist/src/components/EmptyState.d.mts +2 -3
  104. package/dist/src/components/EmptyState.d.mts.map +1 -1
  105. package/dist/src/components/EmptyState.mjs +1 -1
  106. package/dist/src/components/EmptyState.mjs.map +1 -1
  107. package/dist/src/components/HashlineLines.cjs +2 -0
  108. package/dist/src/components/HashlineLines.cjs.map +1 -0
  109. package/dist/src/components/HashlineLines.d.mts +23 -0
  110. package/dist/src/components/HashlineLines.d.mts.map +1 -0
  111. package/dist/src/components/HashlineLines.mjs +2 -0
  112. package/dist/src/components/HashlineLines.mjs.map +1 -0
  113. package/dist/src/components/Input.cjs +1 -1
  114. package/dist/src/components/Input.cjs.map +1 -1
  115. package/dist/src/components/Input.d.mts +6 -7
  116. package/dist/src/components/Input.d.mts.map +1 -1
  117. package/dist/src/components/Input.mjs +1 -1
  118. package/dist/src/components/Input.mjs.map +1 -1
  119. package/dist/src/components/Kbd.cjs +1 -1
  120. package/dist/src/components/Kbd.cjs.map +1 -1
  121. package/dist/src/components/Kbd.d.mts +1 -2
  122. package/dist/src/components/Kbd.d.mts.map +1 -1
  123. package/dist/src/components/Kbd.mjs +1 -1
  124. package/dist/src/components/Kbd.mjs.map +1 -1
  125. package/dist/src/components/Label.cjs +1 -1
  126. package/dist/src/components/Label.cjs.map +1 -1
  127. package/dist/src/components/Label.d.mts +1 -1
  128. package/dist/src/components/Label.d.mts.map +1 -1
  129. package/dist/src/components/Label.mjs +1 -1
  130. package/dist/src/components/Label.mjs.map +1 -1
  131. package/dist/src/components/Markdown.cjs +2 -1
  132. package/dist/src/components/Markdown.cjs.map +1 -1
  133. package/dist/src/components/Markdown.d.mts +12 -3
  134. package/dist/src/components/Markdown.d.mts.map +1 -1
  135. package/dist/src/components/Markdown.mjs +2 -1
  136. package/dist/src/components/Markdown.mjs.map +1 -1
  137. package/dist/src/components/MediaPreview.cjs +1 -1
  138. package/dist/src/components/MediaPreview.cjs.map +1 -1
  139. package/dist/src/components/MediaPreview.d.mts +39 -3
  140. package/dist/src/components/MediaPreview.d.mts.map +1 -1
  141. package/dist/src/components/MediaPreview.mjs +1 -1
  142. package/dist/src/components/MediaPreview.mjs.map +1 -1
  143. package/dist/src/components/MermaidDiagram.cjs +2 -0
  144. package/dist/src/components/MermaidDiagram.cjs.map +1 -0
  145. package/dist/src/components/MermaidDiagram.mjs +2 -0
  146. package/dist/src/components/MermaidDiagram.mjs.map +1 -0
  147. package/dist/src/components/MessageItem.cjs +1 -1
  148. package/dist/src/components/MessageItem.cjs.map +1 -1
  149. package/dist/src/components/MessageItem.d.mts +48 -17
  150. package/dist/src/components/MessageItem.d.mts.map +1 -1
  151. package/dist/src/components/MessageItem.mjs +1 -1
  152. package/dist/src/components/MessageItem.mjs.map +1 -1
  153. package/dist/src/components/MessageLines.cjs +1 -1
  154. package/dist/src/components/MessageLines.cjs.map +1 -1
  155. package/dist/src/components/MessageLines.d.mts +5 -6
  156. package/dist/src/components/MessageLines.d.mts.map +1 -1
  157. package/dist/src/components/MessageLines.mjs +1 -1
  158. package/dist/src/components/MessageLines.mjs.map +1 -1
  159. package/dist/src/components/OptionList.cjs +1 -1
  160. package/dist/src/components/OptionList.cjs.map +1 -1
  161. package/dist/src/components/OptionList.d.mts +9 -10
  162. package/dist/src/components/OptionList.d.mts.map +1 -1
  163. package/dist/src/components/OptionList.mjs +1 -1
  164. package/dist/src/components/OptionList.mjs.map +1 -1
  165. package/dist/src/components/Panel.cjs +1 -1
  166. package/dist/src/components/Panel.cjs.map +1 -1
  167. package/dist/src/components/Panel.d.mts +4 -5
  168. package/dist/src/components/Panel.d.mts.map +1 -1
  169. package/dist/src/components/Panel.mjs +1 -1
  170. package/dist/src/components/Panel.mjs.map +1 -1
  171. package/dist/src/components/PdfPreview.cjs +2 -0
  172. package/dist/src/components/PdfPreview.cjs.map +1 -0
  173. package/dist/src/components/PdfPreview.d.mts +52 -0
  174. package/dist/src/components/PdfPreview.d.mts.map +1 -0
  175. package/dist/src/components/PdfPreview.mjs +2 -0
  176. package/dist/src/components/PdfPreview.mjs.map +1 -0
  177. package/dist/src/components/Popover.cjs +1 -1
  178. package/dist/src/components/Popover.cjs.map +1 -1
  179. package/dist/src/components/Popover.d.mts +8 -8
  180. package/dist/src/components/Popover.d.mts.map +1 -1
  181. package/dist/src/components/Popover.mjs +1 -1
  182. package/dist/src/components/Popover.mjs.map +1 -1
  183. package/dist/src/components/Progress.cjs +1 -1
  184. package/dist/src/components/Progress.cjs.map +1 -1
  185. package/dist/src/components/Progress.d.mts +1 -1
  186. package/dist/src/components/Progress.d.mts.map +1 -1
  187. package/dist/src/components/Progress.mjs +1 -1
  188. package/dist/src/components/Progress.mjs.map +1 -1
  189. package/dist/src/components/RadioGroup.cjs +1 -1
  190. package/dist/src/components/RadioGroup.cjs.map +1 -1
  191. package/dist/src/components/RadioGroup.d.mts +4 -4
  192. package/dist/src/components/RadioGroup.d.mts.map +1 -1
  193. package/dist/src/components/RadioGroup.mjs +1 -1
  194. package/dist/src/components/RadioGroup.mjs.map +1 -1
  195. package/dist/src/components/ScrollArea.cjs +1 -1
  196. package/dist/src/components/ScrollArea.cjs.map +1 -1
  197. package/dist/src/components/ScrollArea.d.mts +3 -3
  198. package/dist/src/components/ScrollArea.d.mts.map +1 -1
  199. package/dist/src/components/ScrollArea.mjs +1 -1
  200. package/dist/src/components/ScrollArea.mjs.map +1 -1
  201. package/dist/src/components/SectionLabel.cjs +1 -1
  202. package/dist/src/components/SectionLabel.cjs.map +1 -1
  203. package/dist/src/components/SectionLabel.d.mts +1 -2
  204. package/dist/src/components/SectionLabel.d.mts.map +1 -1
  205. package/dist/src/components/SectionLabel.mjs +1 -1
  206. package/dist/src/components/SectionLabel.mjs.map +1 -1
  207. package/dist/src/components/Select.cjs +1 -1
  208. package/dist/src/components/Select.cjs.map +1 -1
  209. package/dist/src/components/Select.d.mts +9 -9
  210. package/dist/src/components/Select.d.mts.map +1 -1
  211. package/dist/src/components/Select.mjs +1 -1
  212. package/dist/src/components/Select.mjs.map +1 -1
  213. package/dist/src/components/Separator.cjs +1 -1
  214. package/dist/src/components/Separator.cjs.map +1 -1
  215. package/dist/src/components/Separator.d.mts +1 -1
  216. package/dist/src/components/Separator.d.mts.map +1 -1
  217. package/dist/src/components/Separator.mjs +1 -1
  218. package/dist/src/components/Separator.mjs.map +1 -1
  219. package/dist/src/components/Sheet.cjs +2 -0
  220. package/dist/src/components/Sheet.cjs.map +1 -0
  221. package/dist/src/components/Sheet.d.mts +35 -0
  222. package/dist/src/components/Sheet.d.mts.map +1 -0
  223. package/dist/src/components/Sheet.mjs +2 -0
  224. package/dist/src/components/Sheet.mjs.map +1 -0
  225. package/dist/src/components/Skeleton.cjs +1 -1
  226. package/dist/src/components/Skeleton.cjs.map +1 -1
  227. package/dist/src/components/Skeleton.d.mts +1 -2
  228. package/dist/src/components/Skeleton.d.mts.map +1 -1
  229. package/dist/src/components/Skeleton.mjs +1 -1
  230. package/dist/src/components/Skeleton.mjs.map +1 -1
  231. package/dist/src/components/Spinner.cjs +1 -1
  232. package/dist/src/components/Spinner.cjs.map +1 -1
  233. package/dist/src/components/Spinner.d.mts +2 -3
  234. package/dist/src/components/Spinner.d.mts.map +1 -1
  235. package/dist/src/components/Spinner.mjs +1 -1
  236. package/dist/src/components/Spinner.mjs.map +1 -1
  237. package/dist/src/components/StatusBadge.cjs +1 -1
  238. package/dist/src/components/StatusBadge.cjs.map +1 -1
  239. package/dist/src/components/StatusBadge.d.mts +6 -7
  240. package/dist/src/components/StatusBadge.d.mts.map +1 -1
  241. package/dist/src/components/StatusBadge.mjs +1 -1
  242. package/dist/src/components/StatusBadge.mjs.map +1 -1
  243. package/dist/src/components/StreamCursor.cjs +1 -1
  244. package/dist/src/components/StreamCursor.cjs.map +1 -1
  245. package/dist/src/components/StreamCursor.d.mts +1 -2
  246. package/dist/src/components/StreamCursor.d.mts.map +1 -1
  247. package/dist/src/components/StreamCursor.mjs +1 -1
  248. package/dist/src/components/StreamCursor.mjs.map +1 -1
  249. package/dist/src/components/Switch.cjs +1 -1
  250. package/dist/src/components/Switch.cjs.map +1 -1
  251. package/dist/src/components/Switch.d.mts +1 -1
  252. package/dist/src/components/Switch.d.mts.map +1 -1
  253. package/dist/src/components/Switch.mjs +1 -1
  254. package/dist/src/components/Switch.mjs.map +1 -1
  255. package/dist/src/components/SyntaxText.cjs +4 -0
  256. package/dist/src/components/SyntaxText.cjs.map +1 -0
  257. package/dist/src/components/SyntaxText.d.mts +50 -0
  258. package/dist/src/components/SyntaxText.d.mts.map +1 -0
  259. package/dist/src/components/SyntaxText.mjs +4 -0
  260. package/dist/src/components/SyntaxText.mjs.map +1 -0
  261. package/dist/src/components/Tabs.cjs +1 -1
  262. package/dist/src/components/Tabs.cjs.map +1 -1
  263. package/dist/src/components/Tabs.d.mts +11 -11
  264. package/dist/src/components/Tabs.d.mts.map +1 -1
  265. package/dist/src/components/Tabs.mjs +1 -1
  266. package/dist/src/components/Tabs.mjs.map +1 -1
  267. package/dist/src/components/TerminalView.cjs +2 -0
  268. package/dist/src/components/TerminalView.cjs.map +1 -0
  269. package/dist/src/components/TerminalView.d.mts +31 -0
  270. package/dist/src/components/TerminalView.d.mts.map +1 -0
  271. package/dist/src/components/TerminalView.mjs +2 -0
  272. package/dist/src/components/TerminalView.mjs.map +1 -0
  273. package/dist/src/components/Textarea.cjs +1 -1
  274. package/dist/src/components/Textarea.cjs.map +1 -1
  275. package/dist/src/components/Textarea.d.mts +3 -4
  276. package/dist/src/components/Textarea.d.mts.map +1 -1
  277. package/dist/src/components/Textarea.mjs +1 -1
  278. package/dist/src/components/Textarea.mjs.map +1 -1
  279. package/dist/src/components/Toast.cjs +1 -1
  280. package/dist/src/components/Toast.cjs.map +1 -1
  281. package/dist/src/components/Toast.d.mts +11 -11
  282. package/dist/src/components/Toast.d.mts.map +1 -1
  283. package/dist/src/components/Toast.mjs +1 -1
  284. package/dist/src/components/Toast.mjs.map +1 -1
  285. package/dist/src/components/ToolPathLink.cjs +2 -0
  286. package/dist/src/components/ToolPathLink.cjs.map +1 -0
  287. package/dist/src/components/ToolPathLink.d.mts +22 -0
  288. package/dist/src/components/ToolPathLink.d.mts.map +1 -0
  289. package/dist/src/components/ToolPathLink.mjs +2 -0
  290. package/dist/src/components/ToolPathLink.mjs.map +1 -0
  291. package/dist/src/components/Tooltip.cjs +1 -1
  292. package/dist/src/components/Tooltip.cjs.map +1 -1
  293. package/dist/src/components/Tooltip.d.mts +5 -5
  294. package/dist/src/components/Tooltip.d.mts.map +1 -1
  295. package/dist/src/components/Tooltip.mjs +1 -1
  296. package/dist/src/components/Tooltip.mjs.map +1 -1
  297. package/dist/src/icons/icons.cjs +1 -1
  298. package/dist/src/icons/icons.d.mts +2 -2
  299. package/dist/src/icons/icons.mjs +1 -1
  300. package/dist/src/lib/ansiSpans.cjs +2 -0
  301. package/dist/src/lib/ansiSpans.cjs.map +1 -0
  302. package/dist/src/lib/ansiSpans.d.mts +42 -0
  303. package/dist/src/lib/ansiSpans.d.mts.map +1 -0
  304. package/dist/src/lib/ansiSpans.mjs +2 -0
  305. package/dist/src/lib/ansiSpans.mjs.map +1 -0
  306. package/dist/src/lib/cn.d.mts +1 -2
  307. package/dist/src/lib/cn.d.mts.map +1 -1
  308. package/dist/src/lib/collapse.d.mts +2 -3
  309. package/dist/src/lib/collapse.d.mts.map +1 -1
  310. package/dist/src/lib/editorController.cjs +2 -0
  311. package/dist/src/lib/editorController.cjs.map +1 -0
  312. package/dist/src/lib/editorController.mjs +2 -0
  313. package/dist/src/lib/editorController.mjs.map +1 -0
  314. package/dist/src/lib/editorLanguage.d.mts +2 -3
  315. package/dist/src/lib/editorLanguage.d.mts.map +1 -1
  316. package/dist/src/lib/editorTheme.cjs +1 -1
  317. package/dist/src/lib/editorTheme.cjs.map +1 -1
  318. package/dist/src/lib/editorTheme.d.mts +76 -0
  319. package/dist/src/lib/editorTheme.d.mts.map +1 -0
  320. package/dist/src/lib/editorTheme.mjs +1 -1
  321. package/dist/src/lib/editorTheme.mjs.map +1 -1
  322. package/dist/src/lib/fenceGrammar.cjs +2 -0
  323. package/dist/src/lib/fenceGrammar.cjs.map +1 -0
  324. package/dist/src/lib/fenceGrammar.mjs +2 -0
  325. package/dist/src/lib/fenceGrammar.mjs.map +1 -0
  326. package/dist/src/lib/hashlineHighlight.cjs +3 -0
  327. package/dist/src/lib/hashlineHighlight.cjs.map +1 -0
  328. package/dist/src/lib/hashlineHighlight.d.mts +30 -0
  329. package/dist/src/lib/hashlineHighlight.d.mts.map +1 -0
  330. package/dist/src/lib/hashlineHighlight.mjs +3 -0
  331. package/dist/src/lib/hashlineHighlight.mjs.map +1 -0
  332. package/dist/src/lib/hashlineView.cjs +6 -0
  333. package/dist/src/lib/hashlineView.cjs.map +1 -0
  334. package/dist/src/lib/hashlineView.d.mts +60 -0
  335. package/dist/src/lib/hashlineView.d.mts.map +1 -0
  336. package/dist/src/lib/hashlineView.mjs +6 -0
  337. package/dist/src/lib/hashlineView.mjs.map +1 -0
  338. package/dist/src/lib/media.cjs.map +1 -1
  339. package/dist/src/lib/media.d.mts +1 -2
  340. package/dist/src/lib/media.d.mts.map +1 -1
  341. package/dist/src/lib/media.mjs.map +1 -1
  342. package/dist/src/lib/mediaPlayback.cjs +2 -0
  343. package/dist/src/lib/mediaPlayback.cjs.map +1 -0
  344. package/dist/src/lib/mediaPlayback.mjs +2 -0
  345. package/dist/src/lib/mediaPlayback.mjs.map +1 -0
  346. package/dist/src/lib/mermaidDiagram.cjs +2 -0
  347. package/dist/src/lib/mermaidDiagram.cjs.map +1 -0
  348. package/dist/src/lib/mermaidDiagram.mjs +2 -0
  349. package/dist/src/lib/mermaidDiagram.mjs.map +1 -0
  350. package/dist/src/lib/optionList.d.mts +4 -5
  351. package/dist/src/lib/optionList.d.mts.map +1 -1
  352. package/dist/src/lib/syntaxHighlight.cjs +3 -0
  353. package/dist/src/lib/syntaxHighlight.cjs.map +1 -0
  354. package/dist/src/lib/syntaxHighlight.d.mts +54 -0
  355. package/dist/src/lib/syntaxHighlight.d.mts.map +1 -0
  356. package/dist/src/lib/syntaxHighlight.mjs +3 -0
  357. package/dist/src/lib/syntaxHighlight.mjs.map +1 -0
  358. package/dist/src/lib/tone.cjs.map +1 -1
  359. package/dist/src/lib/tone.d.mts +4 -5
  360. package/dist/src/lib/tone.d.mts.map +1 -1
  361. package/dist/src/lib/tone.mjs.map +1 -1
  362. package/dist/src/theme/apply.cjs.map +1 -1
  363. package/dist/src/theme/apply.d.mts +5 -6
  364. package/dist/src/theme/apply.d.mts.map +1 -1
  365. package/dist/src/theme/apply.mjs.map +1 -1
  366. package/dist/src/theme/builtinThemes.cjs.map +1 -1
  367. package/dist/src/theme/builtinThemes.d.mts +4 -5
  368. package/dist/src/theme/builtinThemes.d.mts.map +1 -1
  369. package/dist/src/theme/builtinThemes.mjs.map +1 -1
  370. package/dist/src/theme/derive.cjs.map +1 -1
  371. package/dist/src/theme/derive.d.mts +4 -5
  372. package/dist/src/theme/derive.d.mts.map +1 -1
  373. package/dist/src/theme/derive.mjs.map +1 -1
  374. package/dist/src/theme/parse.cjs.map +1 -1
  375. package/dist/src/theme/parse.d.mts +1 -2
  376. package/dist/src/theme/parse.d.mts.map +1 -1
  377. package/dist/src/theme/parse.mjs.map +1 -1
  378. package/dist/src/theme/piTheme.cjs.map +1 -1
  379. package/dist/src/theme/piTheme.d.mts +2 -3
  380. package/dist/src/theme/piTheme.d.mts.map +1 -1
  381. package/dist/src/theme/piTheme.mjs.map +1 -1
  382. package/dist/src/theme/preference.d.mts +4 -5
  383. package/dist/src/theme/preference.d.mts.map +1 -1
  384. package/dist/src/types/editor.cjs.map +1 -1
  385. package/dist/src/types/editor.d.mts +39 -5
  386. package/dist/src/types/editor.d.mts.map +1 -1
  387. package/dist/src/types/editor.mjs.map +1 -1
  388. package/dist/src/types/theme.d.mts +11 -12
  389. package/dist/src/types/theme.d.mts.map +1 -1
  390. package/dist/src/types/tone.d.mts +10 -11
  391. package/dist/src/types/tone.d.mts.map +1 -1
  392. package/package.json +21 -17
  393. package/styles/preview.css +17 -0
  394. package/styles/tokens.css +72 -0
  395. package/dist/components/Accordion.d.cts +0 -11
  396. package/dist/components/Accordion.d.cts.map +0 -1
  397. package/dist/components/Avatar.d.cts +0 -10
  398. package/dist/components/Avatar.d.cts.map +0 -1
  399. package/dist/components/Badge.d.cts +0 -18
  400. package/dist/components/Badge.d.cts.map +0 -1
  401. package/dist/components/Breadcrumb.d.cts +0 -37
  402. package/dist/components/Breadcrumb.d.cts.map +0 -1
  403. package/dist/components/Button.d.cts +0 -25
  404. package/dist/components/Button.d.cts.map +0 -1
  405. package/dist/components/Checkbox.d.cts +0 -8
  406. package/dist/components/Checkbox.d.cts.map +0 -1
  407. package/dist/components/CodeEditor.d.cts +0 -6
  408. package/dist/components/CodeEditor.d.cts.map +0 -1
  409. package/dist/components/Collapsible.d.cts +0 -10
  410. package/dist/components/Collapsible.d.cts.map +0 -1
  411. package/dist/components/Command.d.cts +0 -42
  412. package/dist/components/Command.d.cts.map +0 -1
  413. package/dist/components/Dialog.d.cts +0 -39
  414. package/dist/components/Dialog.d.cts.map +0 -1
  415. package/dist/components/Dot.d.cts +0 -16
  416. package/dist/components/Dot.d.cts.map +0 -1
  417. package/dist/components/DropdownMenu.d.cts +0 -34
  418. package/dist/components/DropdownMenu.d.cts.map +0 -1
  419. package/dist/components/EmptyState.d.cts +0 -18
  420. package/dist/components/EmptyState.d.cts.map +0 -1
  421. package/dist/components/Input.d.cts +0 -20
  422. package/dist/components/Input.d.cts.map +0 -1
  423. package/dist/components/Kbd.d.cts +0 -7
  424. package/dist/components/Kbd.d.cts.map +0 -1
  425. package/dist/components/Label.d.cts +0 -8
  426. package/dist/components/Label.d.cts.map +0 -1
  427. package/dist/components/Markdown.d.cts +0 -8
  428. package/dist/components/Markdown.d.cts.map +0 -1
  429. package/dist/components/MediaPreview.d.cts +0 -25
  430. package/dist/components/MediaPreview.d.cts.map +0 -1
  431. package/dist/components/MessageItem.d.cts +0 -71
  432. package/dist/components/MessageItem.d.cts.map +0 -1
  433. package/dist/components/MessageLines.d.cts +0 -24
  434. package/dist/components/MessageLines.d.cts.map +0 -1
  435. package/dist/components/OptionList.d.cts +0 -50
  436. package/dist/components/OptionList.d.cts.map +0 -1
  437. package/dist/components/Panel.d.cts +0 -15
  438. package/dist/components/Panel.d.cts.map +0 -1
  439. package/dist/components/Popover.d.cts +0 -19
  440. package/dist/components/Popover.d.cts.map +0 -1
  441. package/dist/components/Progress.d.cts +0 -8
  442. package/dist/components/Progress.d.cts.map +0 -1
  443. package/dist/components/RadioGroup.d.cts +0 -15
  444. package/dist/components/RadioGroup.d.cts.map +0 -1
  445. package/dist/components/ScrollArea.d.cts +0 -13
  446. package/dist/components/ScrollArea.d.cts.map +0 -1
  447. package/dist/components/SectionLabel.d.cts +0 -7
  448. package/dist/components/SectionLabel.d.cts.map +0 -1
  449. package/dist/components/Select.d.cts +0 -19
  450. package/dist/components/Select.d.cts.map +0 -1
  451. package/dist/components/Separator.d.cts +0 -13
  452. package/dist/components/Separator.d.cts.map +0 -1
  453. package/dist/components/Skeleton.d.cts +0 -11
  454. package/dist/components/Skeleton.d.cts.map +0 -1
  455. package/dist/components/Spinner.d.cts +0 -15
  456. package/dist/components/Spinner.d.cts.map +0 -1
  457. package/dist/components/StatusBadge.d.cts +0 -24
  458. package/dist/components/StatusBadge.d.cts.map +0 -1
  459. package/dist/components/StreamCursor.d.cts +0 -7
  460. package/dist/components/StreamCursor.d.cts.map +0 -1
  461. package/dist/components/Switch.d.cts +0 -8
  462. package/dist/components/Switch.d.cts.map +0 -1
  463. package/dist/components/Tabs.d.cts +0 -36
  464. package/dist/components/Tabs.d.cts.map +0 -1
  465. package/dist/components/Textarea.d.cts +0 -10
  466. package/dist/components/Textarea.d.cts.map +0 -1
  467. package/dist/components/Toast.d.cts +0 -24
  468. package/dist/components/Toast.d.cts.map +0 -1
  469. package/dist/components/Tooltip.d.cts +0 -11
  470. package/dist/components/Tooltip.d.cts.map +0 -1
  471. package/dist/icons/icons.d.cts +0 -2
  472. package/dist/index.d.cts +0 -48
  473. package/dist/lib/cn.d.cts +0 -7
  474. package/dist/lib/cn.d.cts.map +0 -1
  475. package/dist/lib/collapse.d.cts +0 -15
  476. package/dist/lib/collapse.d.cts.map +0 -1
  477. package/dist/lib/editorLanguage.d.cts +0 -22
  478. package/dist/lib/editorLanguage.d.cts.map +0 -1
  479. package/dist/lib/media.d.cts +0 -12
  480. package/dist/lib/media.d.cts.map +0 -1
  481. package/dist/lib/optionList.d.cts +0 -22
  482. package/dist/lib/optionList.d.cts.map +0 -1
  483. package/dist/lib/tone.d.cts +0 -26
  484. package/dist/lib/tone.d.cts.map +0 -1
  485. package/dist/theme/apply.d.cts +0 -26
  486. package/dist/theme/apply.d.cts.map +0 -1
  487. package/dist/theme/builtinThemes.d.cts +0 -12
  488. package/dist/theme/builtinThemes.d.cts.map +0 -1
  489. package/dist/theme/derive.d.cts +0 -15
  490. package/dist/theme/derive.d.cts.map +0 -1
  491. package/dist/theme/parse.d.cts +0 -11
  492. package/dist/theme/parse.d.cts.map +0 -1
  493. package/dist/theme/piTheme.d.cts +0 -20
  494. package/dist/theme/piTheme.d.cts.map +0 -1
  495. package/dist/theme/preference.d.cts +0 -16
  496. package/dist/theme/preference.d.cts.map +0 -1
  497. package/dist/theme.d.cts +0 -8
  498. package/dist/types/editor.d.cts +0 -44
  499. package/dist/types/editor.d.cts.map +0 -1
  500. package/dist/types/theme.d.cts +0 -39
  501. package/dist/types/theme.d.cts.map +0 -1
  502. package/dist/types/tone.d.cts +0 -29
  503. package/dist/types/tone.d.cts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Input.mjs","names":[],"sources":["../../../src/components/Input.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport type { ComponentProps } from 'react';\nimport { cn } from '../lib/cn.ts';\n\n/**\n * The shape both fields wear, so a single-line and a multi-line field in the\n * same form agree on their well, their type ramp, and their invalid state.\n * Textarea builds on it rather than restating it.\n */\nexport const fieldVariants = cva(\n 'min-w-0 font-mono text-doom-hi outline-none placeholder:text-doom-faint disabled:opacity-50 aria-invalid:border-doom-edge-red aria-invalid:text-doom-red',\n {\n variants: {\n variant: {\n default: 'rounded border border-doom-border bg-doom-deep transition-colors focus:border-doom-blue/60',\n /** No well: a composer or a palette search that draws its own surface. */\n bare: 'border-0 bg-transparent',\n },\n /** The same rungs Button names, so a field and the button beside it line up. */\n size: {\n xs: 'px-1.5 py-0.5 text-[10px]',\n sm: 'px-2 py-1 text-[11px]',\n md: 'px-2.5 py-1.5 text-[12px]',\n lg: 'px-3 py-2 text-[13px]',\n },\n },\n compoundVariants: [\n // A bare field sits inside a surface that already has its own padding,\n // so it keeps the size's type ramp and gives up the size's box.\n { variant: 'bare', class: 'p-0' },\n ],\n defaultVariants: { variant: 'default', size: 'md' },\n },\n);\n\nexport type FieldVariant = NonNullable<VariantProps<typeof fieldVariants>['variant']>;\nexport type FieldSize = NonNullable<VariantProps<typeof fieldVariants>['size']>;\n\nexport interface InputProps extends Omit<ComponentProps<'input'>, 'size'>, VariantProps<typeof fieldVariants> {}\n\n/** The one text field: deep well, quiet border, accent border on focus, red edge when invalid. */\nexport function Input({ className, type, variant, size, ...props }: InputProps) {\n return (\n <input\n type={type ?? 'text'}\n data-slot=\"input\"\n spellCheck={false}\n className={cn(fieldVariants({ variant, size }), className)}\n {...props}\n />\n );\n}\n"],"mappings":"0HASA,MAAa,EAAgB,EAC3B,2JACA,CACE,SAAU,CACR,QAAS,CACP,QAAS,6FAET,KAAM,yBACR,EAEA,KAAM,CACJ,GAAI,4BACJ,GAAI,wBACJ,GAAI,4BACJ,GAAI,uBACN,CACF,EACA,iBAAkB,CAGhB,CAAE,QAAS,OAAQ,MAAO,KAAM,CAClC,EACA,gBAAiB,CAAE,QAAS,UAAW,KAAM,IAAK,CACpD,CACF,EAQA,SAAgB,EAAM,CAAE,YAAW,OAAM,UAAS,OAAM,GAAG,GAAqB,CAC9E,OACE,EAAC,QAAD,CACE,KAAM,GAAQ,OACd,YAAU,QACV,WAAY,GACZ,UAAW,EAAG,EAAc,CAAE,UAAS,MAAK,CAAC,EAAG,CAAS,EACzD,GAAI,CACL,CAAA,CAEL"}
1
+ {"version":3,"file":"Input.mjs","names":[],"sources":["../../../src/components/Input.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/**\n * The shape both fields wear, so a single-line and a multi-line field in the\n * same form agree on their well, their type ramp, and their invalid state.\n * Textarea builds on it rather than restating it.\n */\nexport const fieldVariants = cva(\n 'min-w-0 font-mono text-doom-hi outline-none placeholder:text-doom-faint disabled:opacity-50 aria-invalid:border-doom-edge-red aria-invalid:text-doom-red',\n {\n variants: {\n variant: {\n default: 'rounded border border-doom-border bg-doom-deep transition-colors focus:border-doom-blue/60',\n /** No well: a composer or a palette search that draws its own surface. */\n bare: 'border-0 bg-transparent',\n },\n /** The same rungs Button names, so a field and the button beside it line up. */\n size: {\n xs: 'px-1.5 py-0.5 text-2xs',\n sm: 'px-2 py-1 text-xs',\n md: 'px-2.5 py-1.5 text-sm',\n lg: 'px-3 py-2 text-base',\n },\n },\n compoundVariants: [\n // A bare field sits inside a surface that already has its own padding,\n // so it keeps the size's type ramp and gives up the size's box.\n { variant: 'bare', class: 'p-0' },\n ],\n defaultVariants: { variant: 'default', size: 'md' },\n },\n);\n\nexport type FieldVariant = NonNullable<VariantProps<typeof fieldVariants>['variant']>;\nexport type FieldSize = NonNullable<VariantProps<typeof fieldVariants>['size']>;\n\nexport interface InputProps extends Omit<ComponentProps<'input'>, 'size'>, VariantProps<typeof fieldVariants> {}\n\n/** The one text field: deep well, quiet border, accent border on focus, red edge when invalid. */\nexport function Input({ className, type, variant, size, ...props }: InputProps) {\n return (\n <input\n type={type ?? 'text'}\n data-slot=\"input\"\n spellCheck={false}\n className={cn(fieldVariants({ variant, size }), className)}\n {...props}\n />\n );\n}\n"],"mappings":"0HAUA,MAAa,EAAgB,EAC3B,2JACA,CACE,SAAU,CACR,QAAS,CACP,QAAS,6FAET,KAAM,yBACR,EAEA,KAAM,CACJ,GAAI,yBACJ,GAAI,oBACJ,GAAI,wBACJ,GAAI,qBACN,CACF,EACA,iBAAkB,CAGhB,CAAE,QAAS,OAAQ,MAAO,KAAM,CAClC,EACA,gBAAiB,CAAE,QAAS,UAAW,KAAM,IAAK,CACpD,CACF,EAQA,SAAgB,EAAM,CAAE,YAAW,OAAM,UAAS,OAAM,GAAG,GAAqB,CAC9E,MACE,kBAAC,QAAD,CACE,KAAM,GAAQ,OACd,YAAU,QACV,WAAY,GACZ,UAAW,EAAG,EAAc,CAAE,UAAS,MAAK,CAAC,EAAG,CAAS,EACzD,GAAI,CACL,CAAA,CAEL"}
@@ -1,2 +1,2 @@
1
- const e=require("../lib/cn.cjs");let t=require("react/jsx-runtime");function n({className:n,...r}){return(0,t.jsx)(`kbd`,{"data-slot":`kbd`,className:e.cn(`inline-flex items-center rounded bg-doom-deep px-1.5 py-0.5 font-mono text-[8px] font-bold text-doom-faint`,n),...r})}exports.Kbd=n;
1
+ const e=require("../lib/cn.cjs");let t=require("react/jsx-runtime");function n({className:n,...r}){return/* @__PURE__ */ (0,t.jsx)(`kbd`,{"data-slot":`kbd`,className:e.cn(`inline-flex items-center rounded bg-doom-deep px-1.5 py-0.5 font-mono text-2xs font-bold text-doom-faint`,n),...r})}exports.Kbd=n;
2
2
  //# sourceMappingURL=Kbd.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Kbd.cjs","names":["cn"],"sources":["../../../src/components/Kbd.tsx"],"sourcesContent":["import type { ComponentProps } from 'react';\nimport { cn } from '../lib/cn.ts';\n\n/** A key or key path, drawn as the leader hints draw them. */\nexport function Kbd({ className, ...props }: ComponentProps<'kbd'>) {\n return (\n <kbd\n data-slot=\"kbd\"\n className={cn(\n 'inline-flex items-center rounded bg-doom-deep px-1.5 py-0.5 font-mono text-[8px] font-bold text-doom-faint',\n className,\n )}\n {...props}\n />\n );\n}\n"],"mappings":"oEAIA,SAAgB,EAAI,CAAE,YAAW,GAAG,GAAgC,CAClE,OACE,EAAA,EAAA,IAAA,CAAC,MAAD,CACE,YAAU,MACV,UAAWA,EAAAA,GACT,6GACA,CACF,EACA,GAAI,CACL,CAAA,CAEL"}
1
+ {"version":3,"file":"Kbd.cjs","names":["cn"],"sources":["../../../src/components/Kbd.tsx"],"sourcesContent":["import type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/** A key or key path, drawn as the leader hints draw them. */\nexport function Kbd({ className, ...props }: ComponentProps<'kbd'>) {\n return (\n <kbd\n data-slot=\"kbd\"\n className={cn(\n 'inline-flex items-center rounded bg-doom-deep px-1.5 py-0.5 font-mono text-2xs font-bold text-doom-faint',\n className,\n )}\n {...props}\n />\n );\n}\n"],"mappings":"oEAKA,SAAgB,EAAI,CAAE,YAAW,GAAG,GAAgC,CAClE,MACE,iBAAA,EAAA,EAAA,IAAA,CAAC,MAAD,CACE,YAAU,MACV,UAAWA,EAAAA,GACT,2GACA,CACF,EACA,GAAI,CACL,CAAA,CAEL"}
@@ -1,7 +1,6 @@
1
1
  import { ComponentProps } from "react";
2
2
  //#region src/components/Kbd.d.ts
3
3
  /** A key or key path, drawn as the leader hints draw them. */
4
- declare function Kbd({ className, ...props }: ComponentProps<'kbd'>): import("react/jsx-runtime").JSX.Element;
4
+ export declare function Kbd({ className, ...props }: ComponentProps<'kbd'>): import("react").JSX.Element;
5
5
  //#endregion
6
- export { Kbd };
7
6
  //# sourceMappingURL=Kbd.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Kbd.d.mts","names":[],"sources":["../../../src/components/Kbd.tsx"],"mappings":";;;iBAIgB,MAAM,cAAc,SAAS,oDAAqB,IAAA"}
1
+ {"version":3,"file":"Kbd.d.mts","names":[],"sources":["../../../src/components/Kbd.tsx"],"mappings":";;;wBAKgB,MAAM,cAAc,SAAS,wCAAqB,IAAA"}
@@ -1,2 +1,2 @@
1
- import{cn as e}from"../lib/cn.mjs";import{jsx as t}from"react/jsx-runtime";function n({className:n,...r}){return t(`kbd`,{"data-slot":`kbd`,className:e(`inline-flex items-center rounded bg-doom-deep px-1.5 py-0.5 font-mono text-[8px] font-bold text-doom-faint`,n),...r})}export{n as Kbd};
1
+ import{cn as e}from"../lib/cn.mjs";import{jsx as t}from"react/jsx-runtime";function n({className:n,...r}){return/* @__PURE__ */ t(`kbd`,{"data-slot":`kbd`,className:e(`inline-flex items-center rounded bg-doom-deep px-1.5 py-0.5 font-mono text-2xs font-bold text-doom-faint`,n),...r})}export{n as Kbd};
2
2
  //# sourceMappingURL=Kbd.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Kbd.mjs","names":[],"sources":["../../../src/components/Kbd.tsx"],"sourcesContent":["import type { ComponentProps } from 'react';\nimport { cn } from '../lib/cn.ts';\n\n/** A key or key path, drawn as the leader hints draw them. */\nexport function Kbd({ className, ...props }: ComponentProps<'kbd'>) {\n return (\n <kbd\n data-slot=\"kbd\"\n className={cn(\n 'inline-flex items-center rounded bg-doom-deep px-1.5 py-0.5 font-mono text-[8px] font-bold text-doom-faint',\n className,\n )}\n {...props}\n />\n );\n}\n"],"mappings":"2EAIA,SAAgB,EAAI,CAAE,YAAW,GAAG,GAAgC,CAClE,OACE,EAAC,MAAD,CACE,YAAU,MACV,UAAW,EACT,6GACA,CACF,EACA,GAAI,CACL,CAAA,CAEL"}
1
+ {"version":3,"file":"Kbd.mjs","names":[],"sources":["../../../src/components/Kbd.tsx"],"sourcesContent":["import type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/** A key or key path, drawn as the leader hints draw them. */\nexport function Kbd({ className, ...props }: ComponentProps<'kbd'>) {\n return (\n <kbd\n data-slot=\"kbd\"\n className={cn(\n 'inline-flex items-center rounded bg-doom-deep px-1.5 py-0.5 font-mono text-2xs font-bold text-doom-faint',\n className,\n )}\n {...props}\n />\n );\n}\n"],"mappings":"2EAKA,SAAgB,EAAI,CAAE,YAAW,GAAG,GAAgC,CAClE,MACE,kBAAC,MAAD,CACE,YAAU,MACV,UAAW,EACT,2GACA,CACF,EACA,GAAI,CACL,CAAA,CAEL"}
@@ -1,2 +1,2 @@
1
- const e=require("../lib/cn.cjs");let t=require("radix-ui"),n=require("react/jsx-runtime");function r({className:r,...i}){return(0,n.jsx)(t.Label.Root,{"data-slot":`label`,className:e.cn(`flex items-center gap-1.5 text-[10px] text-doom-faint select-none has-[+:disabled]:opacity-50`,r),...i})}exports.Label=r;
1
+ const e=require("../lib/cn.cjs");let t=require("radix-ui"),n=require("react/jsx-runtime");function r({className:r,...i}){return/* @__PURE__ */ (0,n.jsx)(t.Label.Root,{"data-slot":`label`,className:e.cn(`flex items-center gap-1.5 text-xs text-doom-faint select-none has-[+:disabled]:opacity-50`,r),...i})}exports.Label=r;
2
2
  //# sourceMappingURL=Label.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Label.cjs","names":["LabelPrimitive","cn"],"sources":["../../../src/components/Label.tsx"],"sourcesContent":["import { Label as LabelPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\nimport { cn } from '../lib/cn.ts';\n\n/** A field's name: clicking it focuses the control, which a bare span never does. */\nexport function Label({ className, ...props }: ComponentProps<typeof LabelPrimitive.Root>) {\n return (\n <LabelPrimitive.Root\n data-slot=\"label\"\n className={cn(\n 'flex items-center gap-1.5 text-[10px] text-doom-faint select-none has-[+:disabled]:opacity-50',\n className,\n )}\n {...props}\n />\n );\n}\n"],"mappings":"0FAKA,SAAgB,EAAM,CAAE,YAAW,GAAG,GAAqD,CACzF,OACE,EAAA,EAAA,IAAA,CAACA,EAAAA,MAAe,KAAhB,CACE,YAAU,QACV,UAAWC,EAAAA,GACT,gGACA,CACF,EACA,GAAI,CACL,CAAA,CAEL"}
1
+ {"version":3,"file":"Label.cjs","names":["LabelPrimitive","cn"],"sources":["../../../src/components/Label.tsx"],"sourcesContent":["import { Label as LabelPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/** A field's name: clicking it focuses the control, which a bare span never does. */\nexport function Label({ className, ...props }: ComponentProps<typeof LabelPrimitive.Root>) {\n return (\n <LabelPrimitive.Root\n data-slot=\"label\"\n className={cn(\n 'flex items-center gap-1.5 text-xs text-doom-faint select-none has-[+:disabled]:opacity-50',\n className,\n )}\n {...props}\n />\n );\n}\n"],"mappings":"0FAMA,SAAgB,EAAM,CAAE,YAAW,GAAG,GAAqD,CACzF,MACE,iBAAA,EAAA,EAAA,IAAA,CAACA,EAAAA,MAAe,KAAhB,CACE,YAAU,QACV,UAAWC,EAAAA,GACT,4FACA,CACF,EACA,GAAI,CACL,CAAA,CAEL"}
@@ -2,7 +2,7 @@ import { Label } from "radix-ui";
2
2
  import { ComponentProps } from "react";
3
3
  //#region src/components/Label.d.ts
4
4
  /** A field's name: clicking it focuses the control, which a bare span never does. */
5
- declare function Label$1({ className, ...props }: ComponentProps<typeof Label.Root>): import("react/jsx-runtime").JSX.Element;
5
+ declare function Label$1({ className, ...props }: ComponentProps<typeof Label.Root>): import("react").JSX.Element;
6
6
  //#endregion
7
7
  export { Label$1 as Label };
8
8
  //# sourceMappingURL=Label.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Label.d.mts","names":[],"sources":["../../../src/components/Label.tsx"],"mappings":";;;;iBAKgB,UAAQ,cAAc,SAAS,sBAAsB,MAAe,oCAAK,IAAA"}
1
+ {"version":3,"file":"Label.d.mts","names":[],"sources":["../../../src/components/Label.tsx"],"mappings":";;;;iBAMgB,UAAQ,cAAc,SAAS,sBAAsB,MAAe,wBAAK,IAAA"}
@@ -1,2 +1,2 @@
1
- import{cn as e}from"../lib/cn.mjs";import{Label as t}from"radix-ui";import{jsx as n}from"react/jsx-runtime";function r({className:r,...i}){return n(t.Root,{"data-slot":`label`,className:e(`flex items-center gap-1.5 text-[10px] text-doom-faint select-none has-[+:disabled]:opacity-50`,r),...i})}export{r as Label};
1
+ import{cn as e}from"../lib/cn.mjs";import{Label as t}from"radix-ui";import{jsx as n}from"react/jsx-runtime";function r({className:r,...i}){return/* @__PURE__ */ n(t.Root,{"data-slot":`label`,className:e(`flex items-center gap-1.5 text-xs text-doom-faint select-none has-[+:disabled]:opacity-50`,r),...i})}export{r as Label};
2
2
  //# sourceMappingURL=Label.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Label.mjs","names":["Label","LabelPrimitive"],"sources":["../../../src/components/Label.tsx"],"sourcesContent":["import { Label as LabelPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\nimport { cn } from '../lib/cn.ts';\n\n/** A field's name: clicking it focuses the control, which a bare span never does. */\nexport function Label({ className, ...props }: ComponentProps<typeof LabelPrimitive.Root>) {\n return (\n <LabelPrimitive.Root\n data-slot=\"label\"\n className={cn(\n 'flex items-center gap-1.5 text-[10px] text-doom-faint select-none has-[+:disabled]:opacity-50',\n className,\n )}\n {...props}\n />\n );\n}\n"],"mappings":"4GAKA,SAAgBA,EAAM,CAAE,YAAW,GAAG,GAAqD,CACzF,OACE,EAACC,EAAe,KAAhB,CACE,YAAU,QACV,UAAW,EACT,gGACA,CACF,EACA,GAAI,CACL,CAAA,CAEL"}
1
+ {"version":3,"file":"Label.mjs","names":["Label","LabelPrimitive"],"sources":["../../../src/components/Label.tsx"],"sourcesContent":["import { Label as LabelPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/** A field's name: clicking it focuses the control, which a bare span never does. */\nexport function Label({ className, ...props }: ComponentProps<typeof LabelPrimitive.Root>) {\n return (\n <LabelPrimitive.Root\n data-slot=\"label\"\n className={cn(\n 'flex items-center gap-1.5 text-xs text-doom-faint select-none has-[+:disabled]:opacity-50',\n className,\n )}\n {...props}\n />\n );\n}\n"],"mappings":"4GAMA,SAAgBA,EAAM,CAAE,YAAW,GAAG,GAAqD,CACzF,MACE,kBAACC,EAAe,KAAhB,CACE,YAAU,QACV,UAAW,EACT,4FACA,CACF,EACA,GAAI,CACL,CAAA,CAEL"}
@@ -1,2 +1,3 @@
1
- const e=require("../../_virtual/_rolldown/runtime.cjs");let t=require("react/jsx-runtime"),n=require("react-markdown");n=e.__toESM(n,1);let r=require("remark-gfm");r=e.__toESM(r,1);const i=[r.default];function a({className:e,children:n,...r}){return(0,t.jsx)(`code`,{...r,className:`${e??``} rounded bg-doom-deep px-1 py-px font-mono text-[12px] text-doom-green [pre_&]:bg-transparent [pre_&]:p-0 [pre_&]:text-doom-hi`,children:n})}const o={p:({children:e})=>(0,t.jsx)(`p`,{className:`whitespace-pre-wrap break-words`,children:e}),strong:({children:e})=>(0,t.jsx)(`strong`,{className:`font-bold text-doom-hi`,children:e}),em:({children:e})=>(0,t.jsx)(`em`,{className:`italic`,children:e}),del:({children:e})=>(0,t.jsx)(`del`,{className:`text-doom-dim line-through`,children:e}),a:({href:e,children:n})=>(0,t.jsx)(`a`,{href:e,target:`_blank`,rel:`noreferrer`,className:`text-doom-blue underline decoration-doom-blue/50`,children:n}),code:a,pre:({children:e})=>(0,t.jsx)(`pre`,{className:`overflow-x-auto rounded border border-doom-border bg-doom-deep p-2.5 text-[12px] leading-relaxed`,children:e}),ul:({children:e})=>(0,t.jsx)(`ul`,{className:`list-disc pl-5`,children:e}),ol:({children:e})=>(0,t.jsx)(`ol`,{className:`list-decimal pl-5`,children:e}),li:({children:e})=>(0,t.jsx)(`li`,{className:`whitespace-pre-wrap break-words`,children:e}),h1:({children:e})=>(0,t.jsx)(`h1`,{className:`text-[15px] font-bold text-doom-hi`,children:e}),h2:({children:e})=>(0,t.jsx)(`h2`,{className:`text-[14px] font-bold text-doom-hi`,children:e}),h3:({children:e})=>(0,t.jsx)(`h3`,{className:`text-[13px] font-bold text-doom-hi`,children:e}),h4:({children:e})=>(0,t.jsx)(`h4`,{className:`text-[13px] font-bold text-doom-text`,children:e}),blockquote:({children:e})=>(0,t.jsx)(`blockquote`,{className:`border-l-2 border-doom-border pl-3 text-doom-dim`,children:e}),hr:()=>(0,t.jsx)(`hr`,{className:`border-doom-border-soft`}),table:({children:e})=>(0,t.jsx)(`div`,{className:`overflow-x-auto`,children:(0,t.jsx)(`table`,{className:`border-collapse text-[12px]`,children:e})}),th:({children:e})=>(0,t.jsx)(`th`,{className:`border border-doom-border bg-doom-deep px-2 py-1 text-left font-bold text-doom-hi`,children:e}),td:({children:e})=>(0,t.jsx)(`td`,{className:`border border-doom-border px-2 py-1 align-top`,children:e}),img:({src:e,alt:n})=>(0,t.jsx)(`img`,{src:e,alt:n??``,className:`max-h-[480px] max-w-full rounded border border-doom-border`})};function s({text:e}){return(0,t.jsx)(`div`,{className:`flex min-w-0 flex-col gap-2`,children:(0,t.jsx)(n.default,{remarkPlugins:i,components:o,children:e})})}exports.Markdown=s;
1
+ const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("./CodeBlock.cjs");let n=require("react/jsx-runtime"),r=require("react"),i=require("react-markdown");i=e.__toESM(i,1);let a=require("remark-gfm");a=e.__toESM(a,1);const o=[a.default],s=`rounded bg-doom-deep px-1 py-px font-mono text-sm text-doom-green`,c=(0,r.createContext)(void 0);function l({className:e,children:t,...i}){let a=(0,r.useContext)(c),o=typeof t==`string`&&!t.includes(`
2
+ `)?t:void 0,l=o===void 0||e!==void 0?void 0:a?.(o);return l!==void 0&&o!==void 0?/* @__PURE__ */ (0,n.jsx)(`button`,{type:`button`,"data-testid":`markdown-file-link`,title:`open ${o}`,onClick:l,className:`${s} cursor-pointer underline decoration-doom-green/40 underline-offset-2 hover:text-doom-hi hover:decoration-doom-hi`,children:o}):/* @__PURE__ */ (0,n.jsx)(`code`,{...i,className:`${e??``} ${s} [pre_&]:bg-transparent [pre_&]:p-0 [pre_&]:text-doom-hi`,children:t})}function u({href:e,children:t}){let i=(0,r.useContext)(c),a=e;try{a=e===void 0?void 0:decodeURIComponent(e)}catch{a=void 0}let o=a!==void 0&&a!==``&&!/^(?:[a-z][a-z\d+.-]*:|\/\/|#|\?)/i.test(a)?i?.(a,!0):void 0;return o===void 0?/* @__PURE__ */ (0,n.jsx)(`a`,{href:e,target:`_blank`,rel:`noreferrer`,className:`text-doom-blue underline decoration-doom-blue/50`,children:t}):/* @__PURE__ */ (0,n.jsx)(`button`,{type:`button`,"data-testid":`markdown-file-link`,title:`open ${a}`,onClick:o,className:`text-doom-blue underline decoration-doom-blue/50`,children:t})}function d(e){return typeof e==`string`?e:Array.isArray(e)?e.map(e=>d(e)).join(``):``}function f({children:e}){let i=(0,r.isValidElement)(e)?e:void 0;return i===void 0?/* @__PURE__ */ (0,n.jsx)(`pre`,{className:`overflow-x-auto rounded border border-doom-border bg-doom-deep p-2.5 text-sm leading-relaxed`,children:e}):/* @__PURE__ */ (0,n.jsx)(t.CodeBlock,{text:d(i.props.children).replace(/\n$/,``),className:i.props.className})}const p={p:({children:e})=>/* @__PURE__ */ (0,n.jsx)(`p`,{className:`whitespace-pre-wrap break-words`,children:e}),strong:({children:e})=>/* @__PURE__ */ (0,n.jsx)(`strong`,{className:`font-bold text-doom-hi`,children:e}),em:({children:e})=>/* @__PURE__ */ (0,n.jsx)(`em`,{className:`italic`,children:e}),del:({children:e})=>/* @__PURE__ */ (0,n.jsx)(`del`,{className:`text-doom-dim line-through`,children:e}),a:u,code:l,pre:f,ul:({children:e})=>/* @__PURE__ */ (0,n.jsx)(`ul`,{className:`list-disc pl-5`,children:e}),ol:({children:e})=>/* @__PURE__ */ (0,n.jsx)(`ol`,{className:`list-decimal pl-5`,children:e}),li:({children:e})=>/* @__PURE__ */ (0,n.jsx)(`li`,{className:`whitespace-pre-wrap break-words`,children:e}),h1:({children:e})=>/* @__PURE__ */ (0,n.jsx)(`h1`,{className:`text-lg font-bold text-doom-hi`,children:e}),h2:({children:e})=>/* @__PURE__ */ (0,n.jsx)(`h2`,{className:`text-base font-bold text-doom-hi`,children:e}),h3:({children:e})=>/* @__PURE__ */ (0,n.jsx)(`h3`,{className:`text-base font-bold text-doom-hi`,children:e}),h4:({children:e})=>/* @__PURE__ */ (0,n.jsx)(`h4`,{className:`text-base font-bold text-doom-text`,children:e}),blockquote:({children:e})=>/* @__PURE__ */ (0,n.jsx)(`blockquote`,{className:`border-l-2 border-doom-border pl-3 text-doom-dim`,children:e}),hr:()=>/* @__PURE__ */ (0,n.jsx)(`hr`,{className:`border-doom-border-soft`}),table:({children:e})=>/* @__PURE__ */ (0,n.jsx)(`div`,{className:`overflow-x-auto`,children:/* @__PURE__ */ (0,n.jsx)(`table`,{className:`border-collapse text-sm`,children:e})}),th:({children:e})=>/* @__PURE__ */ (0,n.jsx)(`th`,{className:`border border-doom-border bg-doom-deep px-2 py-1 text-left font-bold text-doom-hi`,children:e}),td:({children:e})=>/* @__PURE__ */ (0,n.jsx)(`td`,{className:`border border-doom-border px-2 py-1 align-top`,children:e}),img:({src:e,alt:t})=>/* @__PURE__ */ (0,n.jsx)(`img`,{src:e,alt:t??``,className:`max-h-[480px] max-w-full rounded border border-doom-border`})};function m({text:e,onFileLink:t}){return/* @__PURE__ */ (0,n.jsx)(c.Provider,{value:t,children:/* @__PURE__ */ (0,n.jsx)(`div`,{className:`flex min-w-0 flex-col gap-2`,children:/* @__PURE__ */ (0,n.jsx)(i.default,{remarkPlugins:o,components:p,children:e})})})}exports.Markdown=m;
2
3
  //# sourceMappingURL=Markdown.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Markdown.cjs","names":["remarkGfm","ReactMarkdown"],"sources":["../../../src/components/Markdown.tsx"],"sourcesContent":["import type { ComponentProps } from 'react';\nimport ReactMarkdown, { type Components } from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\n\nconst REMARK_PLUGINS = [remarkGfm];\n\nfunction Code({ className, children, ...rest }: ComponentProps<'code'>) {\n return (\n <code\n {...rest}\n className={`${className ?? ''} rounded bg-doom-deep px-1 py-px font-mono text-[12px] text-doom-green [pre_&]:bg-transparent [pre_&]:p-0 [pre_&]:text-doom-hi`}\n >\n {children}\n </code>\n );\n}\n\nconst COMPONENTS: Components = {\n p: ({ children }) => <p className=\"whitespace-pre-wrap break-words\">{children}</p>,\n strong: ({ children }) => <strong className=\"font-bold text-doom-hi\">{children}</strong>,\n em: ({ children }) => <em className=\"italic\">{children}</em>,\n del: ({ children }) => <del className=\"text-doom-dim line-through\">{children}</del>,\n a: ({ href, children }) => (\n <a href={href} target=\"_blank\" rel=\"noreferrer\" className=\"text-doom-blue underline decoration-doom-blue/50\">\n {children}\n </a>\n ),\n code: Code,\n pre: ({ children }) => (\n <pre className=\"overflow-x-auto rounded border border-doom-border bg-doom-deep p-2.5 text-[12px] leading-relaxed\">\n {children}\n </pre>\n ),\n ul: ({ children }) => <ul className=\"list-disc pl-5\">{children}</ul>,\n ol: ({ children }) => <ol className=\"list-decimal pl-5\">{children}</ol>,\n li: ({ children }) => <li className=\"whitespace-pre-wrap break-words\">{children}</li>,\n h1: ({ children }) => <h1 className=\"text-[15px] font-bold text-doom-hi\">{children}</h1>,\n h2: ({ children }) => <h2 className=\"text-[14px] font-bold text-doom-hi\">{children}</h2>,\n h3: ({ children }) => <h3 className=\"text-[13px] font-bold text-doom-hi\">{children}</h3>,\n h4: ({ children }) => <h4 className=\"text-[13px] font-bold text-doom-text\">{children}</h4>,\n blockquote: ({ children }) => (\n <blockquote className=\"border-l-2 border-doom-border pl-3 text-doom-dim\">{children}</blockquote>\n ),\n hr: () => <hr className=\"border-doom-border-soft\" />,\n table: ({ children }) => (\n <div className=\"overflow-x-auto\">\n <table className=\"border-collapse text-[12px]\">{children}</table>\n </div>\n ),\n th: ({ children }) => (\n <th className=\"border border-doom-border bg-doom-deep px-2 py-1 text-left font-bold text-doom-hi\">{children}</th>\n ),\n td: ({ children }) => <td className=\"border border-doom-border px-2 py-1 align-top\">{children}</td>,\n img: ({ src, alt }) => (\n <img src={src} alt={alt ?? ''} className=\"max-h-[480px] max-w-full rounded border border-doom-border\" />\n ),\n};\n\n/** GitHub-flavored Markdown using the cockpit's safe, shared presentation. */\nexport function Markdown({ text }: { text: string }) {\n return (\n <div className=\"flex min-w-0 flex-col gap-2\">\n <ReactMarkdown remarkPlugins={REMARK_PLUGINS} components={COMPONENTS}>\n {text}\n </ReactMarkdown>\n </div>\n );\n}\n"],"mappings":"qLAIA,MAAM,EAAiB,CAACA,EAAAA,OAAS,EAEjC,SAAS,EAAK,CAAE,YAAW,WAAU,GAAG,GAAgC,CACtE,OACE,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,GAAI,EACJ,UAAW,GAAG,GAAa,GAAG,gIAE7B,UACG,CAAA,CAEV,CAEA,MAAM,EAAyB,CAC7B,GAAI,CAAE,eAAe,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAU,kCAAmC,UAAY,CAAA,EACjF,QAAS,CAAE,eAAe,EAAA,EAAA,IAAA,CAAC,SAAD,CAAQ,UAAU,yBAA0B,UAAiB,CAAA,EACvF,IAAK,CAAE,eAAe,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAU,SAAU,UAAa,CAAA,EAC3D,KAAM,CAAE,eAAe,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,6BAA8B,UAAc,CAAA,EAClF,GAAI,CAAE,OAAM,eACV,EAAA,EAAA,IAAA,CAAC,IAAD,CAAS,OAAM,OAAO,SAAS,IAAI,aAAa,UAAU,mDACvD,UACA,CAAA,EAEL,KAAM,EACN,KAAM,CAAE,eACN,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,mGACZ,UACE,CAAA,EAEP,IAAK,CAAE,eAAe,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAU,iBAAkB,UAAa,CAAA,EACnE,IAAK,CAAE,eAAe,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAU,oBAAqB,UAAa,CAAA,EACtE,IAAK,CAAE,eAAe,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAU,kCAAmC,UAAa,CAAA,EACpF,IAAK,CAAE,eAAe,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAU,qCAAsC,UAAa,CAAA,EACvF,IAAK,CAAE,eAAe,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAU,qCAAsC,UAAa,CAAA,EACvF,IAAK,CAAE,eAAe,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAU,qCAAsC,UAAa,CAAA,EACvF,IAAK,CAAE,eAAe,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAU,uCAAwC,UAAa,CAAA,EACzF,YAAa,CAAE,eACb,EAAA,EAAA,IAAA,CAAC,aAAD,CAAY,UAAU,mDAAoD,UAAqB,CAAA,EAEjG,QAAU,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAU,yBAA2B,CAAA,EACnD,OAAQ,CAAE,eACR,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,kBACb,UAAA,EAAA,EAAA,IAAA,CAAC,QAAD,CAAO,UAAU,8BAA+B,UAAgB,CAAA,CAC7D,CAAA,EAEP,IAAK,CAAE,eACL,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAU,oFAAqF,UAAa,CAAA,EAElH,IAAK,CAAE,eAAe,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAU,gDAAiD,UAAa,CAAA,EAClG,KAAM,CAAE,MAAK,UACX,EAAA,EAAA,IAAA,CAAC,MAAD,CAAU,MAAK,IAAK,GAAO,GAAI,UAAU,4DAA8D,CAAA,CAE3G,EAGA,SAAgB,EAAS,CAAE,QAA0B,CACnD,OACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,8BACb,UAAA,EAAA,EAAA,IAAA,CAACC,EAAAA,QAAD,CAAe,cAAe,EAAgB,WAAY,EACvD,SAAA,CACY,CAAA,CACZ,CAAA,CAET"}
1
+ {"version":3,"file":"Markdown.cjs","names":["remarkGfm","createContext","useContext","isValidElement","CodeBlock","ReactMarkdown"],"sources":["../../../src/components/Markdown.tsx"],"sourcesContent":["import { createContext, type ComponentProps, isValidElement, type ReactNode, useContext } from 'react';\nimport ReactMarkdown, { type Components } from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\n\nimport { CodeBlock } from './CodeBlock';\n\nconst REMARK_PLUGINS = [remarkGfm];\n\nconst CODE_CLASS = 'rounded bg-doom-deep px-1 py-px font-mono text-sm text-doom-green';\n\n/**\n * What a piece of inline code opens, when the host knows.\n *\n * Returning undefined leaves the span as plain code, which is the answer for\n * everything a message quotes that is not a file: a class name, a flag, a\n * command. The caller decides what counts, because only it knows which files\n * the session has.\n */\nexport type FileLinkHandler = (text: string, explicit?: boolean) => (() => void) | undefined;\n\n/**\n * Passed by context rather than as a component prop so the component map stays\n * a module constant. Rebuilding that map per render gives react-markdown new\n * component identities, which remounts the whole rendered tree on every frame\n * of a streaming reply.\n */\nconst FileLinkContext = createContext<FileLinkHandler | undefined>(undefined);\n\nfunction Code({ className, children, ...rest }: ComponentProps<'code'>) {\n const onFileLink = useContext(FileLinkContext);\n // Only a single-line span with no language class is a candidate: a fenced\n // block is content, not a reference, and its own renderer owns it.\n const label = typeof children === 'string' && !children.includes('\\n') ? children : undefined;\n const open = label === undefined || className !== undefined ? undefined : onFileLink?.(label);\n if (open !== undefined && label !== undefined) {\n return (\n <button\n type=\"button\"\n data-testid=\"markdown-file-link\"\n title={`open ${label}`}\n onClick={open}\n className={`${CODE_CLASS} cursor-pointer underline decoration-doom-green/40 underline-offset-2 hover:text-doom-hi hover:decoration-doom-hi`}\n >\n {label}\n </button>\n );\n }\n return (\n <code\n {...rest}\n className={`${className ?? ''} ${CODE_CLASS} [pre_&]:bg-transparent [pre_&]:p-0 [pre_&]:text-doom-hi`}\n >\n {children}\n </code>\n );\n}\n\nfunction Link({ href, children }: ComponentProps<'a'>) {\n const onFileLink = useContext(FileLinkContext);\n let path = href;\n try {\n path = href === undefined ? undefined : decodeURIComponent(href);\n } catch {\n path = undefined;\n }\n const isFile = path !== undefined && path !== '' && !/^(?:[a-z][a-z\\d+.-]*:|\\/\\/|#|\\?)/i.test(path);\n const open = isFile ? onFileLink?.(path!, true) : undefined;\n if (open !== undefined)\n return (\n <button\n type=\"button\"\n data-testid=\"markdown-file-link\"\n title={`open ${path}`}\n onClick={open}\n className=\"text-doom-blue underline decoration-doom-blue/50\"\n >\n {children}\n </button>\n );\n return (\n <a href={href} target=\"_blank\" rel=\"noreferrer\" className=\"text-doom-blue underline decoration-doom-blue/50\">\n {children}\n </a>\n );\n}\n\n/** The text inside a fence, which react-markdown hands over as nested strings. */\nfunction textOf(children: ReactNode): string {\n if (typeof children === 'string') return children;\n if (Array.isArray(children)) return children.map((child) => textOf(child as ReactNode)).join('');\n return '';\n}\n\n/**\n * A fenced block, read off the <code> child that carries its language.\n *\n * The block is handed to `CodeBlock` whole rather than rendered as a styled\n * <pre> around inline code, because a fence is content with its own\n * presentation: it is coloured, it can be copied, and a mermaid fence is a\n * picture. A <pre> that came from raw HTML has no such child and keeps the\n * plain box.\n */\nfunction Pre({ children }: ComponentProps<'pre'>) {\n const code = isValidElement<{ className?: string; children?: ReactNode }>(children) ? children : undefined;\n if (code === undefined)\n return (\n <pre className=\"overflow-x-auto rounded border border-doom-border bg-doom-deep p-2.5 text-sm leading-relaxed\">\n {children}\n </pre>\n );\n // Markdown ends every fence with a newline the author did not type.\n return <CodeBlock text={textOf(code.props.children).replace(/\\n$/, '')} className={code.props.className} />;\n}\nconst COMPONENTS: Components = {\n p: ({ children }) => <p className=\"whitespace-pre-wrap break-words\">{children}</p>,\n strong: ({ children }) => <strong className=\"font-bold text-doom-hi\">{children}</strong>,\n em: ({ children }) => <em className=\"italic\">{children}</em>,\n del: ({ children }) => <del className=\"text-doom-dim line-through\">{children}</del>,\n a: Link,\n code: Code,\n pre: Pre,\n ul: ({ children }) => <ul className=\"list-disc pl-5\">{children}</ul>,\n ol: ({ children }) => <ol className=\"list-decimal pl-5\">{children}</ol>,\n li: ({ children }) => <li className=\"whitespace-pre-wrap break-words\">{children}</li>,\n h1: ({ children }) => <h1 className=\"text-lg font-bold text-doom-hi\">{children}</h1>,\n h2: ({ children }) => <h2 className=\"text-base font-bold text-doom-hi\">{children}</h2>,\n h3: ({ children }) => <h3 className=\"text-base font-bold text-doom-hi\">{children}</h3>,\n h4: ({ children }) => <h4 className=\"text-base font-bold text-doom-text\">{children}</h4>,\n blockquote: ({ children }) => (\n <blockquote className=\"border-l-2 border-doom-border pl-3 text-doom-dim\">{children}</blockquote>\n ),\n hr: () => <hr className=\"border-doom-border-soft\" />,\n table: ({ children }) => (\n <div className=\"overflow-x-auto\">\n <table className=\"border-collapse text-sm\">{children}</table>\n </div>\n ),\n th: ({ children }) => (\n <th className=\"border border-doom-border bg-doom-deep px-2 py-1 text-left font-bold text-doom-hi\">{children}</th>\n ),\n td: ({ children }) => <td className=\"border border-doom-border px-2 py-1 align-top\">{children}</td>,\n img: ({ src, alt }) => (\n <img src={src} alt={alt ?? ''} className=\"max-h-[480px] max-w-full rounded border border-doom-border\" />\n ),\n};\n\n/** GitHub-flavored Markdown using the cockpit's safe, shared presentation. */\nexport function Markdown({ text, onFileLink }: { text: string; onFileLink?: FileLinkHandler }) {\n return (\n <FileLinkContext.Provider value={onFileLink}>\n <div className=\"flex min-w-0 flex-col gap-2\">\n <ReactMarkdown remarkPlugins={REMARK_PLUGINS} components={COMPONENTS}>\n {text}\n </ReactMarkdown>\n </div>\n </FileLinkContext.Provider>\n );\n}\n"],"mappings":"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"}
@@ -1,8 +1,17 @@
1
1
  //#region src/components/Markdown.d.ts
2
+ /**
3
+ * What a piece of inline code opens, when the host knows.
4
+ *
5
+ * Returning undefined leaves the span as plain code, which is the answer for
6
+ * everything a message quotes that is not a file: a class name, a flag, a
7
+ * command. The caller decides what counts, because only it knows which files
8
+ * the session has.
9
+ */
10
+ export type FileLinkHandler = (text: string, explicit?: boolean) => (() => void) | undefined;
2
11
  /** GitHub-flavored Markdown using the cockpit's safe, shared presentation. */
3
- declare function Markdown({ text }: {
12
+ export declare function Markdown({ text, onFileLink }: {
4
13
  text: string;
5
- }): import("react/jsx-runtime").JSX.Element;
14
+ onFileLink?: FileLinkHandler;
15
+ }): import("react").JSX.Element;
6
16
  //#endregion
7
- export { Markdown };
8
17
  //# sourceMappingURL=Markdown.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Markdown.d.mts","names":[],"sources":["../../../src/components/Markdown.tsx"],"mappings":";;iBA2DgB,WAAW;EAAU;gCAAc,IAAA"}
1
+ {"version":3,"file":"Markdown.d.mts","names":[],"sources":["../../../src/components/Markdown.tsx"],"mappings":";;;;;;;;;YAkBY,mBAAmB,cAAc;;wBAiI7B,WAAW,MAAM;EAAgB;EAAc,aAAa;oBAAiB,IAAA"}
@@ -1,2 +1,3 @@
1
- import{jsx as e}from"react/jsx-runtime";import t from"react-markdown";import n from"remark-gfm";const r=[n];function i({className:t,children:n,...r}){return e(`code`,{...r,className:`${t??``} rounded bg-doom-deep px-1 py-px font-mono text-[12px] text-doom-green [pre_&]:bg-transparent [pre_&]:p-0 [pre_&]:text-doom-hi`,children:n})}const a={p:({children:t})=>e(`p`,{className:`whitespace-pre-wrap break-words`,children:t}),strong:({children:t})=>e(`strong`,{className:`font-bold text-doom-hi`,children:t}),em:({children:t})=>e(`em`,{className:`italic`,children:t}),del:({children:t})=>e(`del`,{className:`text-doom-dim line-through`,children:t}),a:({href:t,children:n})=>e(`a`,{href:t,target:`_blank`,rel:`noreferrer`,className:`text-doom-blue underline decoration-doom-blue/50`,children:n}),code:i,pre:({children:t})=>e(`pre`,{className:`overflow-x-auto rounded border border-doom-border bg-doom-deep p-2.5 text-[12px] leading-relaxed`,children:t}),ul:({children:t})=>e(`ul`,{className:`list-disc pl-5`,children:t}),ol:({children:t})=>e(`ol`,{className:`list-decimal pl-5`,children:t}),li:({children:t})=>e(`li`,{className:`whitespace-pre-wrap break-words`,children:t}),h1:({children:t})=>e(`h1`,{className:`text-[15px] font-bold text-doom-hi`,children:t}),h2:({children:t})=>e(`h2`,{className:`text-[14px] font-bold text-doom-hi`,children:t}),h3:({children:t})=>e(`h3`,{className:`text-[13px] font-bold text-doom-hi`,children:t}),h4:({children:t})=>e(`h4`,{className:`text-[13px] font-bold text-doom-text`,children:t}),blockquote:({children:t})=>e(`blockquote`,{className:`border-l-2 border-doom-border pl-3 text-doom-dim`,children:t}),hr:()=>e(`hr`,{className:`border-doom-border-soft`}),table:({children:t})=>e(`div`,{className:`overflow-x-auto`,children:e(`table`,{className:`border-collapse text-[12px]`,children:t})}),th:({children:t})=>e(`th`,{className:`border border-doom-border bg-doom-deep px-2 py-1 text-left font-bold text-doom-hi`,children:t}),td:({children:t})=>e(`td`,{className:`border border-doom-border px-2 py-1 align-top`,children:t}),img:({src:t,alt:n})=>e(`img`,{src:t,alt:n??``,className:`max-h-[480px] max-w-full rounded border border-doom-border`})};function o({text:n}){return e(`div`,{className:`flex min-w-0 flex-col gap-2`,children:e(t,{remarkPlugins:r,components:a,children:n})})}export{o as Markdown};
1
+ import{CodeBlock as e}from"./CodeBlock.mjs";import{jsx as t}from"react/jsx-runtime";import{createContext as n,isValidElement as r,useContext as i}from"react";import a from"react-markdown";import o from"remark-gfm";const s=[o],c=`rounded bg-doom-deep px-1 py-px font-mono text-sm text-doom-green`,l=n(void 0);function u({className:e,children:n,...r}){let a=i(l),o=typeof n==`string`&&!n.includes(`
2
+ `)?n:void 0,s=o===void 0||e!==void 0?void 0:a?.(o);return s!==void 0&&o!==void 0?/* @__PURE__ */ t(`button`,{type:`button`,"data-testid":`markdown-file-link`,title:`open ${o}`,onClick:s,className:`${c} cursor-pointer underline decoration-doom-green/40 underline-offset-2 hover:text-doom-hi hover:decoration-doom-hi`,children:o}):/* @__PURE__ */ t(`code`,{...r,className:`${e??``} ${c} [pre_&]:bg-transparent [pre_&]:p-0 [pre_&]:text-doom-hi`,children:n})}function d({href:e,children:n}){let r=i(l),a=e;try{a=e===void 0?void 0:decodeURIComponent(e)}catch{a=void 0}let o=a!==void 0&&a!==``&&!/^(?:[a-z][a-z\d+.-]*:|\/\/|#|\?)/i.test(a)?r?.(a,!0):void 0;return o===void 0?/* @__PURE__ */ t(`a`,{href:e,target:`_blank`,rel:`noreferrer`,className:`text-doom-blue underline decoration-doom-blue/50`,children:n}):/* @__PURE__ */ t(`button`,{type:`button`,"data-testid":`markdown-file-link`,title:`open ${a}`,onClick:o,className:`text-doom-blue underline decoration-doom-blue/50`,children:n})}function f(e){return typeof e==`string`?e:Array.isArray(e)?e.map(e=>f(e)).join(``):``}function p({children:n}){let i=r(n)?n:void 0;return i===void 0?/* @__PURE__ */ t(`pre`,{className:`overflow-x-auto rounded border border-doom-border bg-doom-deep p-2.5 text-sm leading-relaxed`,children:n}):/* @__PURE__ */ t(e,{text:f(i.props.children).replace(/\n$/,``),className:i.props.className})}const m={p:({children:e})=>/* @__PURE__ */ t(`p`,{className:`whitespace-pre-wrap break-words`,children:e}),strong:({children:e})=>/* @__PURE__ */ t(`strong`,{className:`font-bold text-doom-hi`,children:e}),em:({children:e})=>/* @__PURE__ */ t(`em`,{className:`italic`,children:e}),del:({children:e})=>/* @__PURE__ */ t(`del`,{className:`text-doom-dim line-through`,children:e}),a:d,code:u,pre:p,ul:({children:e})=>/* @__PURE__ */ t(`ul`,{className:`list-disc pl-5`,children:e}),ol:({children:e})=>/* @__PURE__ */ t(`ol`,{className:`list-decimal pl-5`,children:e}),li:({children:e})=>/* @__PURE__ */ t(`li`,{className:`whitespace-pre-wrap break-words`,children:e}),h1:({children:e})=>/* @__PURE__ */ t(`h1`,{className:`text-lg font-bold text-doom-hi`,children:e}),h2:({children:e})=>/* @__PURE__ */ t(`h2`,{className:`text-base font-bold text-doom-hi`,children:e}),h3:({children:e})=>/* @__PURE__ */ t(`h3`,{className:`text-base font-bold text-doom-hi`,children:e}),h4:({children:e})=>/* @__PURE__ */ t(`h4`,{className:`text-base font-bold text-doom-text`,children:e}),blockquote:({children:e})=>/* @__PURE__ */ t(`blockquote`,{className:`border-l-2 border-doom-border pl-3 text-doom-dim`,children:e}),hr:()=>/* @__PURE__ */ t(`hr`,{className:`border-doom-border-soft`}),table:({children:e})=>/* @__PURE__ */ t(`div`,{className:`overflow-x-auto`,children:/* @__PURE__ */ t(`table`,{className:`border-collapse text-sm`,children:e})}),th:({children:e})=>/* @__PURE__ */ t(`th`,{className:`border border-doom-border bg-doom-deep px-2 py-1 text-left font-bold text-doom-hi`,children:e}),td:({children:e})=>/* @__PURE__ */ t(`td`,{className:`border border-doom-border px-2 py-1 align-top`,children:e}),img:({src:e,alt:n})=>/* @__PURE__ */ t(`img`,{src:e,alt:n??``,className:`max-h-[480px] max-w-full rounded border border-doom-border`})};function h({text:e,onFileLink:n}){return/* @__PURE__ */ t(l.Provider,{value:n,children:/* @__PURE__ */ t(`div`,{className:`flex min-w-0 flex-col gap-2`,children:/* @__PURE__ */ t(a,{remarkPlugins:s,components:m,children:e})})})}export{h as Markdown};
2
3
  //# sourceMappingURL=Markdown.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Markdown.mjs","names":[],"sources":["../../../src/components/Markdown.tsx"],"sourcesContent":["import type { ComponentProps } from 'react';\nimport ReactMarkdown, { type Components } from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\n\nconst REMARK_PLUGINS = [remarkGfm];\n\nfunction Code({ className, children, ...rest }: ComponentProps<'code'>) {\n return (\n <code\n {...rest}\n className={`${className ?? ''} rounded bg-doom-deep px-1 py-px font-mono text-[12px] text-doom-green [pre_&]:bg-transparent [pre_&]:p-0 [pre_&]:text-doom-hi`}\n >\n {children}\n </code>\n );\n}\n\nconst COMPONENTS: Components = {\n p: ({ children }) => <p className=\"whitespace-pre-wrap break-words\">{children}</p>,\n strong: ({ children }) => <strong className=\"font-bold text-doom-hi\">{children}</strong>,\n em: ({ children }) => <em className=\"italic\">{children}</em>,\n del: ({ children }) => <del className=\"text-doom-dim line-through\">{children}</del>,\n a: ({ href, children }) => (\n <a href={href} target=\"_blank\" rel=\"noreferrer\" className=\"text-doom-blue underline decoration-doom-blue/50\">\n {children}\n </a>\n ),\n code: Code,\n pre: ({ children }) => (\n <pre className=\"overflow-x-auto rounded border border-doom-border bg-doom-deep p-2.5 text-[12px] leading-relaxed\">\n {children}\n </pre>\n ),\n ul: ({ children }) => <ul className=\"list-disc pl-5\">{children}</ul>,\n ol: ({ children }) => <ol className=\"list-decimal pl-5\">{children}</ol>,\n li: ({ children }) => <li className=\"whitespace-pre-wrap break-words\">{children}</li>,\n h1: ({ children }) => <h1 className=\"text-[15px] font-bold text-doom-hi\">{children}</h1>,\n h2: ({ children }) => <h2 className=\"text-[14px] font-bold text-doom-hi\">{children}</h2>,\n h3: ({ children }) => <h3 className=\"text-[13px] font-bold text-doom-hi\">{children}</h3>,\n h4: ({ children }) => <h4 className=\"text-[13px] font-bold text-doom-text\">{children}</h4>,\n blockquote: ({ children }) => (\n <blockquote className=\"border-l-2 border-doom-border pl-3 text-doom-dim\">{children}</blockquote>\n ),\n hr: () => <hr className=\"border-doom-border-soft\" />,\n table: ({ children }) => (\n <div className=\"overflow-x-auto\">\n <table className=\"border-collapse text-[12px]\">{children}</table>\n </div>\n ),\n th: ({ children }) => (\n <th className=\"border border-doom-border bg-doom-deep px-2 py-1 text-left font-bold text-doom-hi\">{children}</th>\n ),\n td: ({ children }) => <td className=\"border border-doom-border px-2 py-1 align-top\">{children}</td>,\n img: ({ src, alt }) => (\n <img src={src} alt={alt ?? ''} className=\"max-h-[480px] max-w-full rounded border border-doom-border\" />\n ),\n};\n\n/** GitHub-flavored Markdown using the cockpit's safe, shared presentation. */\nexport function Markdown({ text }: { text: string }) {\n return (\n <div className=\"flex min-w-0 flex-col gap-2\">\n <ReactMarkdown remarkPlugins={REMARK_PLUGINS} components={COMPONENTS}>\n {text}\n </ReactMarkdown>\n </div>\n );\n}\n"],"mappings":"gGAIA,MAAM,EAAiB,CAAC,CAAS,EAEjC,SAAS,EAAK,CAAE,YAAW,WAAU,GAAG,GAAgC,CACtE,OACE,EAAC,OAAD,CACE,GAAI,EACJ,UAAW,GAAG,GAAa,GAAG,gIAE7B,UACG,CAAA,CAEV,CAEA,MAAM,EAAyB,CAC7B,GAAI,CAAE,cAAe,EAAC,IAAD,CAAG,UAAU,kCAAmC,UAAY,CAAA,EACjF,QAAS,CAAE,cAAe,EAAC,SAAD,CAAQ,UAAU,yBAA0B,UAAiB,CAAA,EACvF,IAAK,CAAE,cAAe,EAAC,KAAD,CAAI,UAAU,SAAU,UAAa,CAAA,EAC3D,KAAM,CAAE,cAAe,EAAC,MAAD,CAAK,UAAU,6BAA8B,UAAc,CAAA,EAClF,GAAI,CAAE,OAAM,cACV,EAAC,IAAD,CAAS,OAAM,OAAO,SAAS,IAAI,aAAa,UAAU,mDACvD,UACA,CAAA,EAEL,KAAM,EACN,KAAM,CAAE,cACN,EAAC,MAAD,CAAK,UAAU,mGACZ,UACE,CAAA,EAEP,IAAK,CAAE,cAAe,EAAC,KAAD,CAAI,UAAU,iBAAkB,UAAa,CAAA,EACnE,IAAK,CAAE,cAAe,EAAC,KAAD,CAAI,UAAU,oBAAqB,UAAa,CAAA,EACtE,IAAK,CAAE,cAAe,EAAC,KAAD,CAAI,UAAU,kCAAmC,UAAa,CAAA,EACpF,IAAK,CAAE,cAAe,EAAC,KAAD,CAAI,UAAU,qCAAsC,UAAa,CAAA,EACvF,IAAK,CAAE,cAAe,EAAC,KAAD,CAAI,UAAU,qCAAsC,UAAa,CAAA,EACvF,IAAK,CAAE,cAAe,EAAC,KAAD,CAAI,UAAU,qCAAsC,UAAa,CAAA,EACvF,IAAK,CAAE,cAAe,EAAC,KAAD,CAAI,UAAU,uCAAwC,UAAa,CAAA,EACzF,YAAa,CAAE,cACb,EAAC,aAAD,CAAY,UAAU,mDAAoD,UAAqB,CAAA,EAEjG,OAAU,EAAC,KAAD,CAAI,UAAU,yBAA2B,CAAA,EACnD,OAAQ,CAAE,cACR,EAAC,MAAD,CAAK,UAAU,kBACb,SAAA,EAAC,QAAD,CAAO,UAAU,8BAA+B,UAAgB,CAAA,CAC7D,CAAA,EAEP,IAAK,CAAE,cACL,EAAC,KAAD,CAAI,UAAU,oFAAqF,UAAa,CAAA,EAElH,IAAK,CAAE,cAAe,EAAC,KAAD,CAAI,UAAU,gDAAiD,UAAa,CAAA,EAClG,KAAM,CAAE,MAAK,SACX,EAAC,MAAD,CAAU,MAAK,IAAK,GAAO,GAAI,UAAU,4DAA8D,CAAA,CAE3G,EAGA,SAAgB,EAAS,CAAE,QAA0B,CACnD,OACE,EAAC,MAAD,CAAK,UAAU,8BACb,SAAA,EAAC,EAAD,CAAe,cAAe,EAAgB,WAAY,EACvD,SAAA,CACY,CAAA,CACZ,CAAA,CAET"}
1
+ {"version":3,"file":"Markdown.mjs","names":[],"sources":["../../../src/components/Markdown.tsx"],"sourcesContent":["import { createContext, type ComponentProps, isValidElement, type ReactNode, useContext } from 'react';\nimport ReactMarkdown, { type Components } from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\n\nimport { CodeBlock } from './CodeBlock';\n\nconst REMARK_PLUGINS = [remarkGfm];\n\nconst CODE_CLASS = 'rounded bg-doom-deep px-1 py-px font-mono text-sm text-doom-green';\n\n/**\n * What a piece of inline code opens, when the host knows.\n *\n * Returning undefined leaves the span as plain code, which is the answer for\n * everything a message quotes that is not a file: a class name, a flag, a\n * command. The caller decides what counts, because only it knows which files\n * the session has.\n */\nexport type FileLinkHandler = (text: string, explicit?: boolean) => (() => void) | undefined;\n\n/**\n * Passed by context rather than as a component prop so the component map stays\n * a module constant. Rebuilding that map per render gives react-markdown new\n * component identities, which remounts the whole rendered tree on every frame\n * of a streaming reply.\n */\nconst FileLinkContext = createContext<FileLinkHandler | undefined>(undefined);\n\nfunction Code({ className, children, ...rest }: ComponentProps<'code'>) {\n const onFileLink = useContext(FileLinkContext);\n // Only a single-line span with no language class is a candidate: a fenced\n // block is content, not a reference, and its own renderer owns it.\n const label = typeof children === 'string' && !children.includes('\\n') ? children : undefined;\n const open = label === undefined || className !== undefined ? undefined : onFileLink?.(label);\n if (open !== undefined && label !== undefined) {\n return (\n <button\n type=\"button\"\n data-testid=\"markdown-file-link\"\n title={`open ${label}`}\n onClick={open}\n className={`${CODE_CLASS} cursor-pointer underline decoration-doom-green/40 underline-offset-2 hover:text-doom-hi hover:decoration-doom-hi`}\n >\n {label}\n </button>\n );\n }\n return (\n <code\n {...rest}\n className={`${className ?? ''} ${CODE_CLASS} [pre_&]:bg-transparent [pre_&]:p-0 [pre_&]:text-doom-hi`}\n >\n {children}\n </code>\n );\n}\n\nfunction Link({ href, children }: ComponentProps<'a'>) {\n const onFileLink = useContext(FileLinkContext);\n let path = href;\n try {\n path = href === undefined ? undefined : decodeURIComponent(href);\n } catch {\n path = undefined;\n }\n const isFile = path !== undefined && path !== '' && !/^(?:[a-z][a-z\\d+.-]*:|\\/\\/|#|\\?)/i.test(path);\n const open = isFile ? onFileLink?.(path!, true) : undefined;\n if (open !== undefined)\n return (\n <button\n type=\"button\"\n data-testid=\"markdown-file-link\"\n title={`open ${path}`}\n onClick={open}\n className=\"text-doom-blue underline decoration-doom-blue/50\"\n >\n {children}\n </button>\n );\n return (\n <a href={href} target=\"_blank\" rel=\"noreferrer\" className=\"text-doom-blue underline decoration-doom-blue/50\">\n {children}\n </a>\n );\n}\n\n/** The text inside a fence, which react-markdown hands over as nested strings. */\nfunction textOf(children: ReactNode): string {\n if (typeof children === 'string') return children;\n if (Array.isArray(children)) return children.map((child) => textOf(child as ReactNode)).join('');\n return '';\n}\n\n/**\n * A fenced block, read off the <code> child that carries its language.\n *\n * The block is handed to `CodeBlock` whole rather than rendered as a styled\n * <pre> around inline code, because a fence is content with its own\n * presentation: it is coloured, it can be copied, and a mermaid fence is a\n * picture. A <pre> that came from raw HTML has no such child and keeps the\n * plain box.\n */\nfunction Pre({ children }: ComponentProps<'pre'>) {\n const code = isValidElement<{ className?: string; children?: ReactNode }>(children) ? children : undefined;\n if (code === undefined)\n return (\n <pre className=\"overflow-x-auto rounded border border-doom-border bg-doom-deep p-2.5 text-sm leading-relaxed\">\n {children}\n </pre>\n );\n // Markdown ends every fence with a newline the author did not type.\n return <CodeBlock text={textOf(code.props.children).replace(/\\n$/, '')} className={code.props.className} />;\n}\nconst COMPONENTS: Components = {\n p: ({ children }) => <p className=\"whitespace-pre-wrap break-words\">{children}</p>,\n strong: ({ children }) => <strong className=\"font-bold text-doom-hi\">{children}</strong>,\n em: ({ children }) => <em className=\"italic\">{children}</em>,\n del: ({ children }) => <del className=\"text-doom-dim line-through\">{children}</del>,\n a: Link,\n code: Code,\n pre: Pre,\n ul: ({ children }) => <ul className=\"list-disc pl-5\">{children}</ul>,\n ol: ({ children }) => <ol className=\"list-decimal pl-5\">{children}</ol>,\n li: ({ children }) => <li className=\"whitespace-pre-wrap break-words\">{children}</li>,\n h1: ({ children }) => <h1 className=\"text-lg font-bold text-doom-hi\">{children}</h1>,\n h2: ({ children }) => <h2 className=\"text-base font-bold text-doom-hi\">{children}</h2>,\n h3: ({ children }) => <h3 className=\"text-base font-bold text-doom-hi\">{children}</h3>,\n h4: ({ children }) => <h4 className=\"text-base font-bold text-doom-text\">{children}</h4>,\n blockquote: ({ children }) => (\n <blockquote className=\"border-l-2 border-doom-border pl-3 text-doom-dim\">{children}</blockquote>\n ),\n hr: () => <hr className=\"border-doom-border-soft\" />,\n table: ({ children }) => (\n <div className=\"overflow-x-auto\">\n <table className=\"border-collapse text-sm\">{children}</table>\n </div>\n ),\n th: ({ children }) => (\n <th className=\"border border-doom-border bg-doom-deep px-2 py-1 text-left font-bold text-doom-hi\">{children}</th>\n ),\n td: ({ children }) => <td className=\"border border-doom-border px-2 py-1 align-top\">{children}</td>,\n img: ({ src, alt }) => (\n <img src={src} alt={alt ?? ''} className=\"max-h-[480px] max-w-full rounded border border-doom-border\" />\n ),\n};\n\n/** GitHub-flavored Markdown using the cockpit's safe, shared presentation. */\nexport function Markdown({ text, onFileLink }: { text: string; onFileLink?: FileLinkHandler }) {\n return (\n <FileLinkContext.Provider value={onFileLink}>\n <div className=\"flex min-w-0 flex-col gap-2\">\n <ReactMarkdown remarkPlugins={REMARK_PLUGINS} components={COMPONENTS}>\n {text}\n </ReactMarkdown>\n </div>\n </FileLinkContext.Provider>\n );\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- require("../icons/icons.cjs");const e=require("../lib/cn.cjs"),t=require("./Badge.cjs"),n=require("../lib/media.cjs");let r=require("react/jsx-runtime"),i=require("lucide-react");const a=`max-w-full rounded border border-doom-border bg-doom-deep`;function o({src:o,path:s,kind:c,className:l,"data-testid":u}){let d=c??n.mediaKindOf(s),f=s.split(`/`).at(-1)??s;return d===`image`?(0,r.jsx)(`a`,{href:o,target:`_blank`,rel:`noreferrer`,"data-testid":u,"data-kind":d,children:(0,r.jsx)(`img`,{src:o,alt:s,className:e.cn(a,`max-h-[36rem]`,l)})}):d===`video`?(0,r.jsx)(`video`,{src:o,controls:!0,preload:`metadata`,"data-testid":u,"data-kind":d,className:e.cn(a,`max-h-[36rem]`,l)}):d===`pdf`?(0,r.jsx)(`iframe`,{src:o,title:s,"data-testid":u,"data-kind":d,className:e.cn(a,`h-[36rem] w-full`,l)}):(0,r.jsx)(t.Badge,{asChild:!0,size:`md`,"data-testid":u,"data-kind":d,className:e.cn(`self-start bg-doom-panel text-doom-text hover:border-doom-blue/50`,l),children:(0,r.jsxs)(`a`,{href:o,download:f,children:[(0,r.jsx)(i.FileText,{className:`h-3 w-3 shrink-0 text-doom-faint`}),`download `,f]})})}exports.MediaPreview=o;
1
+ require("../icons/icons.cjs");const e=require("../lib/cn.cjs"),t=require("./Badge.cjs"),n=require("../lib/media.cjs"),r=require("../lib/mediaPlayback.cjs"),i=require("./PdfPreview.cjs");let a=require("react/jsx-runtime"),o=require("react"),s=require("lucide-react");const c=`max-w-full rounded border border-doom-border bg-doom-deep`;function l(e){return{playing:!e.paused&&!e.ended,currentTime:e.currentTime,duration:Number.isFinite(e.duration)?e.duration:0}}function u(e,t={current:void 0}){return{play:async()=>{let t=e.current;t!==null&&await t.play()},pause:()=>e.current?.pause(),seek:t=>{let n=e.current;n!==null&&(n.currentTime=r.boundedMediaTime(t,n.duration))},getState:()=>{let t=e.current;return t===null?{playing:!1,currentTime:0,duration:0}:l(t)},isFrameReady:()=>{let n=e.current;return n!==null&&!n.seeking&&n.readyState>=2&&(n.requestVideoFrameCallback===void 0||t.current!==void 0)},getIntrinsicSize:()=>{let t=e.current;return t===null||t.videoWidth<=0||t.videoHeight<=0?null:{width:t.videoWidth,height:t.videoHeight}},captureFrame:async(n=`image/png`,r)=>{let i=e.current;if(i===null||i.videoWidth<=0||i.videoHeight<=0||i.seeking)return null;let a=t.current===void 0?void 0:{...t.current},o=a?.mediaTime??i.currentTime,s=document.createElement(`canvas`);s.width=i.videoWidth,s.height=i.videoHeight;let c=s.getContext(`2d`);if(c===null)return null;c.drawImage(i,0,0,s.width,s.height);let l=await new Promise(e=>s.toBlob(e,n,r));return l===null?null:{blob:l,width:s.width,height:s.height,timeSeconds:o,...a===void 0?{}:{metadata:a}}}}}function d({src:t,className:n,testId:r,controllerRef:i,onPlaybackStateChange:s,videoControls:d=!0}){let f=(0,o.useRef)(null),p=(0,o.useRef)(void 0),m=()=>{let e=f.current;e!==null&&s?.(l(e))},h=(0,o.useRef)(m);return(0,o.useEffect)(()=>{h.current=m}),(0,o.useImperativeHandle)(i,()=>u(f,p),[]),(0,o.useEffect)(()=>{let e=f.current;if(e===null||e.requestVideoFrameCallback===void 0)return;let t=0,n=(r,i)=>{p.current={mediaTime:i.mediaTime,...Number.isFinite(i.presentedFrames)?{presentedFrames:i.presentedFrames}:{}},h.current(),t=e.requestVideoFrameCallback(n)};return t=e.requestVideoFrameCallback(n),()=>e.cancelVideoFrameCallback(t)},[]),/* @__PURE__ */ (0,a.jsx)(`video`,{ref:f,src:t,controls:d,playsInline:!0,preload:`metadata`,"data-testid":r,"data-kind":`video`,className:e.cn(c,`max-h-[36rem]`,n),onPlay:m,onPause:m,onTimeUpdate:m,onDurationChange:m,onEnded:m,onLoadedMetadata:m,onLoadedData:m,onSeeking:()=>{p.current=void 0,m()},onSeeked:m,children:/* @__PURE__ */ (0,a.jsx)(`track`,{kind:`captions`})})}function f({src:r,path:o,kind:l,className:u,controllerRef:f,pdfControllerRef:p,onPlaybackStateChange:m,videoControls:h,"data-testid":g}){let _=l??n.mediaKindOf(o),v=o.split(`/`).at(-1)??o;return _===`image`?/* @__PURE__ */ (0,a.jsx)(`a`,{href:r,target:`_blank`,rel:`noreferrer`,"data-testid":g,"data-kind":_,children:/* @__PURE__ */ (0,a.jsx)(`img`,{src:r,alt:o,className:e.cn(c,`max-h-[36rem]`,u)})}):_===`video`?/* @__PURE__ */ (0,a.jsx)(d,{src:r,className:u,controllerRef:f,onPlaybackStateChange:m,testId:g,videoControls:h}):_===`pdf`?/* @__PURE__ */ (0,a.jsx)(i.PdfPreview,{src:r,path:o,controllerRef:p,"data-testid":g,className:u}):/* @__PURE__ */ (0,a.jsx)(t.Badge,{asChild:!0,size:`md`,"data-testid":g,"data-kind":_,className:e.cn(`self-start bg-doom-panel text-doom-text hover:border-doom-blue/50`,u),children:/* @__PURE__ */ (0,a.jsxs)(`a`,{href:r,download:v,children:[/* @__PURE__ */ (0,a.jsx)(s.FileText,{className:`h-3 w-3 shrink-0 text-doom-faint`}),`download `,v]})})}exports.MediaPreview=f,exports.mediaPlaybackState=l,exports.mediaPreviewController=u;
2
2
  //# sourceMappingURL=MediaPreview.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"MediaPreview.cjs","names":["mediaKindOf","cn","Badge","FileIcon"],"sources":["../../../src/components/MediaPreview.tsx"],"sourcesContent":["import { FileIcon } from '../icons/icons.ts';\nimport { cn } from '../lib/cn.ts';\nimport { mediaKindOf } from '../lib/media.ts';\nimport type { MediaKind } from '../types/editor.ts';\nimport { Badge } from './Badge.tsx';\n\n/**\n * A file the browser can show but not edit.\n *\n * It renders bytes a server is already serving, so the caller supplies the\n * URL and this decides only which element reads it. Everything the browser\n * cannot render is a download rather than a converted approximation: a `.docx`\n * turned into HTML is a different document, and offering to edit that one\n * would be offering to overwrite the real one with it.\n */\n\nexport interface MediaPreviewProps {\n /** Where the bytes are served from. */\n src: string;\n /** The file's path, used for the accessible name and the download name. */\n path: string;\n /** Overrides the kind inferred from the path, for a server that knows better. */\n kind?: MediaKind;\n className?: string;\n 'data-testid'?: string;\n}\n\nconst FRAME = 'max-w-full rounded border border-doom-border bg-doom-deep';\n\nexport function MediaPreview({ src, path, kind, className, 'data-testid': testId }: MediaPreviewProps) {\n const resolved = kind ?? mediaKindOf(path);\n const name = path.split('/').at(-1) ?? path;\n\n if (resolved === 'image') {\n return (\n <a href={src} target=\"_blank\" rel=\"noreferrer\" data-testid={testId} data-kind={resolved}>\n <img src={src} alt={path} className={cn(FRAME, 'max-h-[36rem]', className)} />\n </a>\n );\n }\n if (resolved === 'video') {\n return (\n <video\n src={src}\n controls\n preload=\"metadata\"\n data-testid={testId}\n data-kind={resolved}\n className={cn(FRAME, 'max-h-[36rem]', className)}\n />\n );\n }\n if (resolved === 'pdf') {\n return (\n <iframe\n src={src}\n title={path}\n data-testid={testId}\n data-kind={resolved}\n className={cn(FRAME, 'h-[36rem] w-full', className)}\n />\n );\n }\n return (\n <Badge\n asChild\n size=\"md\"\n data-testid={testId}\n data-kind={resolved}\n className={cn('self-start bg-doom-panel text-doom-text hover:border-doom-blue/50', className)}\n >\n <a href={src} download={name}>\n <FileIcon className=\"h-3 w-3 shrink-0 text-doom-faint\" />\n download {name}\n </a>\n </Badge>\n );\n}\n"],"mappings":"mLA2BA,MAAM,EAAQ,4DAEd,SAAgB,EAAa,CAAE,MAAK,OAAM,OAAM,YAAW,cAAe,GAA6B,CACrG,IAAM,EAAW,GAAQA,EAAAA,YAAY,CAAI,EACnC,EAAO,EAAK,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,GAAK,EAgCvC,OA9BI,IAAa,SAEb,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,KAAM,EAAK,OAAO,SAAS,IAAI,aAAa,cAAa,EAAQ,YAAW,EAC7E,UAAA,EAAA,EAAA,IAAA,CAAC,MAAD,CAAU,MAAK,IAAK,EAAM,UAAWC,EAAAA,GAAG,EAAO,gBAAiB,CAAS,CAAI,CAAA,CAC5E,CAAA,EAGH,IAAa,SAEb,EAAA,EAAA,IAAA,CAAC,QAAD,CACO,MACL,SAAA,GACA,QAAQ,WACR,cAAa,EACb,YAAW,EACX,UAAWA,EAAAA,GAAG,EAAO,gBAAiB,CAAS,CAChD,CAAA,EAGD,IAAa,OAEb,EAAA,EAAA,IAAA,CAAC,SAAD,CACO,MACL,MAAO,EACP,cAAa,EACb,YAAW,EACX,UAAWA,EAAAA,GAAG,EAAO,mBAAoB,CAAS,CACnD,CAAA,GAIH,EAAA,EAAA,IAAA,CAACC,EAAAA,MAAD,CACE,QAAA,GACA,KAAK,KACL,cAAa,EACb,YAAW,EACX,UAAWD,EAAAA,GAAG,oEAAqE,CAAS,EAE5F,UAAA,EAAA,EAAA,KAAA,CAAC,IAAD,CAAG,KAAM,EAAK,SAAU,EAAxB,SAAA,EACE,EAAA,EAAA,IAAA,CAACE,EAAAA,SAAD,CAAU,UAAU,kCAAoC,CAAA,EAAC,YAC/C,CACT,GACE,CAAA,CAEX"}
1
+ {"version":3,"file":"MediaPreview.cjs","names":["boundedMediaTime","useRef","cn","mediaKindOf","PdfPreview","Badge","FileIcon"],"sources":["../../../src/components/MediaPreview.tsx"],"sourcesContent":["import { useEffect, useImperativeHandle, useRef } from 'react';\n\nimport { FileIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\nimport { mediaKindOf } from '../lib/media';\nimport { boundedMediaTime } from '../lib/mediaPlayback';\nimport type { MediaKind } from '../types/editor';\nimport { Badge } from './Badge';\nimport { PdfPreview, type PdfPreviewController } from './PdfPreview';\n/**\n * A file the browser can show but not edit.\n *\n * It renders bytes a server is already serving, so the caller supplies the\n * URL and this decides only which element reads it. Everything the browser\n * cannot render is a download rather than a converted approximation: a `.docx`\n * turned into HTML is a different document, and offering to edit that one\n * would be offering to overwrite the real one with it.\n */\n\nexport interface MediaPlaybackState {\n playing: boolean;\n currentTime: number;\n duration: number;\n}\n\nexport interface MediaIntrinsicSize {\n width: number;\n height: number;\n}\n\nexport interface MediaFrameMetadata {\n mediaTime: number;\n presentedFrames?: number;\n}\n\nexport interface MediaFrameCapture {\n blob: Blob;\n width: number;\n height: number;\n timeSeconds: number;\n metadata?: MediaFrameMetadata;\n}\n\nexport interface MediaPreviewController {\n play: () => Promise<void>;\n pause: () => void;\n seek: (seconds: number) => void;\n getState: () => MediaPlaybackState;\n isFrameReady: () => boolean;\n getIntrinsicSize: () => MediaIntrinsicSize | null;\n captureFrame: (type?: 'image/png' | 'image/jpeg', quality?: number) => Promise<MediaFrameCapture | null>;\n}\n\nexport interface MediaPreviewProps {\n /** Where the bytes are served from. */\n src: string;\n /** The file's path, used for the accessible name and the download name. */\n path: string;\n /** Overrides the kind inferred from the path, for a server that knows better. */\n kind?: MediaKind;\n className?: string;\n videoControls?: boolean;\n 'data-testid'?: string;\n /** Video-only controller. It is assigned while the video element is mounted. */\n controllerRef?: import('react').Ref<MediaPreviewController>;\n /** PDF-only page and geometry controller. */\n pdfControllerRef?: import('react').Ref<PdfPreviewController>;\n /** Reports browser playback state changes for video previews. */\n onPlaybackStateChange?: (state: MediaPlaybackState) => void;\n}\n\nconst FRAME = 'max-w-full rounded border border-doom-border bg-doom-deep';\n\ninterface VideoPreviewProps {\n src: string;\n className?: string;\n testId?: string;\n videoControls?: boolean;\n controllerRef?: import('react').Ref<MediaPreviewController>;\n onPlaybackStateChange?: (state: MediaPlaybackState) => void;\n}\n\nexport function mediaPlaybackState(video: HTMLVideoElement): MediaPlaybackState {\n return {\n playing: !video.paused && !video.ended,\n currentTime: video.currentTime,\n duration: Number.isFinite(video.duration) ? video.duration : 0,\n };\n}\n\nexport function mediaPreviewController(\n videoRef: { readonly current: HTMLVideoElement | null },\n frameMetadataRef: { readonly current: MediaFrameMetadata | undefined } = { current: undefined },\n): MediaPreviewController {\n return {\n play: async () => {\n const video = videoRef.current;\n if (video !== null) await video.play();\n },\n pause: () => videoRef.current?.pause(),\n seek: (seconds) => {\n const video = videoRef.current;\n if (video !== null) video.currentTime = boundedMediaTime(seconds, video.duration);\n },\n getState: () => {\n const video = videoRef.current;\n return video === null ? { playing: false, currentTime: 0, duration: 0 } : mediaPlaybackState(video);\n },\n isFrameReady: () => {\n const video = videoRef.current;\n return (\n video !== null &&\n !video.seeking &&\n video.readyState >= 2 &&\n (video.requestVideoFrameCallback === undefined || frameMetadataRef.current !== undefined)\n );\n },\n getIntrinsicSize: () => {\n const video = videoRef.current;\n return video === null || video.videoWidth <= 0 || video.videoHeight <= 0\n ? null\n : { width: video.videoWidth, height: video.videoHeight };\n },\n captureFrame: async (type = 'image/png', quality) => {\n const video = videoRef.current;\n if (video === null || video.videoWidth <= 0 || video.videoHeight <= 0 || video.seeking) return null;\n const metadata = frameMetadataRef.current === undefined ? undefined : { ...frameMetadataRef.current };\n const timeSeconds = metadata?.mediaTime ?? video.currentTime;\n const canvas = document.createElement('canvas');\n canvas.width = video.videoWidth;\n canvas.height = video.videoHeight;\n const context = canvas.getContext('2d');\n if (context === null) return null;\n context.drawImage(video, 0, 0, canvas.width, canvas.height);\n const blob = await new Promise<Blob | null>((resolve) => canvas.toBlob(resolve, type, quality));\n if (blob === null) return null;\n return {\n blob,\n width: canvas.width,\n height: canvas.height,\n timeSeconds,\n ...(metadata === undefined ? {} : { metadata }),\n };\n },\n };\n}\n\nfunction VideoPreview({\n src,\n className,\n testId,\n controllerRef,\n onPlaybackStateChange,\n videoControls = true,\n}: VideoPreviewProps) {\n const videoRef = useRef<HTMLVideoElement>(null);\n const frameMetadataRef = useRef<MediaFrameMetadata | undefined>(undefined);\n const reportState = () => {\n const video = videoRef.current;\n if (video !== null) onPlaybackStateChange?.(mediaPlaybackState(video));\n };\n const reportStateRef = useRef(reportState);\n useEffect(() => {\n reportStateRef.current = reportState;\n });\n useImperativeHandle(controllerRef, () => mediaPreviewController(videoRef, frameMetadataRef), []);\n useEffect(() => {\n const video = videoRef.current;\n if (video === null || video.requestVideoFrameCallback === undefined) return;\n let request = 0;\n const report: VideoFrameRequestCallback = (_now, metadata) => {\n frameMetadataRef.current = {\n mediaTime: metadata.mediaTime,\n ...(Number.isFinite(metadata.presentedFrames) ? { presentedFrames: metadata.presentedFrames } : {}),\n };\n reportStateRef.current();\n request = video.requestVideoFrameCallback(report);\n };\n request = video.requestVideoFrameCallback(report);\n return () => video.cancelVideoFrameCallback(request);\n }, []);\n return (\n <video\n ref={videoRef}\n src={src}\n controls={videoControls}\n playsInline\n preload=\"metadata\"\n data-testid={testId}\n data-kind=\"video\"\n className={cn(FRAME, 'max-h-[36rem]', className)}\n onPlay={reportState}\n onPause={reportState}\n onTimeUpdate={reportState}\n onDurationChange={reportState}\n onEnded={reportState}\n onLoadedMetadata={reportState}\n onLoadedData={reportState}\n onSeeking={() => {\n frameMetadataRef.current = undefined;\n reportState();\n }}\n onSeeked={reportState}\n >\n <track kind=\"captions\" />\n </video>\n );\n}\n\nexport function MediaPreview({\n src,\n path,\n kind,\n className,\n controllerRef,\n pdfControllerRef,\n onPlaybackStateChange,\n videoControls,\n 'data-testid': testId,\n}: MediaPreviewProps) {\n const resolved = kind ?? mediaKindOf(path);\n const name = path.split('/').at(-1) ?? path;\n\n if (resolved === 'image') {\n return (\n <a href={src} target=\"_blank\" rel=\"noreferrer\" data-testid={testId} data-kind={resolved}>\n <img src={src} alt={path} className={cn(FRAME, 'max-h-[36rem]', className)} />\n </a>\n );\n }\n if (resolved === 'video') {\n return (\n <VideoPreview\n src={src}\n className={className}\n controllerRef={controllerRef}\n onPlaybackStateChange={onPlaybackStateChange}\n testId={testId}\n videoControls={videoControls}\n />\n );\n }\n if (resolved === 'pdf') {\n return (\n <PdfPreview src={src} path={path} controllerRef={pdfControllerRef} data-testid={testId} className={className} />\n );\n }\n return (\n <Badge\n asChild\n size=\"md\"\n data-testid={testId}\n data-kind={resolved}\n className={cn('self-start bg-doom-panel text-doom-text hover:border-doom-blue/50', className)}\n >\n <a href={src} download={name}>\n <FileIcon className=\"h-3 w-3 shrink-0 text-doom-faint\" />\n download {name}\n </a>\n </Badge>\n );\n}\n"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { MediaKind } from "../types/editor.mjs";
2
+ import { PdfPreviewController } from "./PdfPreview.mjs";
2
3
  //#region src/components/MediaPreview.d.ts
3
4
  /**
4
5
  * A file the browser can show but not edit.
@@ -9,7 +10,36 @@ import { MediaKind } from "../types/editor.mjs";
9
10
  * turned into HTML is a different document, and offering to edit that one
10
11
  * would be offering to overwrite the real one with it.
11
12
  */
12
- interface MediaPreviewProps {
13
+ export interface MediaPlaybackState {
14
+ playing: boolean;
15
+ currentTime: number;
16
+ duration: number;
17
+ }
18
+ export interface MediaIntrinsicSize {
19
+ width: number;
20
+ height: number;
21
+ }
22
+ export interface MediaFrameMetadata {
23
+ mediaTime: number;
24
+ presentedFrames?: number;
25
+ }
26
+ export interface MediaFrameCapture {
27
+ blob: Blob;
28
+ width: number;
29
+ height: number;
30
+ timeSeconds: number;
31
+ metadata?: MediaFrameMetadata;
32
+ }
33
+ export interface MediaPreviewController {
34
+ play: () => Promise<void>;
35
+ pause: () => void;
36
+ seek: (seconds: number) => void;
37
+ getState: () => MediaPlaybackState;
38
+ isFrameReady: () => boolean;
39
+ getIntrinsicSize: () => MediaIntrinsicSize | null;
40
+ captureFrame: (type?: 'image/png' | 'image/jpeg', quality?: number) => Promise<MediaFrameCapture | null>;
41
+ }
42
+ export interface MediaPreviewProps {
13
43
  /** Where the bytes are served from. */
14
44
  src: string;
15
45
  /** The file's path, used for the accessible name and the download name. */
@@ -17,9 +47,15 @@ interface MediaPreviewProps {
17
47
  /** Overrides the kind inferred from the path, for a server that knows better. */
18
48
  kind?: MediaKind;
19
49
  className?: string;
50
+ videoControls?: boolean;
20
51
  'data-testid'?: string;
52
+ /** Video-only controller. It is assigned while the video element is mounted. */
53
+ controllerRef?: import('react').Ref<MediaPreviewController>;
54
+ /** PDF-only page and geometry controller. */
55
+ pdfControllerRef?: import('react').Ref<PdfPreviewController>;
56
+ /** Reports browser playback state changes for video previews. */
57
+ onPlaybackStateChange?: (state: MediaPlaybackState) => void;
21
58
  }
22
- declare function MediaPreview({ src, path, kind, className, 'data-testid': testId }: MediaPreviewProps): import("react/jsx-runtime").JSX.Element;
59
+ export declare function MediaPreview({ src, path, kind, className, controllerRef, pdfControllerRef, onPlaybackStateChange, videoControls, 'data-testid': testId }: MediaPreviewProps): import("react").JSX.Element;
23
60
  //#endregion
24
- export { MediaPreview, MediaPreviewProps };
25
61
  //# sourceMappingURL=MediaPreview.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MediaPreview.d.mts","names":[],"sources":["../../../src/components/MediaPreview.tsx"],"mappings":";;;;;;;;;;;UAgBiB;;EAEf;;EAEA;;EAEA,OAAO;EACP;EACA;;iBAKc,eAAe,KAAK,MAAM,MAAM,0BAA0B,UAAU,gDAAiB,IAAA"}
1
+ {"version":3,"file":"MediaPreview.d.mts","names":[],"sources":["../../../src/components/MediaPreview.tsx"],"mappings":";;;;;;;;;;;;iBAmBiB;EACf;EACA;EACA;;iBAGe;EACf;EACA;;iBAGe;EACf;EACA;;iBAGe;EACf,MAAM;EACN;EACA;EACA;EACA,WAAW;;iBAGI;EACf,YAAY;EACZ;EACA,OAAO;EACP,gBAAgB;EAChB;EACA,wBAAwB;EACxB,eAAe,mCAAmC,qBAAqB,QAAQ;;iBAGhE;;EAEf;;EAEA;;EAEA,OAAO;EACP;EACA;EACA;;EAEA,gCAAgC,IAAI;;EAEpC,mCAAmC,IAAI;;EAEvC,yBAAyB,OAAO;;wBA6IlB,eACd,KACA,MACA,MACA,WACA,eACA,kBACA,uBACA,8BACe,UACd,oCAAiB,IAAA"}
@@ -1,2 +1,2 @@
1
- import{FileIcon as e}from"../icons/icons.mjs";import{cn as t}from"../lib/cn.mjs";import{Badge as n}from"./Badge.mjs";import{mediaKindOf as r}from"../lib/media.mjs";import{jsx as i,jsxs as a}from"react/jsx-runtime";const o=`max-w-full rounded border border-doom-border bg-doom-deep`;function s({src:s,path:c,kind:l,className:u,"data-testid":d}){let f=l??r(c),p=c.split(`/`).at(-1)??c;return f===`image`?i(`a`,{href:s,target:`_blank`,rel:`noreferrer`,"data-testid":d,"data-kind":f,children:i(`img`,{src:s,alt:c,className:t(o,`max-h-[36rem]`,u)})}):f===`video`?i(`video`,{src:s,controls:!0,preload:`metadata`,"data-testid":d,"data-kind":f,className:t(o,`max-h-[36rem]`,u)}):f===`pdf`?i(`iframe`,{src:s,title:c,"data-testid":d,"data-kind":f,className:t(o,`h-[36rem] w-full`,u)}):i(n,{asChild:!0,size:`md`,"data-testid":d,"data-kind":f,className:t(`self-start bg-doom-panel text-doom-text hover:border-doom-blue/50`,u),children:a(`a`,{href:s,download:p,children:[i(e,{className:`h-3 w-3 shrink-0 text-doom-faint`}),`download `,p]})})}export{s as MediaPreview};
1
+ import{FileIcon as e}from"../icons/icons.mjs";import{cn as t}from"../lib/cn.mjs";import{Badge as n}from"./Badge.mjs";import{mediaKindOf as r}from"../lib/media.mjs";import{boundedMediaTime as i}from"../lib/mediaPlayback.mjs";import{PdfPreview as a}from"./PdfPreview.mjs";import{jsx as o,jsxs as s}from"react/jsx-runtime";import{useEffect as c,useImperativeHandle as l,useRef as u}from"react";const d=`max-w-full rounded border border-doom-border bg-doom-deep`;function f(e){return{playing:!e.paused&&!e.ended,currentTime:e.currentTime,duration:Number.isFinite(e.duration)?e.duration:0}}function p(e,t={current:void 0}){return{play:async()=>{let t=e.current;t!==null&&await t.play()},pause:()=>e.current?.pause(),seek:t=>{let n=e.current;n!==null&&(n.currentTime=i(t,n.duration))},getState:()=>{let t=e.current;return t===null?{playing:!1,currentTime:0,duration:0}:f(t)},isFrameReady:()=>{let n=e.current;return n!==null&&!n.seeking&&n.readyState>=2&&(n.requestVideoFrameCallback===void 0||t.current!==void 0)},getIntrinsicSize:()=>{let t=e.current;return t===null||t.videoWidth<=0||t.videoHeight<=0?null:{width:t.videoWidth,height:t.videoHeight}},captureFrame:async(n=`image/png`,r)=>{let i=e.current;if(i===null||i.videoWidth<=0||i.videoHeight<=0||i.seeking)return null;let a=t.current===void 0?void 0:{...t.current},o=a?.mediaTime??i.currentTime,s=document.createElement(`canvas`);s.width=i.videoWidth,s.height=i.videoHeight;let c=s.getContext(`2d`);if(c===null)return null;c.drawImage(i,0,0,s.width,s.height);let l=await new Promise(e=>s.toBlob(e,n,r));return l===null?null:{blob:l,width:s.width,height:s.height,timeSeconds:o,...a===void 0?{}:{metadata:a}}}}}function m({src:e,className:n,testId:r,controllerRef:i,onPlaybackStateChange:a,videoControls:s=!0}){let m=u(null),h=u(void 0),g=()=>{let e=m.current;e!==null&&a?.(f(e))},_=u(g);return c(()=>{_.current=g}),l(i,()=>p(m,h),[]),c(()=>{let e=m.current;if(e===null||e.requestVideoFrameCallback===void 0)return;let t=0,n=(r,i)=>{h.current={mediaTime:i.mediaTime,...Number.isFinite(i.presentedFrames)?{presentedFrames:i.presentedFrames}:{}},_.current(),t=e.requestVideoFrameCallback(n)};return t=e.requestVideoFrameCallback(n),()=>e.cancelVideoFrameCallback(t)},[]),/* @__PURE__ */ o(`video`,{ref:m,src:e,controls:s,playsInline:!0,preload:`metadata`,"data-testid":r,"data-kind":`video`,className:t(d,`max-h-[36rem]`,n),onPlay:g,onPause:g,onTimeUpdate:g,onDurationChange:g,onEnded:g,onLoadedMetadata:g,onLoadedData:g,onSeeking:()=>{h.current=void 0,g()},onSeeked:g,children:/* @__PURE__ */ o(`track`,{kind:`captions`})})}function h({src:i,path:c,kind:l,className:u,controllerRef:f,pdfControllerRef:p,onPlaybackStateChange:h,videoControls:g,"data-testid":_}){let v=l??r(c),y=c.split(`/`).at(-1)??c;return v===`image`?/* @__PURE__ */ o(`a`,{href:i,target:`_blank`,rel:`noreferrer`,"data-testid":_,"data-kind":v,children:/* @__PURE__ */ o(`img`,{src:i,alt:c,className:t(d,`max-h-[36rem]`,u)})}):v===`video`?/* @__PURE__ */ o(m,{src:i,className:u,controllerRef:f,onPlaybackStateChange:h,testId:_,videoControls:g}):v===`pdf`?/* @__PURE__ */ o(a,{src:i,path:c,controllerRef:p,"data-testid":_,className:u}):/* @__PURE__ */ o(n,{asChild:!0,size:`md`,"data-testid":_,"data-kind":v,className:t(`self-start bg-doom-panel text-doom-text hover:border-doom-blue/50`,u),children:/* @__PURE__ */ s(`a`,{href:i,download:y,children:[/* @__PURE__ */ o(e,{className:`h-3 w-3 shrink-0 text-doom-faint`}),`download `,y]})})}export{h as MediaPreview,f as mediaPlaybackState,p as mediaPreviewController};
2
2
  //# sourceMappingURL=MediaPreview.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"MediaPreview.mjs","names":[],"sources":["../../../src/components/MediaPreview.tsx"],"sourcesContent":["import { FileIcon } from '../icons/icons.ts';\nimport { cn } from '../lib/cn.ts';\nimport { mediaKindOf } from '../lib/media.ts';\nimport type { MediaKind } from '../types/editor.ts';\nimport { Badge } from './Badge.tsx';\n\n/**\n * A file the browser can show but not edit.\n *\n * It renders bytes a server is already serving, so the caller supplies the\n * URL and this decides only which element reads it. Everything the browser\n * cannot render is a download rather than a converted approximation: a `.docx`\n * turned into HTML is a different document, and offering to edit that one\n * would be offering to overwrite the real one with it.\n */\n\nexport interface MediaPreviewProps {\n /** Where the bytes are served from. */\n src: string;\n /** The file's path, used for the accessible name and the download name. */\n path: string;\n /** Overrides the kind inferred from the path, for a server that knows better. */\n kind?: MediaKind;\n className?: string;\n 'data-testid'?: string;\n}\n\nconst FRAME = 'max-w-full rounded border border-doom-border bg-doom-deep';\n\nexport function MediaPreview({ src, path, kind, className, 'data-testid': testId }: MediaPreviewProps) {\n const resolved = kind ?? mediaKindOf(path);\n const name = path.split('/').at(-1) ?? path;\n\n if (resolved === 'image') {\n return (\n <a href={src} target=\"_blank\" rel=\"noreferrer\" data-testid={testId} data-kind={resolved}>\n <img src={src} alt={path} className={cn(FRAME, 'max-h-[36rem]', className)} />\n </a>\n );\n }\n if (resolved === 'video') {\n return (\n <video\n src={src}\n controls\n preload=\"metadata\"\n data-testid={testId}\n data-kind={resolved}\n className={cn(FRAME, 'max-h-[36rem]', className)}\n />\n );\n }\n if (resolved === 'pdf') {\n return (\n <iframe\n src={src}\n title={path}\n data-testid={testId}\n data-kind={resolved}\n className={cn(FRAME, 'h-[36rem] w-full', className)}\n />\n );\n }\n return (\n <Badge\n asChild\n size=\"md\"\n data-testid={testId}\n data-kind={resolved}\n className={cn('self-start bg-doom-panel text-doom-text hover:border-doom-blue/50', className)}\n >\n <a href={src} download={name}>\n <FileIcon className=\"h-3 w-3 shrink-0 text-doom-faint\" />\n download {name}\n </a>\n </Badge>\n );\n}\n"],"mappings":"sNA2BA,MAAM,EAAQ,4DAEd,SAAgB,EAAa,CAAE,MAAK,OAAM,OAAM,YAAW,cAAe,GAA6B,CACrG,IAAM,EAAW,GAAQ,EAAY,CAAI,EACnC,EAAO,EAAK,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,GAAK,EAgCvC,OA9BI,IAAa,QAEb,EAAC,IAAD,CAAG,KAAM,EAAK,OAAO,SAAS,IAAI,aAAa,cAAa,EAAQ,YAAW,EAC7E,SAAA,EAAC,MAAD,CAAU,MAAK,IAAK,EAAM,UAAW,EAAG,EAAO,gBAAiB,CAAS,CAAI,CAAA,CAC5E,CAAA,EAGH,IAAa,QAEb,EAAC,QAAD,CACO,MACL,SAAA,GACA,QAAQ,WACR,cAAa,EACb,YAAW,EACX,UAAW,EAAG,EAAO,gBAAiB,CAAS,CAChD,CAAA,EAGD,IAAa,MAEb,EAAC,SAAD,CACO,MACL,MAAO,EACP,cAAa,EACb,YAAW,EACX,UAAW,EAAG,EAAO,mBAAoB,CAAS,CACnD,CAAA,EAIH,EAAC,EAAD,CACE,QAAA,GACA,KAAK,KACL,cAAa,EACb,YAAW,EACX,UAAW,EAAG,oEAAqE,CAAS,EAE5F,SAAA,EAAC,IAAD,CAAG,KAAM,EAAK,SAAU,EAAxB,SAAA,CACE,EAAC,EAAD,CAAU,UAAU,kCAAoC,CAAA,EAAC,YAC/C,CACT,GACE,CAAA,CAEX"}
1
+ {"version":3,"file":"MediaPreview.mjs","names":[],"sources":["../../../src/components/MediaPreview.tsx"],"sourcesContent":["import { useEffect, useImperativeHandle, useRef } from 'react';\n\nimport { FileIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\nimport { mediaKindOf } from '../lib/media';\nimport { boundedMediaTime } from '../lib/mediaPlayback';\nimport type { MediaKind } from '../types/editor';\nimport { Badge } from './Badge';\nimport { PdfPreview, type PdfPreviewController } from './PdfPreview';\n/**\n * A file the browser can show but not edit.\n *\n * It renders bytes a server is already serving, so the caller supplies the\n * URL and this decides only which element reads it. Everything the browser\n * cannot render is a download rather than a converted approximation: a `.docx`\n * turned into HTML is a different document, and offering to edit that one\n * would be offering to overwrite the real one with it.\n */\n\nexport interface MediaPlaybackState {\n playing: boolean;\n currentTime: number;\n duration: number;\n}\n\nexport interface MediaIntrinsicSize {\n width: number;\n height: number;\n}\n\nexport interface MediaFrameMetadata {\n mediaTime: number;\n presentedFrames?: number;\n}\n\nexport interface MediaFrameCapture {\n blob: Blob;\n width: number;\n height: number;\n timeSeconds: number;\n metadata?: MediaFrameMetadata;\n}\n\nexport interface MediaPreviewController {\n play: () => Promise<void>;\n pause: () => void;\n seek: (seconds: number) => void;\n getState: () => MediaPlaybackState;\n isFrameReady: () => boolean;\n getIntrinsicSize: () => MediaIntrinsicSize | null;\n captureFrame: (type?: 'image/png' | 'image/jpeg', quality?: number) => Promise<MediaFrameCapture | null>;\n}\n\nexport interface MediaPreviewProps {\n /** Where the bytes are served from. */\n src: string;\n /** The file's path, used for the accessible name and the download name. */\n path: string;\n /** Overrides the kind inferred from the path, for a server that knows better. */\n kind?: MediaKind;\n className?: string;\n videoControls?: boolean;\n 'data-testid'?: string;\n /** Video-only controller. It is assigned while the video element is mounted. */\n controllerRef?: import('react').Ref<MediaPreviewController>;\n /** PDF-only page and geometry controller. */\n pdfControllerRef?: import('react').Ref<PdfPreviewController>;\n /** Reports browser playback state changes for video previews. */\n onPlaybackStateChange?: (state: MediaPlaybackState) => void;\n}\n\nconst FRAME = 'max-w-full rounded border border-doom-border bg-doom-deep';\n\ninterface VideoPreviewProps {\n src: string;\n className?: string;\n testId?: string;\n videoControls?: boolean;\n controllerRef?: import('react').Ref<MediaPreviewController>;\n onPlaybackStateChange?: (state: MediaPlaybackState) => void;\n}\n\nexport function mediaPlaybackState(video: HTMLVideoElement): MediaPlaybackState {\n return {\n playing: !video.paused && !video.ended,\n currentTime: video.currentTime,\n duration: Number.isFinite(video.duration) ? video.duration : 0,\n };\n}\n\nexport function mediaPreviewController(\n videoRef: { readonly current: HTMLVideoElement | null },\n frameMetadataRef: { readonly current: MediaFrameMetadata | undefined } = { current: undefined },\n): MediaPreviewController {\n return {\n play: async () => {\n const video = videoRef.current;\n if (video !== null) await video.play();\n },\n pause: () => videoRef.current?.pause(),\n seek: (seconds) => {\n const video = videoRef.current;\n if (video !== null) video.currentTime = boundedMediaTime(seconds, video.duration);\n },\n getState: () => {\n const video = videoRef.current;\n return video === null ? { playing: false, currentTime: 0, duration: 0 } : mediaPlaybackState(video);\n },\n isFrameReady: () => {\n const video = videoRef.current;\n return (\n video !== null &&\n !video.seeking &&\n video.readyState >= 2 &&\n (video.requestVideoFrameCallback === undefined || frameMetadataRef.current !== undefined)\n );\n },\n getIntrinsicSize: () => {\n const video = videoRef.current;\n return video === null || video.videoWidth <= 0 || video.videoHeight <= 0\n ? null\n : { width: video.videoWidth, height: video.videoHeight };\n },\n captureFrame: async (type = 'image/png', quality) => {\n const video = videoRef.current;\n if (video === null || video.videoWidth <= 0 || video.videoHeight <= 0 || video.seeking) return null;\n const metadata = frameMetadataRef.current === undefined ? undefined : { ...frameMetadataRef.current };\n const timeSeconds = metadata?.mediaTime ?? video.currentTime;\n const canvas = document.createElement('canvas');\n canvas.width = video.videoWidth;\n canvas.height = video.videoHeight;\n const context = canvas.getContext('2d');\n if (context === null) return null;\n context.drawImage(video, 0, 0, canvas.width, canvas.height);\n const blob = await new Promise<Blob | null>((resolve) => canvas.toBlob(resolve, type, quality));\n if (blob === null) return null;\n return {\n blob,\n width: canvas.width,\n height: canvas.height,\n timeSeconds,\n ...(metadata === undefined ? {} : { metadata }),\n };\n },\n };\n}\n\nfunction VideoPreview({\n src,\n className,\n testId,\n controllerRef,\n onPlaybackStateChange,\n videoControls = true,\n}: VideoPreviewProps) {\n const videoRef = useRef<HTMLVideoElement>(null);\n const frameMetadataRef = useRef<MediaFrameMetadata | undefined>(undefined);\n const reportState = () => {\n const video = videoRef.current;\n if (video !== null) onPlaybackStateChange?.(mediaPlaybackState(video));\n };\n const reportStateRef = useRef(reportState);\n useEffect(() => {\n reportStateRef.current = reportState;\n });\n useImperativeHandle(controllerRef, () => mediaPreviewController(videoRef, frameMetadataRef), []);\n useEffect(() => {\n const video = videoRef.current;\n if (video === null || video.requestVideoFrameCallback === undefined) return;\n let request = 0;\n const report: VideoFrameRequestCallback = (_now, metadata) => {\n frameMetadataRef.current = {\n mediaTime: metadata.mediaTime,\n ...(Number.isFinite(metadata.presentedFrames) ? { presentedFrames: metadata.presentedFrames } : {}),\n };\n reportStateRef.current();\n request = video.requestVideoFrameCallback(report);\n };\n request = video.requestVideoFrameCallback(report);\n return () => video.cancelVideoFrameCallback(request);\n }, []);\n return (\n <video\n ref={videoRef}\n src={src}\n controls={videoControls}\n playsInline\n preload=\"metadata\"\n data-testid={testId}\n data-kind=\"video\"\n className={cn(FRAME, 'max-h-[36rem]', className)}\n onPlay={reportState}\n onPause={reportState}\n onTimeUpdate={reportState}\n onDurationChange={reportState}\n onEnded={reportState}\n onLoadedMetadata={reportState}\n onLoadedData={reportState}\n onSeeking={() => {\n frameMetadataRef.current = undefined;\n reportState();\n }}\n onSeeked={reportState}\n >\n <track kind=\"captions\" />\n </video>\n );\n}\n\nexport function MediaPreview({\n src,\n path,\n kind,\n className,\n controllerRef,\n pdfControllerRef,\n onPlaybackStateChange,\n videoControls,\n 'data-testid': testId,\n}: MediaPreviewProps) {\n const resolved = kind ?? mediaKindOf(path);\n const name = path.split('/').at(-1) ?? path;\n\n if (resolved === 'image') {\n return (\n <a href={src} target=\"_blank\" rel=\"noreferrer\" data-testid={testId} data-kind={resolved}>\n <img src={src} alt={path} className={cn(FRAME, 'max-h-[36rem]', className)} />\n </a>\n );\n }\n if (resolved === 'video') {\n return (\n <VideoPreview\n src={src}\n className={className}\n controllerRef={controllerRef}\n onPlaybackStateChange={onPlaybackStateChange}\n testId={testId}\n videoControls={videoControls}\n />\n );\n }\n if (resolved === 'pdf') {\n return (\n <PdfPreview src={src} path={path} controllerRef={pdfControllerRef} data-testid={testId} className={className} />\n );\n }\n return (\n <Badge\n asChild\n size=\"md\"\n data-testid={testId}\n data-kind={resolved}\n className={cn('self-start bg-doom-panel text-doom-text hover:border-doom-blue/50', className)}\n >\n <a href={src} download={name}>\n <FileIcon className=\"h-3 w-3 shrink-0 text-doom-faint\" />\n download {name}\n </a>\n </Badge>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ const e=require("./SyntaxText.cjs"),t=require("../lib/mermaidDiagram.cjs");let n=require("react/jsx-runtime"),r=require("react");function i({code:i}){let a=`mermaid-${(0,r.useId)().replaceAll(/[^a-zA-Z0-9]/g,``)}`,[o,s]=(0,r.useState)(void 0);return(0,r.useEffect)(()=>{let e=!0;return t.renderMermaid(a,i).then(t=>{e&&s({source:i,svg:t})},()=>void 0),()=>{e=!1}},[i,a]),o?.source===i?/* @__PURE__ */ (0,n.jsx)(`div`,{"data-testid":`mermaid-diagram`,dangerouslySetInnerHTML:{__html:o.svg},className:`flex justify-center overflow-x-auto [&_svg]:h-auto [&_svg]:max-w-full`}):/* @__PURE__ */ (0,n.jsx)(e.SyntaxText,{text:i,className:`text-doom-text`})}exports.MermaidDiagram=i;
2
+ //# sourceMappingURL=MermaidDiagram.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MermaidDiagram.cjs","names":["useId","useState","renderMermaid","SyntaxText"],"sources":["../../../src/components/MermaidDiagram.tsx"],"sourcesContent":["import { useEffect, useId, useState } from 'react';\n\nimport { renderMermaid } from '../lib/mermaidDiagram';\nimport { SyntaxText } from './SyntaxText';\n\n/**\n * A mermaid fence, drawn.\n *\n * DESIGN PATTERNS:\n * - The source is the fallback, never a spinner or an error box. A diagram\n * that has not loaded yet, a diagram that fails to parse and a diagram in a\n * half-streamed message all show the text the author wrote, which stays\n * useful on its own.\n * - The rendered markup is stored with the source it came from, so a message\n * that grows never paints the previous frame's picture over new text.\n *\n * AVOID:\n * - Rendering at module scope or during render: mermaid measures text in the\n * document, so it only runs in an effect, in a browser.\n */\n\ninterface Drawn {\n source: string;\n svg: string;\n}\n\nexport function MermaidDiagram({ code }: { code: string }) {\n // Mermaid puts the id in the DOM and in the SVG's own ids, so React's\n // colon-wrapped value has to lose its punctuation first.\n const id = `mermaid-${useId().replaceAll(/[^a-zA-Z0-9]/g, '')}`;\n const [drawn, setDrawn] = useState<Drawn | undefined>(undefined);\n\n useEffect(() => {\n let live = true;\n void renderMermaid(id, code).then(\n (svg) => {\n if (live) setDrawn({ source: code, svg });\n },\n // Invalid syntax and a chunk that will not load are the same outcome\n // here: the block keeps showing its source.\n () => undefined,\n );\n return () => {\n live = false;\n };\n }, [code, id]);\n\n if (drawn?.source !== code) return <SyntaxText text={code} className=\"text-doom-text\" />;\n return (\n <div\n data-testid=\"mermaid-diagram\"\n // Mermaid sanitises its own output under the strict security level set\n // in lib/mermaidDiagram.ts; this is the only way it hands back a figure.\n dangerouslySetInnerHTML={{ __html: drawn.svg }}\n className=\"flex justify-center overflow-x-auto [&_svg]:h-auto [&_svg]:max-w-full\"\n />\n );\n}\n"],"mappings":"iIA0BA,SAAgB,EAAe,CAAE,QAA0B,CAGzD,IAAM,EAAK,YAAA,EAAWA,EAAAA,MAAAA,CAAM,CAAC,CAAC,WAAW,gBAAiB,EAAE,IACtD,CAAC,EAAO,IAAA,EAAYC,EAAAA,SAAAA,CAA4B,IAAA,EAAS,EAkB/D,OAhBA,EAAA,EAAA,UAAA,KAAgB,CACd,IAAI,EAAO,GASX,OARA,EAAKC,cAAc,EAAI,CAAI,CAAC,CAAC,KAC1B,GAAQ,CACH,GAAM,EAAS,CAAE,OAAQ,EAAM,KAAI,CAAC,CAC1C,MAGM,IAAA,EACR,MACa,CACX,EAAO,EACT,CACF,EAAG,CAAC,EAAM,CAAE,CAAC,EAET,GAAO,SAAW,EAEpB,iBAAA,EAAA,EAAA,IAAA,CAAC,MAAD,CACE,cAAY,kBAGZ,wBAAyB,CAAE,OAAQ,EAAM,GAAI,EAC7C,UAAU,uEACX,CAAA,EARgC,iBAAA,EAAA,EAAA,IAAA,CAACC,EAAAA,WAAD,CAAY,KAAM,EAAM,UAAU,gBAAkB,CAAA,CAUzF"}
@@ -0,0 +1,2 @@
1
+ import{SyntaxText as e}from"./SyntaxText.mjs";import{renderMermaid as t}from"../lib/mermaidDiagram.mjs";import{jsx as n}from"react/jsx-runtime";import{useEffect as r,useId as i,useState as a}from"react";function o({code:o}){let s=`mermaid-${i().replaceAll(/[^a-zA-Z0-9]/g,``)}`,[c,l]=a(void 0);return r(()=>{let e=!0;return t(s,o).then(t=>{e&&l({source:o,svg:t})},()=>void 0),()=>{e=!1}},[o,s]),c?.source===o?/* @__PURE__ */ n(`div`,{"data-testid":`mermaid-diagram`,dangerouslySetInnerHTML:{__html:c.svg},className:`flex justify-center overflow-x-auto [&_svg]:h-auto [&_svg]:max-w-full`}):/* @__PURE__ */ n(e,{text:o,className:`text-doom-text`})}export{o as MermaidDiagram};
2
+ //# sourceMappingURL=MermaidDiagram.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MermaidDiagram.mjs","names":[],"sources":["../../../src/components/MermaidDiagram.tsx"],"sourcesContent":["import { useEffect, useId, useState } from 'react';\n\nimport { renderMermaid } from '../lib/mermaidDiagram';\nimport { SyntaxText } from './SyntaxText';\n\n/**\n * A mermaid fence, drawn.\n *\n * DESIGN PATTERNS:\n * - The source is the fallback, never a spinner or an error box. A diagram\n * that has not loaded yet, a diagram that fails to parse and a diagram in a\n * half-streamed message all show the text the author wrote, which stays\n * useful on its own.\n * - The rendered markup is stored with the source it came from, so a message\n * that grows never paints the previous frame's picture over new text.\n *\n * AVOID:\n * - Rendering at module scope or during render: mermaid measures text in the\n * document, so it only runs in an effect, in a browser.\n */\n\ninterface Drawn {\n source: string;\n svg: string;\n}\n\nexport function MermaidDiagram({ code }: { code: string }) {\n // Mermaid puts the id in the DOM and in the SVG's own ids, so React's\n // colon-wrapped value has to lose its punctuation first.\n const id = `mermaid-${useId().replaceAll(/[^a-zA-Z0-9]/g, '')}`;\n const [drawn, setDrawn] = useState<Drawn | undefined>(undefined);\n\n useEffect(() => {\n let live = true;\n void renderMermaid(id, code).then(\n (svg) => {\n if (live) setDrawn({ source: code, svg });\n },\n // Invalid syntax and a chunk that will not load are the same outcome\n // here: the block keeps showing its source.\n () => undefined,\n );\n return () => {\n live = false;\n };\n }, [code, id]);\n\n if (drawn?.source !== code) return <SyntaxText text={code} className=\"text-doom-text\" />;\n return (\n <div\n data-testid=\"mermaid-diagram\"\n // Mermaid sanitises its own output under the strict security level set\n // in lib/mermaidDiagram.ts; this is the only way it hands back a figure.\n dangerouslySetInnerHTML={{ __html: drawn.svg }}\n className=\"flex justify-center overflow-x-auto [&_svg]:h-auto [&_svg]:max-w-full\"\n />\n );\n}\n"],"mappings":"2MA0BA,SAAgB,EAAe,CAAE,QAA0B,CAGzD,IAAM,EAAK,WAAW,EAAM,CAAC,CAAC,WAAW,gBAAiB,EAAE,IACtD,CAAC,EAAO,GAAY,EAA4B,IAAA,EAAS,EAkB/D,OAhBA,MAAgB,CACd,IAAI,EAAO,GASX,OARA,EAAmB,EAAI,CAAI,CAAC,CAAC,KAC1B,GAAQ,CACH,GAAM,EAAS,CAAE,OAAQ,EAAM,KAAI,CAAC,CAC1C,MAGM,IAAA,EACR,MACa,CACX,EAAO,EACT,CACF,EAAG,CAAC,EAAM,CAAE,CAAC,EAET,GAAO,SAAW,EAEpB,kBAAC,MAAD,CACE,cAAY,kBAGZ,wBAAyB,CAAE,OAAQ,EAAM,GAAI,EAC7C,UAAU,uEACX,CAAA,EARgC,kBAAC,EAAD,CAAY,KAAM,EAAM,UAAU,gBAAkB,CAAA,CAUzF"}
@@ -1,2 +1,2 @@
1
- require("../icons/icons.cjs");const e=require("../lib/cn.cjs"),t=require("./Button.cjs"),n=require("./StatusBadge.cjs");let r=require("react/jsx-runtime"),i=require("class-variance-authority"),a=require("react"),o=require("lucide-react");const s=(0,a.createContext)({tone:`neutral`,expandable:!1,expanded:!1,toggle:()=>void 0});function c(){return(0,a.useContext)(s)}const l=(0,i.cva)(`overflow-hidden rounded-md border bg-doom-panel transition-colors`,{variants:{tone:n.STATUS_EDGE},defaultVariants:{tone:`neutral`}});function u({className:t,tone:n,expandable:i=!1,defaultExpanded:o=!1,expanded:c,onExpandedChange:u,children:d,...f}){let[p,m]=(0,a.useState)(o),h=c??p,g={tone:n??`neutral`,expandable:i,expanded:h,toggle:()=>{let e=!h;c===void 0&&m(e),u?.(e)}};return(0,r.jsx)(s.Provider,{value:g,children:(0,r.jsx)(`div`,{"data-slot":`message-item`,"data-expanded":h,className:e.cn(l({tone:n}),t),...f,children:typeof d==`function`?d(g):d})})}function d(e){return e.running?`running`:e.isError?`error`:`ok`}const f={neutral:``,running:`RUNNING`,ok:`OK`,error:`ERROR`,info:`INFO`,accent:`NOTE`};function p({className:i,title:a,badge:s,children:l,...u}){let{tone:d,expandable:p,expanded:m,toggle:h}=c(),g=s===void 0?f[d]:s;return(0,r.jsxs)(`div`,{"data-slot":`message-item-header`,className:e.cn(`flex min-h-8 items-center gap-2 px-[11px] text-[11px] text-doom-dim`,i),...u,children:[(0,r.jsx)(`span`,{className:`shrink-0 font-bold text-doom-hi`,children:a}),(0,r.jsx)(`div`,{"data-slot":`message-item-summary`,className:`flex min-w-0 flex-1 items-center gap-2`,children:l}),g!==null&&g!==``?(0,r.jsx)(n.StatusBadge,{tone:d,"data-testid":`tool-status`,children:g}):null,p?(0,r.jsx)(t.Button,{variant:`ghost`,size:`icon`,"data-testid":`tool-expand`,"aria-expanded":m,"aria-label":m?`collapse`:`expand`,onClick:h,className:`text-doom-faint hover:text-doom-blue`,children:m?(0,r.jsx)(o.ChevronUp,{className:`h-3 w-3`}):(0,r.jsx)(o.ChevronDown,{className:`h-3 w-3`})}):null]})}function m({className:t,...n}){return(0,r.jsx)(`div`,{"data-slot":`message-item-body`,className:e.cn(`border-t border-doom-border-soft bg-doom-deep px-3 py-2 text-[11px] text-doom-dim`,t),...n})}const h={neutral:`…`,running:`◐`,ok:`✓`,error:`✗`,info:`●`,accent:`●`},g=(0,i.cva)(`shrink-0`,{variants:{tone:{neutral:`text-doom-faint`,running:`text-doom-yellow`,ok:`text-doom-green`,error:`text-doom-red`,info:`text-doom-blue`,accent:`text-doom-magenta`}},defaultVariants:{tone:`neutral`}});function _({className:t,tone:n,glyph:i,expands:a=!1,children:o,...s}){let{toggle:l}=c(),u=(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(`span`,{className:g({tone:n}),children:i??h[n??`neutral`]}),(0,r.jsx)(`span`,{children:o})]});return a?(0,r.jsx)(`button`,{type:`button`,"data-slot":`message-item-status`,"data-testid":`tool-more`,onClick:l,className:e.cn(`flex cursor-pointer items-center gap-1.5 text-doom-faint hover:text-doom-blue`,t),children:u}):(0,r.jsx)(`span`,{"data-slot":`message-item-status`,className:e.cn(`flex items-center gap-1.5 text-doom-faint`,t),...s,children:u})}exports.MessageItem=u,exports.MessageItemBody=m,exports.MessageItemHeader=p,exports.MessageItemStatus=_,exports.STATUS_GLYPH=h,exports.STATUS_LABEL=f,exports.messageItemStatusVariants=g,exports.messageItemVariants=l,exports.toolTone=d,exports.useMessageItem=c;
1
+ require("../icons/icons.cjs");const e=require("../lib/cn.cjs"),t=require("./Button.cjs"),n=require("./StatusBadge.cjs");let r=require("react/jsx-runtime"),i=require("react"),a=require("class-variance-authority"),o=require("lucide-react");const s=(0,i.createContext)({tone:`neutral`,expandable:!1,expanded:!1,toggle:()=>void 0});function c(){return(0,i.useContext)(s)}const l=(0,i.createContext)(null),u=(0,a.cva)(`overflow-hidden rounded-md border bg-doom-panel transition-colors`,{variants:{tone:n.STATUS_EDGE},defaultVariants:{tone:`neutral`}}),d=(0,a.cva)(`overflow-hidden border-l-2 transition-colors`,{variants:{tone:n.STATUS_EDGE},defaultVariants:{tone:`neutral`}});function f({className:t,tone:n,expandable:a=!1,defaultExpanded:o=!1,expanded:c,onExpandedChange:f,children:p,...m}){let[h,g]=(0,i.useState)(o),_=(0,i.useContext)(l)!==null,v=c??h,y={tone:n??`neutral`,expandable:a,expanded:v,toggle:()=>{let e=!v;c===void 0&&g(e),f?.(e)}};return/* @__PURE__ */ (0,r.jsx)(s.Provider,{value:y,children:/* @__PURE__ */ (0,r.jsx)(`div`,{"data-slot":`message-item`,"data-expanded":v,"data-grouped":_,className:e.cn(_?d({tone:n}):u({tone:n}),t),...m,children:typeof p==`function`?p(y):p})})}function p({className:t,tone:i,title:a,summary:o,badge:s,children:c,...d}){let f=s===void 0?h[i??`neutral`]:s;return/* @__PURE__ */ (0,r.jsx)(l.Provider,{value:{tone:i??`neutral`},children:/* @__PURE__ */ (0,r.jsxs)(`div`,{"data-slot":`message-item-group`,className:e.cn(u({tone:i}),t),...d,children:[/* @__PURE__ */ (0,r.jsxs)(`div`,{className:`flex min-h-8 items-center gap-2 border-doom-border-soft border-b px-[11px] text-sm text-doom-dim`,children:[/* @__PURE__ */ (0,r.jsx)(`span`,{className:`shrink-0 font-bold text-doom-hi`,children:a}),/* @__PURE__ */ (0,r.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-doom-faint`,children:o}),f!==null&&f!==``?/* @__PURE__ */ (0,r.jsx)(n.StatusBadge,{tone:i??`neutral`,children:f}):null]}),/* @__PURE__ */ (0,r.jsx)(`div`,{className:`flex flex-col divide-y divide-doom-border-soft`,children:c})]})})}function m(e){return e.running?`running`:e.isError?`error`:`ok`}const h={neutral:``,running:`RUNNING`,ok:`OK`,error:`ERROR`,info:`INFO`,accent:`NOTE`},g=/* @__PURE__ */ new Set([`ok`,`neutral`]);function _({className:a,title:s,badge:u,children:d,...f}){let{tone:p,expandable:m,expanded:_,toggle:v}=c(),y=(0,i.useContext)(l),b=y!==null&&g.has(p)?null:h[p],x=u===void 0?b:u;return/* @__PURE__ */ (0,r.jsxs)(`div`,{"data-slot":`message-item-header`,className:e.cn(`flex min-h-8 items-center gap-2 px-[11px] text-sm text-doom-dim`,a),...f,children:[y===null?/* @__PURE__ */ (0,r.jsx)(`span`,{className:`shrink-0 font-bold text-doom-hi`,children:s}):null,/* @__PURE__ */ (0,r.jsx)(`div`,{"data-slot":`message-item-summary`,className:`flex min-w-0 flex-1 items-center gap-2`,children:d}),x!==null&&x!==``?/* @__PURE__ */ (0,r.jsx)(n.StatusBadge,{tone:p,"data-testid":`tool-status`,children:x}):null,m?/* @__PURE__ */ (0,r.jsx)(t.Button,{variant:`ghost`,size:`icon`,"data-testid":`tool-expand`,"aria-expanded":_,"aria-label":_?`collapse`:`expand`,onClick:v,className:`text-doom-faint hover:text-doom-blue`,children:_?/* @__PURE__ */ (0,r.jsx)(o.ChevronUp,{className:`h-3 w-3`}):/* @__PURE__ */ (0,r.jsx)(o.ChevronDown,{className:`h-3 w-3`})}):null]})}function v({className:t,...n}){return/* @__PURE__ */ (0,r.jsx)(`div`,{"data-slot":`message-item-body`,className:e.cn(`border-t border-doom-border-soft bg-doom-deep px-3 py-2 text-sm text-doom-dim`,t),...n})}const y={neutral:`…`,running:`◐`,ok:`✓`,error:`✗`,info:`●`,accent:`●`},b=(0,a.cva)(`shrink-0`,{variants:{tone:{neutral:`text-doom-faint`,running:`text-doom-yellow`,ok:`text-doom-green`,error:`text-doom-red`,info:`text-doom-blue`,accent:`text-doom-magenta`}},defaultVariants:{tone:`neutral`}});function x({className:t,tone:n,glyph:i,expands:a=!1,children:o,...s}){let{toggle:l}=c(),u=/* @__PURE__ */ (0,r.jsxs)(r.Fragment,{children:[/* @__PURE__ */ (0,r.jsx)(`span`,{className:b({tone:n}),children:i??y[n??`neutral`]}),/* @__PURE__ */ (0,r.jsx)(`span`,{children:o})]});return a?/* @__PURE__ */ (0,r.jsx)(`button`,{type:`button`,"data-slot":`message-item-status`,"data-testid":`tool-more`,onClick:l,className:e.cn(`flex cursor-pointer items-center gap-1.5 text-doom-faint hover:text-doom-blue`,t),children:u}):/* @__PURE__ */ (0,r.jsx)(`span`,{"data-slot":`message-item-status`,className:e.cn(`flex items-center gap-1.5 text-doom-faint`,t),...s,children:u})}exports.MessageItem=f,exports.MessageItemBody=v,exports.MessageItemGroup=p,exports.MessageItemHeader=_,exports.MessageItemStatus=x,exports.STATUS_GLYPH=y,exports.STATUS_LABEL=h,exports.messageItemRowVariants=d,exports.messageItemStatusVariants=b,exports.messageItemVariants=u,exports.toolTone=m,exports.useMessageItem=c;
2
2
  //# sourceMappingURL=MessageItem.cjs.map