@joewinke/jatui 0.37.0 → 0.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (266) hide show
  1. package/dist/artifact-blocks/AttachmentChip.svelte +66 -0
  2. package/dist/artifact-blocks/AttachmentChip.svelte.d.ts +7 -0
  3. package/dist/artifact-blocks/BlockComments.svelte +309 -0
  4. package/dist/artifact-blocks/BlockComments.svelte.d.ts +33 -0
  5. package/dist/artifact-blocks/BlockRenderer.svelte +674 -0
  6. package/dist/artifact-blocks/BlockRenderer.svelte.d.ts +55 -0
  7. package/dist/artifact-blocks/BlockVerdict.svelte +151 -0
  8. package/dist/artifact-blocks/BlockVerdict.svelte.d.ts +13 -0
  9. package/dist/artifact-blocks/BlocksArtifactView.svelte +1616 -0
  10. package/dist/artifact-blocks/BlocksArtifactView.svelte.d.ts +113 -0
  11. package/dist/artifact-blocks/CONTRACT.md +225 -0
  12. package/dist/artifact-blocks/CommentPill.svelte +49 -0
  13. package/dist/artifact-blocks/CommentPill.svelte.d.ts +16 -0
  14. package/dist/artifact-blocks/FoldedRounds.svelte +95 -0
  15. package/dist/artifact-blocks/FoldedRounds.svelte.d.ts +9 -0
  16. package/dist/artifact-blocks/Glyph.svelte +54 -0
  17. package/dist/artifact-blocks/Glyph.svelte.d.ts +10 -0
  18. package/dist/artifact-blocks/HistoryScrubber.svelte +500 -0
  19. package/dist/artifact-blocks/HistoryScrubber.svelte.d.ts +15 -0
  20. package/dist/artifact-blocks/Markdown.svelte +186 -0
  21. package/dist/artifact-blocks/Markdown.svelte.d.ts +30 -0
  22. package/dist/artifact-blocks/NoteComposer.svelte +31 -0
  23. package/dist/artifact-blocks/NoteComposer.svelte.d.ts +8 -0
  24. package/dist/artifact-blocks/PlainComposer.svelte +200 -0
  25. package/dist/artifact-blocks/PlainComposer.svelte.d.ts +15 -0
  26. package/dist/artifact-blocks/SectionTools.svelte +102 -0
  27. package/dist/artifact-blocks/SectionTools.svelte.d.ts +19 -0
  28. package/dist/artifact-blocks/adapter.d.ts +13 -0
  29. package/dist/artifact-blocks/adapter.js +31 -0
  30. package/dist/artifact-blocks/autoSend.d.ts +49 -0
  31. package/dist/artifact-blocks/autoSend.js +103 -0
  32. package/dist/artifact-blocks/blocks/actions/ActionsBlock.svelte +557 -0
  33. package/dist/artifact-blocks/blocks/actions/ActionsBlock.svelte.d.ts +48 -0
  34. package/dist/artifact-blocks/blocks/actions/block.d.ts +8 -0
  35. package/dist/artifact-blocks/blocks/actions/block.js +74 -0
  36. package/dist/artifact-blocks/blocks/actions/requests.d.ts +62 -0
  37. package/dist/artifact-blocks/blocks/actions/requests.js +26 -0
  38. package/dist/artifact-blocks/blocks/actions/schema.d.ts +168 -0
  39. package/dist/artifact-blocks/blocks/actions/schema.js +253 -0
  40. package/dist/artifact-blocks/blocks/callout/CalloutBlock.svelte +779 -0
  41. package/dist/artifact-blocks/blocks/callout/CalloutBlock.svelte.d.ts +40 -0
  42. package/dist/artifact-blocks/blocks/callout/block.d.ts +7 -0
  43. package/dist/artifact-blocks/blocks/callout/block.js +39 -0
  44. package/dist/artifact-blocks/blocks/callout/schema.d.ts +72 -0
  45. package/dist/artifact-blocks/blocks/callout/schema.js +115 -0
  46. package/dist/artifact-blocks/blocks/chart/ChartBlock.svelte +875 -0
  47. package/dist/artifact-blocks/blocks/chart/ChartBlock.svelte.d.ts +59 -0
  48. package/dist/artifact-blocks/blocks/chart/block.d.ts +9 -0
  49. package/dist/artifact-blocks/blocks/chart/block.js +70 -0
  50. package/dist/artifact-blocks/blocks/chart/schema.d.ts +171 -0
  51. package/dist/artifact-blocks/blocks/chart/schema.js +498 -0
  52. package/dist/artifact-blocks/blocks/chart/thumb.d.ts +2 -0
  53. package/dist/artifact-blocks/blocks/chart/thumb.js +201 -0
  54. package/dist/artifact-blocks/blocks/checklist/ChecklistBlock.svelte +1048 -0
  55. package/dist/artifact-blocks/blocks/checklist/ChecklistBlock.svelte.d.ts +16 -0
  56. package/dist/artifact-blocks/blocks/checklist/Icon.svelte +105 -0
  57. package/dist/artifact-blocks/blocks/checklist/Icon.svelte.d.ts +17 -0
  58. package/dist/artifact-blocks/blocks/checklist/block.d.ts +10 -0
  59. package/dist/artifact-blocks/blocks/checklist/block.js +63 -0
  60. package/dist/artifact-blocks/blocks/checklist/itemReview.d.ts +16 -0
  61. package/dist/artifact-blocks/blocks/checklist/itemReview.js +63 -0
  62. package/dist/artifact-blocks/blocks/checklist/labels.d.ts +62 -0
  63. package/dist/artifact-blocks/blocks/checklist/labels.js +96 -0
  64. package/dist/artifact-blocks/blocks/checklist/retest.d.ts +43 -0
  65. package/dist/artifact-blocks/blocks/checklist/retest.js +68 -0
  66. package/dist/artifact-blocks/blocks/checklist/schema.d.ts +84 -0
  67. package/dist/artifact-blocks/blocks/checklist/schema.js +91 -0
  68. package/dist/artifact-blocks/blocks/code/CodeBlock.svelte +128 -0
  69. package/dist/artifact-blocks/blocks/code/CodeBlock.svelte.d.ts +12 -0
  70. package/dist/artifact-blocks/blocks/code/block.d.ts +8 -0
  71. package/dist/artifact-blocks/blocks/code/block.js +31 -0
  72. package/dist/artifact-blocks/blocks/code/highlight.d.ts +34 -0
  73. package/dist/artifact-blocks/blocks/code/highlight.js +280 -0
  74. package/dist/artifact-blocks/blocks/code/schema.d.ts +32 -0
  75. package/dist/artifact-blocks/blocks/code/schema.js +39 -0
  76. package/dist/artifact-blocks/blocks/collage/CollageBlock.svelte +290 -0
  77. package/dist/artifact-blocks/blocks/collage/CollageBlock.svelte.d.ts +29 -0
  78. package/dist/artifact-blocks/blocks/collage/block.d.ts +9 -0
  79. package/dist/artifact-blocks/blocks/collage/block.js +29 -0
  80. package/dist/artifact-blocks/blocks/collage/schema.d.ts +52 -0
  81. package/dist/artifact-blocks/blocks/collage/schema.js +86 -0
  82. package/dist/artifact-blocks/blocks/compare/CompareBlock.svelte +484 -0
  83. package/dist/artifact-blocks/blocks/compare/CompareBlock.svelte.d.ts +25 -0
  84. package/dist/artifact-blocks/blocks/compare/block.d.ts +9 -0
  85. package/dist/artifact-blocks/blocks/compare/block.js +32 -0
  86. package/dist/artifact-blocks/blocks/compare/schema.d.ts +74 -0
  87. package/dist/artifact-blocks/blocks/compare/schema.js +148 -0
  88. package/dist/artifact-blocks/blocks/diagram/DiagramBlock.svelte +392 -0
  89. package/dist/artifact-blocks/blocks/diagram/DiagramBlock.svelte.d.ts +30 -0
  90. package/dist/artifact-blocks/blocks/diagram/block.d.ts +9 -0
  91. package/dist/artifact-blocks/blocks/diagram/block.js +50 -0
  92. package/dist/artifact-blocks/blocks/diagram/constants.d.ts +48 -0
  93. package/dist/artifact-blocks/blocks/diagram/constants.js +53 -0
  94. package/dist/artifact-blocks/blocks/diagram/schema.d.ts +161 -0
  95. package/dist/artifact-blocks/blocks/diagram/schema.js +621 -0
  96. package/dist/artifact-blocks/blocks/diagram/thumb.d.ts +2 -0
  97. package/dist/artifact-blocks/blocks/diagram/thumb.js +157 -0
  98. package/dist/artifact-blocks/blocks/diagram/types.d.ts +74 -0
  99. package/dist/artifact-blocks/blocks/diagram/types.js +1 -0
  100. package/dist/artifact-blocks/blocks/diff/DiffBlock.svelte +81 -0
  101. package/dist/artifact-blocks/blocks/diff/DiffBlock.svelte.d.ts +10 -0
  102. package/dist/artifact-blocks/blocks/diff/block.d.ts +7 -0
  103. package/dist/artifact-blocks/blocks/diff/block.js +36 -0
  104. package/dist/artifact-blocks/blocks/diff/schema.d.ts +18 -0
  105. package/dist/artifact-blocks/blocks/diff/schema.js +35 -0
  106. package/dist/artifact-blocks/blocks/diff-review/DiffReviewBlock.svelte +1055 -0
  107. package/dist/artifact-blocks/blocks/diff-review/DiffReviewBlock.svelte.d.ts +5 -0
  108. package/dist/artifact-blocks/blocks/diff-review/block.d.ts +15 -0
  109. package/dist/artifact-blocks/blocks/diff-review/block.js +64 -0
  110. package/dist/artifact-blocks/blocks/diff-review/decisions.d.ts +57 -0
  111. package/dist/artifact-blocks/blocks/diff-review/decisions.js +80 -0
  112. package/dist/artifact-blocks/blocks/diff-review/schema.d.ts +13 -0
  113. package/dist/artifact-blocks/blocks/diff-review/schema.js +84 -0
  114. package/dist/artifact-blocks/blocks/diff-review/types.d.ts +35 -0
  115. package/dist/artifact-blocks/blocks/diff-review/types.js +1 -0
  116. package/dist/artifact-blocks/blocks/explainer/ExplainerBlock.svelte +145 -0
  117. package/dist/artifact-blocks/blocks/explainer/ExplainerBlock.svelte.d.ts +5 -0
  118. package/dist/artifact-blocks/blocks/explainer/block.d.ts +8 -0
  119. package/dist/artifact-blocks/blocks/explainer/block.js +21 -0
  120. package/dist/artifact-blocks/blocks/explainer/schema.d.ts +26 -0
  121. package/dist/artifact-blocks/blocks/explainer/schema.js +69 -0
  122. package/dist/artifact-blocks/blocks/group-content.d.ts +10 -0
  123. package/dist/artifact-blocks/blocks/group-content.js +16 -0
  124. package/dist/artifact-blocks/blocks/group-data.d.ts +10 -0
  125. package/dist/artifact-blocks/blocks/group-data.js +7 -0
  126. package/dist/artifact-blocks/blocks/group-review.d.ts +10 -0
  127. package/dist/artifact-blocks/blocks/group-review.js +12 -0
  128. package/dist/artifact-blocks/blocks/group-visual.d.ts +17 -0
  129. package/dist/artifact-blocks/blocks/group-visual.js +14 -0
  130. package/dist/artifact-blocks/blocks/map/MapBlock.svelte +413 -0
  131. package/dist/artifact-blocks/blocks/map/MapBlock.svelte.d.ts +53 -0
  132. package/dist/artifact-blocks/blocks/map/block.d.ts +9 -0
  133. package/dist/artifact-blocks/blocks/map/block.js +62 -0
  134. package/dist/artifact-blocks/blocks/map/schema.d.ts +123 -0
  135. package/dist/artifact-blocks/blocks/map/schema.js +113 -0
  136. package/dist/artifact-blocks/blocks/map/thumb.d.ts +2 -0
  137. package/dist/artifact-blocks/blocks/map/thumb.js +69 -0
  138. package/dist/artifact-blocks/blocks/markdown/MarkdownBlock.svelte +33 -0
  139. package/dist/artifact-blocks/blocks/markdown/MarkdownBlock.svelte.d.ts +15 -0
  140. package/dist/artifact-blocks/blocks/markdown/block.d.ts +7 -0
  141. package/dist/artifact-blocks/blocks/markdown/block.js +28 -0
  142. package/dist/artifact-blocks/blocks/markdown/render.d.ts +17 -0
  143. package/dist/artifact-blocks/blocks/markdown/render.js +115 -0
  144. package/dist/artifact-blocks/blocks/markdown/schema.d.ts +10 -0
  145. package/dist/artifact-blocks/blocks/markdown/schema.js +23 -0
  146. package/dist/artifact-blocks/blocks/media-picker/MediaPickerBlock.svelte +2112 -0
  147. package/dist/artifact-blocks/blocks/media-picker/MediaPickerBlock.svelte.d.ts +5 -0
  148. package/dist/artifact-blocks/blocks/media-picker/block.d.ts +24 -0
  149. package/dist/artifact-blocks/blocks/media-picker/block.js +137 -0
  150. package/dist/artifact-blocks/blocks/media-picker/choices.d.ts +28 -0
  151. package/dist/artifact-blocks/blocks/media-picker/choices.js +35 -0
  152. package/dist/artifact-blocks/blocks/media-picker/decisions.d.ts +51 -0
  153. package/dist/artifact-blocks/blocks/media-picker/decisions.js +75 -0
  154. package/dist/artifact-blocks/blocks/media-picker/schema.d.ts +7 -0
  155. package/dist/artifact-blocks/blocks/media-picker/schema.js +199 -0
  156. package/dist/artifact-blocks/blocks/media-picker/types.d.ts +92 -0
  157. package/dist/artifact-blocks/blocks/media-picker/types.js +1 -0
  158. package/dist/artifact-blocks/blocks/media-picker/versions.d.ts +51 -0
  159. package/dist/artifact-blocks/blocks/media-picker/versions.js +118 -0
  160. package/dist/artifact-blocks/blocks/mockup/MockupBlock.svelte +213 -0
  161. package/dist/artifact-blocks/blocks/mockup/MockupBlock.svelte.d.ts +5 -0
  162. package/dist/artifact-blocks/blocks/mockup/block.d.ts +26 -0
  163. package/dist/artifact-blocks/blocks/mockup/block.js +52 -0
  164. package/dist/artifact-blocks/blocks/mockup/doc.d.ts +24 -0
  165. package/dist/artifact-blocks/blocks/mockup/doc.js +44 -0
  166. package/dist/artifact-blocks/blocks/mockup/sandbox.d.ts +21 -0
  167. package/dist/artifact-blocks/blocks/mockup/sandbox.js +27 -0
  168. package/dist/artifact-blocks/blocks/mockup/schema.d.ts +7 -0
  169. package/dist/artifact-blocks/blocks/mockup/schema.js +90 -0
  170. package/dist/artifact-blocks/blocks/mockup/types.d.ts +36 -0
  171. package/dist/artifact-blocks/blocks/mockup/types.js +17 -0
  172. package/dist/artifact-blocks/blocks/program/ProgramBlock.svelte +359 -0
  173. package/dist/artifact-blocks/blocks/program/ProgramBlock.svelte.d.ts +32 -0
  174. package/dist/artifact-blocks/blocks/program/block.d.ts +35 -0
  175. package/dist/artifact-blocks/blocks/program/block.js +68 -0
  176. package/dist/artifact-blocks/blocks/program/schema.d.ts +132 -0
  177. package/dist/artifact-blocks/blocks/program/schema.js +268 -0
  178. package/dist/artifact-blocks/blocks/stats/StatsBlock.svelte +315 -0
  179. package/dist/artifact-blocks/blocks/stats/StatsBlock.svelte.d.ts +24 -0
  180. package/dist/artifact-blocks/blocks/stats/block.d.ts +7 -0
  181. package/dist/artifact-blocks/blocks/stats/block.js +49 -0
  182. package/dist/artifact-blocks/blocks/stats/schema.d.ts +82 -0
  183. package/dist/artifact-blocks/blocks/stats/schema.js +43 -0
  184. package/dist/artifact-blocks/blocks/stats/thumb.d.ts +2 -0
  185. package/dist/artifact-blocks/blocks/stats/thumb.js +102 -0
  186. package/dist/artifact-blocks/blocks/table/TableBlock.svelte +490 -0
  187. package/dist/artifact-blocks/blocks/table/TableBlock.svelte.d.ts +28 -0
  188. package/dist/artifact-blocks/blocks/table/block.d.ts +9 -0
  189. package/dist/artifact-blocks/blocks/table/block.js +100 -0
  190. package/dist/artifact-blocks/blocks/table/schema.d.ts +143 -0
  191. package/dist/artifact-blocks/blocks/table/schema.js +278 -0
  192. package/dist/artifact-blocks/blocks/timeline/TimelineBlock.svelte +347 -0
  193. package/dist/artifact-blocks/blocks/timeline/TimelineBlock.svelte.d.ts +42 -0
  194. package/dist/artifact-blocks/blocks/timeline/block.d.ts +9 -0
  195. package/dist/artifact-blocks/blocks/timeline/block.js +96 -0
  196. package/dist/artifact-blocks/blocks/timeline/constants.d.ts +26 -0
  197. package/dist/artifact-blocks/blocks/timeline/constants.js +27 -0
  198. package/dist/artifact-blocks/blocks/timeline/schema.d.ts +102 -0
  199. package/dist/artifact-blocks/blocks/timeline/schema.js +405 -0
  200. package/dist/artifact-blocks/blocks/timeline/thumb.d.ts +2 -0
  201. package/dist/artifact-blocks/blocks/timeline/thumb.js +117 -0
  202. package/dist/artifact-blocks/blocks/timeline/types.d.ts +66 -0
  203. package/dist/artifact-blocks/blocks/timeline/types.js +1 -0
  204. package/dist/artifact-blocks/blocks/transcript/TranscriptBlock.svelte +169 -0
  205. package/dist/artifact-blocks/blocks/transcript/TranscriptBlock.svelte.d.ts +26 -0
  206. package/dist/artifact-blocks/blocks/transcript/block.d.ts +9 -0
  207. package/dist/artifact-blocks/blocks/transcript/block.js +86 -0
  208. package/dist/artifact-blocks/blocks/transcript/schema.d.ts +114 -0
  209. package/dist/artifact-blocks/blocks/transcript/schema.js +126 -0
  210. package/dist/artifact-blocks/builtins.d.ts +40 -0
  211. package/dist/artifact-blocks/builtins.js +22 -0
  212. package/dist/artifact-blocks/contractBlocks.d.ts +92 -0
  213. package/dist/artifact-blocks/contractBlocks.js +279 -0
  214. package/dist/artifact-blocks/history.d.ts +140 -0
  215. package/dist/artifact-blocks/history.js +363 -0
  216. package/dist/artifact-blocks/index.d.ts +40 -0
  217. package/dist/artifact-blocks/index.js +46 -0
  218. package/dist/artifact-blocks/listen/context.d.ts +30 -0
  219. package/dist/artifact-blocks/listen/context.js +30 -0
  220. package/dist/artifact-blocks/liveData.d.ts +78 -0
  221. package/dist/artifact-blocks/liveData.js +137 -0
  222. package/dist/artifact-blocks/liveDataPoller.d.ts +41 -0
  223. package/dist/artifact-blocks/liveDataPoller.js +140 -0
  224. package/dist/artifact-blocks/openNav.d.ts +46 -0
  225. package/dist/artifact-blocks/openNav.js +106 -0
  226. package/dist/artifact-blocks/pageReviewKeys.d.ts +17 -0
  227. package/dist/artifact-blocks/pageReviewKeys.js +115 -0
  228. package/dist/artifact-blocks/params.d.ts +98 -0
  229. package/dist/artifact-blocks/params.js +159 -0
  230. package/dist/artifact-blocks/registry.d.ts +27 -0
  231. package/dist/artifact-blocks/registry.js +83 -0
  232. package/dist/artifact-blocks/review/BlockIcon.svelte +99 -0
  233. package/dist/artifact-blocks/review/BlockIcon.svelte.d.ts +17 -0
  234. package/dist/artifact-blocks/review/BulkRejectForm.svelte +94 -0
  235. package/dist/artifact-blocks/review/BulkRejectForm.svelte.d.ts +11 -0
  236. package/dist/artifact-blocks/review/BulkUndoBar.svelte +40 -0
  237. package/dist/artifact-blocks/review/BulkUndoBar.svelte.d.ts +9 -0
  238. package/dist/artifact-blocks/review/ItemNote.svelte +193 -0
  239. package/dist/artifact-blocks/review/ItemNote.svelte.d.ts +33 -0
  240. package/dist/artifact-blocks/review/NoteToggle.svelte +52 -0
  241. package/dist/artifact-blocks/review/NoteToggle.svelte.d.ts +12 -0
  242. package/dist/artifact-blocks/review/TeamChip.svelte +71 -0
  243. package/dist/artifact-blocks/review/TeamChip.svelte.d.ts +8 -0
  244. package/dist/artifact-blocks/review/attachments.d.ts +10 -0
  245. package/dist/artifact-blocks/review/attachments.js +37 -0
  246. package/dist/artifact-blocks/review/bulk.d.ts +52 -0
  247. package/dist/artifact-blocks/review/bulk.js +61 -0
  248. package/dist/artifact-blocks/review/itemReview.d.ts +33 -0
  249. package/dist/artifact-blocks/review/itemReview.js +112 -0
  250. package/dist/artifact-blocks/review/roundLines.d.ts +14 -0
  251. package/dist/artifact-blocks/review/roundLines.js +20 -0
  252. package/dist/artifact-blocks/review/rounds.d.ts +86 -0
  253. package/dist/artifact-blocks/review/rounds.js +302 -0
  254. package/dist/artifact-blocks/review/saver.d.ts +23 -0
  255. package/dist/artifact-blocks/review/saver.js +48 -0
  256. package/dist/artifact-blocks/review/team.d.ts +31 -0
  257. package/dist/artifact-blocks/review/team.js +42 -0
  258. package/dist/artifact-blocks/review/visualOrder.d.ts +29 -0
  259. package/dist/artifact-blocks/review/visualOrder.js +66 -0
  260. package/dist/artifact-blocks/review.d.ts +180 -0
  261. package/dist/artifact-blocks/review.js +716 -0
  262. package/dist/artifact-blocks/thumb-kit.d.ts +80 -0
  263. package/dist/artifact-blocks/thumb-kit.js +149 -0
  264. package/dist/artifact-blocks/types.d.ts +513 -0
  265. package/dist/artifact-blocks/types.js +1 -0
  266. package/package.json +11 -2
@@ -0,0 +1,66 @@
1
+ <script lang="ts">
2
+ /**
3
+ * AttachmentChip (jatui-vsuzi) — the default chip for one note attachment:
4
+ * a labelled link to the stored bytes (kind · name · size). Hosts with a
5
+ * richer chip (inline player, transcript) pass HostAdapter.attachmentChip.
6
+ * The URL is host-issued, but still policy-checked: an unsafe one renders
7
+ * the label as plain text.
8
+ */
9
+ import { isSafeLinkUrl } from "./params.js"
10
+ import type { NoteAttachment } from "./types.js"
11
+
12
+ let { clip }: { clip: NoteAttachment } = $props()
13
+
14
+ const KIND_LABEL: Record<string, string> = {
15
+ screen: "Screen",
16
+ voice: "Voice",
17
+ audio: "Audio",
18
+ video: "Video",
19
+ image: "Image",
20
+ file: "File",
21
+ }
22
+
23
+ function size(bytes: number): string {
24
+ if (!Number.isFinite(bytes) || bytes <= 0) return ""
25
+ if (bytes < 1024) return `${bytes} B`
26
+ if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)} KB`
27
+ return `${(bytes / 1024 / 1024).toFixed(1)} MB`
28
+ }
29
+
30
+ function duration(s: number | null): string {
31
+ if (s == null || !Number.isFinite(s)) return ""
32
+ const m = Math.floor(s / 60)
33
+ const r = Math.round(s % 60)
34
+ return `${m}:${String(r).padStart(2, "0")}`
35
+ }
36
+
37
+ const name = $derived(clip.label ?? clip.name)
38
+ const meta = $derived(
39
+ [KIND_LABEL[clip.kind] ?? "File", duration(clip.durationSeconds) || size(clip.sizeBytes)]
40
+ .filter(Boolean)
41
+ .join(" · "),
42
+ )
43
+ const href = $derived(typeof clip.url === "string" && isSafeLinkUrl(clip.url) ? clip.url : null)
44
+ </script>
45
+
46
+ {#if href}
47
+ <a
48
+ {href}
49
+ target="_blank"
50
+ rel="noopener noreferrer"
51
+ class="border-base-content/15 hover:border-primary inline-flex max-w-[16rem] items-center gap-1.5 rounded-field border px-2 py-0.5 text-xs"
52
+ title={clip.transcript ?? name}
53
+ data-attachment-chip
54
+ >
55
+ <span class="truncate">{name}</span>
56
+ {#if meta}<span class="text-base-content/50 shrink-0">{meta}</span>{/if}
57
+ </a>
58
+ {:else}
59
+ <span
60
+ class="border-base-content/15 inline-flex max-w-[16rem] items-center gap-1.5 rounded-field border px-2 py-0.5 text-xs"
61
+ data-attachment-chip
62
+ >
63
+ <span class="truncate">{name}</span>
64
+ {#if meta}<span class="text-base-content/50 shrink-0">{meta}</span>{/if}
65
+ </span>
66
+ {/if}
@@ -0,0 +1,7 @@
1
+ import type { NoteAttachment } from "./types.js";
2
+ type $$ComponentProps = {
3
+ clip: NoteAttachment;
4
+ };
5
+ declare const AttachmentChip: import("svelte").Component<$$ComponentProps, {}, "">;
6
+ type AttachmentChip = ReturnType<typeof AttachmentChip>;
7
+ export default AttachmentChip;
@@ -0,0 +1,309 @@
1
+ <script lang="ts">
2
+ /**
3
+ * BlockComments (origin mos-kib2f) — the per-block comment thread: an icon
4
+ * + unresolved-count chip under each block that opens a small thread
5
+ * drawer.
6
+ *
7
+ * The drawer reads and posts through the host's CommentsService
8
+ * (HostAdapter.comments):
9
+ * - the thread restores on first open (`load`);
10
+ * - posting is the host's call (`post`) — a comment is attributable to a
11
+ * person, so a host should only offer it to a signed-in viewer;
12
+ * - the poster can resolve their OWN comment (`setResolved`) — the
13
+ * resolved flag is per-poster, never someone else's.
14
+ *
15
+ * No service, or a disabled surface → renders NOTHING (the read-only
16
+ * mode). Theming is token-only, radius tokens, light + dark + phone, and
17
+ * every animation sits under motion-safe.
18
+ */
19
+ import CommentPill from "./CommentPill.svelte"
20
+ import NoteComposer from "./NoteComposer.svelte"
21
+ import AttachmentChip from "./AttachmentChip.svelte"
22
+ import { hostAdapter } from "./adapter.js"
23
+ import type { BlockComment, NoteAttachment } from "./types.js"
24
+
25
+ interface Props {
26
+ artifactId: string
27
+ version: number
28
+ blockId: string
29
+ /** The block's label (the block title / type) — the drawer's heading. */
30
+ blockLabel: string
31
+ /** Server-rendered unresolved count for THIS block (0 until first load). */
32
+ count?: number
33
+ /** A session member is viewing (false on the public share route). */
34
+ enabled: boolean
35
+ /**
36
+ * The block below breaks out of the reading column (a wide table).
37
+ * The trigger row then uses the SAME breakout — the pill must align
38
+ * with the block's actual right edge, never sit inboard of it, and
39
+ * never touch the block's chrome (mos-51g8l).
40
+ */
41
+ wide?: boolean
42
+ /**
43
+ * The trigger lives elsewhere (mos-8fvt9): the block's heading row
44
+ * renders a CommentPill through SectionTools and drives `open`. This
45
+ * component then renders only the thread drawer — kept here, at the
46
+ * section level, where no block's `@container` can trap its
47
+ * position: fixed.
48
+ */
49
+ hosted?: boolean
50
+ /** The drawer is open (bindable, so a hosted trigger can drive it). */
51
+ open?: boolean
52
+ /** Reports the live unresolved count to a hosted trigger. */
53
+ onunresolved?: (n: number) => void
54
+ }
55
+
56
+ let {
57
+ artifactId,
58
+ version,
59
+ blockId,
60
+ blockLabel,
61
+ count = 0,
62
+ enabled,
63
+ wide = false,
64
+ hosted = false,
65
+ open = $bindable(false),
66
+ onunresolved = undefined,
67
+ }: Props = $props()
68
+
69
+ type CommentRow = BlockComment
70
+
71
+ const adapter = hostAdapter()
72
+ const service = adapter.comments
73
+ const Chip = adapter.attachmentChip ?? AttachmentChip
74
+ /** Live only with a service: no service is the read-only mode. */
75
+ const live = $derived(enabled && service !== undefined)
76
+
77
+ let loaded = $state(false)
78
+ /** The thread could not be read: say so, never "No comments yet". */
79
+ let loadFailed = $state(false)
80
+ let comments = $state<CommentRow[]>([])
81
+ let sending = $state(false)
82
+ let error = $state("")
83
+
84
+ /** The chip's number: unresolved, live-updated as the thread changes. */
85
+ const unresolved = $derived(
86
+ comments.length > 0
87
+ ? comments.filter((c) => !c.resolved).length
88
+ : (count ?? 0),
89
+ )
90
+
91
+ $effect(() => {
92
+ onunresolved?.(unresolved)
93
+ })
94
+
95
+ // The thread restores on first open, whoever opened it (own trigger or a
96
+ // hosted one).
97
+ $effect(() => {
98
+ if (open && !loaded && live) void load()
99
+ })
100
+
101
+ function close() {
102
+ open = false
103
+ error = ""
104
+ }
105
+
106
+ function onKeydown(e: KeyboardEvent) {
107
+ if (e.key === "Escape" && open) close()
108
+ }
109
+
110
+ function toggle() {
111
+ if (open) close()
112
+ else open = true
113
+ }
114
+
115
+ async function load() {
116
+ if (!service) return
117
+ loaded = true
118
+ loadFailed = false
119
+ try {
120
+ comments = (await service.load({ artifactId, version, blockId })) ?? []
121
+ } catch {
122
+ loadFailed = true
123
+ // History is a convenience; a failed GET must not block commenting.
124
+ }
125
+ }
126
+
127
+ async function post(payload: { text: string; clips: NoteAttachment[] }) {
128
+ const text = payload.text
129
+ if (sending) return
130
+ if (!text && payload.clips.length === 0) return
131
+ sending = true
132
+ error = ""
133
+ try {
134
+ if (!service) throw new Error("Comments are not available here")
135
+ const comment = await service.post({
136
+ artifactId,
137
+ version,
138
+ blockId,
139
+ body: text,
140
+ attachments: payload.clips,
141
+ })
142
+ comments = [...comments, comment]
143
+ } catch (e) {
144
+ error = e instanceof Error ? e.message : "Could not comment right now"
145
+ // The composer keeps the draft; it surfaces the failure.
146
+ throw e
147
+ } finally {
148
+ sending = false
149
+ }
150
+ }
151
+
152
+ async function toggleResolved(c: CommentRow) {
153
+ if (!c.mine) return // only the poster flips their own flag
154
+ const next = !c.resolved
155
+ try {
156
+ if (!service) throw new Error("Could not update the comment")
157
+ await service.setResolved({ artifactId, commentId: c.id, resolved: next })
158
+ comments = comments.map((row) =>
159
+ row.id === c.id ? { ...row, resolved: next } : row,
160
+ )
161
+ } catch (e) {
162
+ error = e instanceof Error ? e.message : "Could not update the comment"
163
+ }
164
+ }
165
+
166
+ const timeFmt = new Intl.DateTimeFormat("en-US", {
167
+ month: "short",
168
+ day: "numeric",
169
+ hour: "numeric",
170
+ minute: "2-digit",
171
+ })
172
+ function when(iso: string): string {
173
+ const d = new Date(iso)
174
+ return Number.isFinite(d.getTime()) ? timeFmt.format(d) : ""
175
+ }
176
+ </script>
177
+
178
+ <svelte:window onkeydown={onKeydown} />
179
+
180
+ {#if live}
181
+ <!-- mb-2: the trigger NEVER touches block chrome (a pill kissing a wide
182
+ table's filter box). Matches the failed-save strip's mb-2, so chrome
183
+ rows read at one rhythm. -->
184
+ {#if !hosted}
185
+ <div class="mb-2 flex justify-end" class:bc-wide={wide}>
186
+ <CommentPill label={blockLabel} {unresolved} {open} onclick={toggle} />
187
+ </div>
188
+ {/if}
189
+
190
+ {#if open}
191
+ <div
192
+ role="dialog"
193
+ aria-label="Comments on {blockLabel}"
194
+ class="border-base-content/10 bg-base-100 fixed inset-x-2 bottom-16 z-40 flex max-h-[60vh] flex-col rounded-box border shadow-xl sm:inset-x-auto sm:right-4 sm:w-[22rem]"
195
+ >
196
+ <header
197
+ class="border-base-content/10 flex items-center gap-2 border-b px-4 py-3"
198
+ >
199
+ <h2 class="min-w-0 truncate text-sm font-semibold">{blockLabel}</h2>
200
+ <span class="text-base-content/50 shrink-0 text-xs">comments</span>
201
+ <button
202
+ type="button"
203
+ class="btn btn-ghost btn-xs btn-circle ml-auto"
204
+ aria-label="Close comments"
205
+ onclick={close}
206
+ >
207
+ ✕
208
+ </button>
209
+ </header>
210
+
211
+ <div class="flex-1 overflow-y-auto px-4 py-3" tabindex="-1">
212
+ {#if error}
213
+ <p role="alert" class="text-error-content text-sm">{error}</p>
214
+ {/if}
215
+
216
+ {#if loadFailed}
217
+ <p class="text-base-content/60 text-sm" data-comments-load-failed>
218
+ Couldn't load earlier comments.
219
+ <button
220
+ type="button"
221
+ class="link link-primary"
222
+ onclick={() => void load()}>Try again</button
223
+ >
224
+ </p>
225
+ {:else if comments.length === 0}
226
+ <p class="text-base-content/50 text-sm">No comments yet.</p>
227
+ {/if}
228
+
229
+ <ul class="flex flex-col gap-3">
230
+ {#each comments as c (c.id)}
231
+ <li
232
+ class="rounded-field border border-base-content/10 px-3 py-2 {c.resolved
233
+ ? 'opacity-60'
234
+ : ''}"
235
+ >
236
+ {#if c.body}
237
+ <p
238
+ class="text-sm {c.resolved
239
+ ? 'line-through'
240
+ : ''} whitespace-pre-wrap"
241
+ >
242
+ {c.body}
243
+ </p>
244
+ {/if}
245
+ {#if c.attachments && c.attachments.length > 0}
246
+ <ul
247
+ class="mt-1.5 flex flex-wrap items-center gap-1.5"
248
+ aria-label="Comment attachments"
249
+ >
250
+ {#each c.attachments as a (a.name)}
251
+ <li><Chip clip={a} /></li>
252
+ {/each}
253
+ </ul>
254
+ {/if}
255
+ <div
256
+ class="text-base-content/40 mt-1 flex items-center gap-2 text-2xs"
257
+ >
258
+ <span>{when(c.created_at)}</span>
259
+ {#if c.mine}
260
+ <button
261
+ type="button"
262
+ class="link link-hover text-base-content/60"
263
+ onclick={() => toggleResolved(c)}
264
+ >
265
+ {c.resolved ? "unresolve" : "resolve"}
266
+ </button>
267
+ {/if}
268
+ </div>
269
+ </li>
270
+ {/each}
271
+ </ul>
272
+ </div>
273
+
274
+ <footer class="border-base-content/10 border-t px-4 py-3">
275
+ <!-- The ONE composer (the host's, else jatui's text composer). Its
276
+ submit row posts; a failed post keeps the draft. -->
277
+ <NoteComposer
278
+ {artifactId}
279
+ submitLabel="Comment"
280
+ onSubmit={post}
281
+ busy={sending}
282
+ {error}
283
+ placeholder="Comment on this block…"
284
+ label="Your comment on {blockLabel}"
285
+ rows={2}
286
+ maxLength={20000}
287
+ autofocus
288
+ />
289
+ </footer>
290
+ </div>
291
+ {/if}
292
+ {/if}
293
+
294
+ <style>
295
+ /* Wide block (mos-51g8l): the trigger row breaks out with the SAME
296
+ formula the wide block itself uses (`.tb-wide` in TableBlock.svelte) —
297
+ centred on the reading column, capped at 80rem, kept 1.5rem inside the
298
+ page view (--artifact-page-w is the page's MEASURED width, so an admin
299
+ sidebar host stays correct). The two edges move together, so the pill's
300
+ right edge sits on the block's right edge instead of inboard of it.
301
+ Only the /a page opts in — pinned/embedded hosts (no
302
+ [data-artifact-page]) keep the column, and there the formula degrades
303
+ to 100% anyway (min(100% - 3rem, 80rem) < 100%). */
304
+ :global([data-artifact-page]) .bc-wide {
305
+ --bc-w: max(100%, min(var(--artifact-page-w, 100%) - 3rem, 80rem));
306
+ width: var(--bc-w);
307
+ margin-inline: calc((100% - var(--bc-w)) / 2);
308
+ }
309
+ </style>
@@ -0,0 +1,33 @@
1
+ interface Props {
2
+ artifactId: string;
3
+ version: number;
4
+ blockId: string;
5
+ /** The block's label (the block title / type) — the drawer's heading. */
6
+ blockLabel: string;
7
+ /** Server-rendered unresolved count for THIS block (0 until first load). */
8
+ count?: number;
9
+ /** A session member is viewing (false on the public share route). */
10
+ enabled: boolean;
11
+ /**
12
+ * The block below breaks out of the reading column (a wide table).
13
+ * The trigger row then uses the SAME breakout — the pill must align
14
+ * with the block's actual right edge, never sit inboard of it, and
15
+ * never touch the block's chrome (mos-51g8l).
16
+ */
17
+ wide?: boolean;
18
+ /**
19
+ * The trigger lives elsewhere (mos-8fvt9): the block's heading row
20
+ * renders a CommentPill through SectionTools and drives `open`. This
21
+ * component then renders only the thread drawer — kept here, at the
22
+ * section level, where no block's `@container` can trap its
23
+ * position: fixed.
24
+ */
25
+ hosted?: boolean;
26
+ /** The drawer is open (bindable, so a hosted trigger can drive it). */
27
+ open?: boolean;
28
+ /** Reports the live unresolved count to a hosted trigger. */
29
+ onunresolved?: (n: number) => void;
30
+ }
31
+ declare const BlockComments: import("svelte").Component<Props, {}, "open">;
32
+ type BlockComments = ReturnType<typeof BlockComments>;
33
+ export default BlockComments;