@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,143 @@
1
+ /**
2
+ * Table block — params schema, cell formatting/tone logic and CSV builder.
3
+ *
4
+ * Pure functions only (no DOM) so `block.test.ts` can exercise them and
5
+ * `TableBlock.svelte` stays a thin render layer over jatui's DataTable.
6
+ *
7
+ * Untrusted input rules (CONTRACT.md): every string is length-capped and
8
+ * rendered as text (Svelte escapes it — never {@html}); link hrefs go
9
+ * through `isSafeUrl` (https or root-relative, never `//`-protocol-relative
10
+ * or any scheme). `urlSchema` NOTE: the core task (mos-bqeoa) will publish
11
+ * `src/lib/artifact-blocks/params.ts` with the canonical urlSchema — until it
12
+ * lands this folder carries this local copy and should switch to the shared
13
+ * one (tracked in the block task's review signal).
14
+ */
15
+ import { z } from "zod";
16
+ export declare const COLUMN_TYPES: readonly ["text", "number", "percent", "currency", "date", "badge", "link"];
17
+ export type ColumnType = (typeof COLUMN_TYPES)[number];
18
+ export declare const MAX_ROWS = 5000;
19
+ export declare const MAX_COLUMNS = 24;
20
+ export type CellValue = string | number | boolean | null;
21
+ declare const columnSchema: z.ZodObject<{
22
+ key: z.ZodString;
23
+ label: z.ZodString;
24
+ type: z.ZodDefault<z.ZodEnum<{
25
+ number: "number";
26
+ date: "date";
27
+ link: "link";
28
+ text: "text";
29
+ badge: "badge";
30
+ currency: "currency";
31
+ percent: "percent";
32
+ }>>;
33
+ direction: z.ZodDefault<z.ZodEnum<{
34
+ highIsGood: "highIsGood";
35
+ lowIsGood: "lowIsGood";
36
+ }>>;
37
+ good: z.ZodOptional<z.ZodNumber>;
38
+ warn: z.ZodOptional<z.ZodNumber>;
39
+ tones: z.ZodOptional<z.ZodArray<z.ZodObject<{
40
+ value: z.ZodString;
41
+ tone: z.ZodEnum<{
42
+ warn: "warn";
43
+ good: "good";
44
+ bad: "bad";
45
+ }>;
46
+ }, z.core.$strip>>>;
47
+ hrefKey: z.ZodOptional<z.ZodString>;
48
+ width: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
49
+ auto: "auto";
50
+ md: "md";
51
+ lg: "lg";
52
+ xs: "xs";
53
+ sm: "sm";
54
+ }>, z.ZodNumber]>>;
55
+ }, z.core.$strip>;
56
+ export type ColumnSpec = z.infer<typeof columnSchema>;
57
+ export declare const tableSchema: z.ZodObject<{
58
+ title: z.ZodOptional<z.ZodString>;
59
+ columns: z.ZodArray<z.ZodObject<{
60
+ key: z.ZodString;
61
+ label: z.ZodString;
62
+ type: z.ZodDefault<z.ZodEnum<{
63
+ number: "number";
64
+ date: "date";
65
+ link: "link";
66
+ text: "text";
67
+ badge: "badge";
68
+ currency: "currency";
69
+ percent: "percent";
70
+ }>>;
71
+ direction: z.ZodDefault<z.ZodEnum<{
72
+ highIsGood: "highIsGood";
73
+ lowIsGood: "lowIsGood";
74
+ }>>;
75
+ good: z.ZodOptional<z.ZodNumber>;
76
+ warn: z.ZodOptional<z.ZodNumber>;
77
+ tones: z.ZodOptional<z.ZodArray<z.ZodObject<{
78
+ value: z.ZodString;
79
+ tone: z.ZodEnum<{
80
+ warn: "warn";
81
+ good: "good";
82
+ bad: "bad";
83
+ }>;
84
+ }, z.core.$strip>>>;
85
+ hrefKey: z.ZodOptional<z.ZodString>;
86
+ width: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
87
+ auto: "auto";
88
+ md: "md";
89
+ lg: "lg";
90
+ xs: "xs";
91
+ sm: "sm";
92
+ }>, z.ZodNumber]>>;
93
+ }, z.core.$strip>>;
94
+ rows: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>>;
95
+ pageSize: z.ZodDefault<z.ZodNumber>;
96
+ filterable: z.ZodDefault<z.ZodBoolean>;
97
+ maxHeightPx: z.ZodDefault<z.ZodNumber>;
98
+ currency: z.ZodDefault<z.ZodString>;
99
+ csv: z.ZodDefault<z.ZodBoolean>;
100
+ wide: z.ZodOptional<z.ZodBoolean>;
101
+ dataKey: z.ZodOptional<z.ZodString>;
102
+ }, z.core.$strip>;
103
+ export type TableParams = z.infer<typeof tableSchema>;
104
+ /** https:// or root-relative only; `//host` (protocol-relative) is NOT safe
105
+ * because the browser fills the page's scheme — treat it as external junk. */
106
+ export declare function isSafeUrl(u: unknown): boolean;
107
+ export type Tone = "good" | "warn" | "bad";
108
+ /** Solid tone chips only: per DESIGN.md's measured contrast table, soft and
109
+ * outline chip variants fail AA on several tones in light themes, while
110
+ * solid clears AA on every tone in both themes. */
111
+ export declare const TONE_CLASS: Record<Tone, string>;
112
+ export declare const NUMERIC_TYPES: readonly ColumnType[];
113
+ /** Conditional tone for one cell against its column's thresholds. */
114
+ export declare function toneForCell(col: ColumnSpec, value: CellValue): Tone | null;
115
+ /** How one column claims horizontal space. `shrink` = content width, no
116
+ * wrapping. `flex` = wraps, gets `pct` of the width left after the shrink
117
+ * columns (the classic width:1px / width:N% table pattern), never narrower
118
+ * than `minRem`. */
119
+ export type ColumnLayout = {
120
+ mode: "shrink";
121
+ } | {
122
+ mode: "flex";
123
+ pct: number;
124
+ minRem: number;
125
+ };
126
+ /** Resolve every column's width (explicit hint first, then a default by
127
+ * column type and, for text, by the longest/average value in `rows`). */
128
+ export declare function resolveColumnLayout(columns: ColumnSpec[], rows: Record<string, CellValue>[]): ColumnLayout[];
129
+ /** Wide layout: explicit `wide`, else more than 4 columns. */
130
+ export declare function isWide(params: Pick<TableParams, "wide" | "columns">): boolean;
131
+ /** What a cell says (also what filtering and the CSV see). */
132
+ export declare function formatCell(value: CellValue, col: ColumnSpec, currency: string): string;
133
+ /** Sort key per column type: numbers/date numerically (missing = lowest),
134
+ * text case-insensitively. */
135
+ export declare function sortValue(value: CellValue, type: ColumnType): string | number;
136
+ /** Case-insensitive substring match across the DISPLAY value of every column. */
137
+ export declare function filterRows(rows: Record<string, CellValue>[], columns: ColumnSpec[], query: string, currency: string): Record<string, CellValue>[];
138
+ /** RFC-4180 CSV: quote fields containing comma/quote/newline; "" escapes ". */
139
+ export declare function toCsv(headers: string[], rows: string[][]): string;
140
+ /** Trigger a client-side download. No-ops (silently) where object URLs don't
141
+ * exist (SSR, jsdom) — tests assert on `toCsv` output instead. */
142
+ export declare function downloadCsv(filename: string, csv: string): void;
143
+ export {};
@@ -0,0 +1,278 @@
1
+ /**
2
+ * Table block — params schema, cell formatting/tone logic and CSV builder.
3
+ *
4
+ * Pure functions only (no DOM) so `block.test.ts` can exercise them and
5
+ * `TableBlock.svelte` stays a thin render layer over jatui's DataTable.
6
+ *
7
+ * Untrusted input rules (CONTRACT.md): every string is length-capped and
8
+ * rendered as text (Svelte escapes it — never {@html}); link hrefs go
9
+ * through `isSafeUrl` (https or root-relative, never `//`-protocol-relative
10
+ * or any scheme). `urlSchema` NOTE: the core task (mos-bqeoa) will publish
11
+ * `src/lib/artifact-blocks/params.ts` with the canonical urlSchema — until it
12
+ * lands this folder carries this local copy and should switch to the shared
13
+ * one (tracked in the block task's review signal).
14
+ */
15
+ import { z } from "zod";
16
+ export const COLUMN_TYPES = [
17
+ "text",
18
+ "number",
19
+ "percent",
20
+ "currency",
21
+ "date",
22
+ "badge",
23
+ "link",
24
+ ];
25
+ export const MAX_ROWS = 5000;
26
+ export const MAX_COLUMNS = 24;
27
+ /** Named column-width hints; `auto` shrinks the column to its content. */
28
+ const WIDTH_HINTS = ["xs", "sm", "md", "lg", "auto"];
29
+ const columnSchema = z.object({
30
+ key: z.string().min(1).max(80),
31
+ label: z.string().min(1).max(80),
32
+ type: z.enum(COLUMN_TYPES).default("text"),
33
+ /** Threshold tone direction (numeric columns): is a high value good? */
34
+ direction: z.enum(["highIsGood", "lowIsGood"]).default("highIsGood"),
35
+ /** Tone thresholds — both set: good/warn bands + bad remainder; only
36
+ * `warn`: at/past warn = warn, beyond = bad; only `good`: good or neutral. */
37
+ good: z.number().finite().optional(),
38
+ warn: z.number().finite().optional(),
39
+ /** badge columns: exact value → tone chips. */
40
+ tones: z
41
+ .array(z.object({
42
+ value: z.string().max(80),
43
+ tone: z.enum(["good", "warn", "bad"]),
44
+ }))
45
+ .max(50)
46
+ .optional(),
47
+ /** link columns: row key that holds the URL (default: the cell value). */
48
+ hrefKey: z.string().max(80).optional(),
49
+ /** Width hint: xs|sm|md|lg (text that wraps, growing share of the free
50
+ * width), auto (shrink to content, never wraps) or a number = fr weight
51
+ * (0.5-12). Omitted: badge/number/date/link columns and short text shrink
52
+ * to content; long text columns share the rest by length. */
53
+ width: z
54
+ .union([z.enum(WIDTH_HINTS), z.number().finite().min(0.5).max(12)])
55
+ .optional(),
56
+ });
57
+ export const tableSchema = z.object({
58
+ title: z.string().max(200).optional(),
59
+ columns: z.array(columnSchema).min(1).max(MAX_COLUMNS),
60
+ rows: z
61
+ .array(z.record(z.string(), z.union([
62
+ z.string().max(500),
63
+ z.number().finite(),
64
+ z.boolean(),
65
+ z.null(),
66
+ ])))
67
+ .min(1)
68
+ .max(MAX_ROWS),
69
+ /** Rows per page (pagination lives at 50 by default; hard cap 200). */
70
+ pageSize: z.number().int().min(5).max(200).default(50),
71
+ filterable: z.boolean().default(true),
72
+ /** Sticky header needs its own scroller — height in px (120–2000). */
73
+ maxHeightPx: z.number().int().min(120).max(2000).default(420),
74
+ /** ISO 4217 code used when a column type is "currency". */
75
+ currency: z
76
+ .string()
77
+ .regex(/^[A-Za-z]{3}$/)
78
+ .default("USD"),
79
+ /** Offer the CSV download button. */
80
+ csv: z.boolean().default(true),
81
+ /** Break out of the page's reading column to the full viewport width
82
+ * (capped). Default: on when the table has more than 4 columns. */
83
+ wide: z.boolean().optional(),
84
+ /** Phase-3 live data: key into ctx.data whose value replaces params. */
85
+ dataKey: z.string().max(80).optional(),
86
+ });
87
+ // ── URLs (local urlSchema until core params.ts lands) ─────────────────────
88
+ /** https:// or root-relative only; `//host` (protocol-relative) is NOT safe
89
+ * because the browser fills the page's scheme — treat it as external junk. */
90
+ export function isSafeUrl(u) {
91
+ if (typeof u !== "string" || u.length === 0 || u.length > 2048)
92
+ return false;
93
+ if (u.startsWith("//"))
94
+ return false;
95
+ if (u.startsWith("/"))
96
+ return true;
97
+ return /^https:\/\//.test(u);
98
+ }
99
+ /** Solid tone chips only: per DESIGN.md's measured contrast table, soft and
100
+ * outline chip variants fail AA on several tones in light themes, while
101
+ * solid clears AA on every tone in both themes. */
102
+ export const TONE_CLASS = {
103
+ good: "badge-success",
104
+ warn: "badge-warning",
105
+ bad: "badge-error",
106
+ };
107
+ export const NUMERIC_TYPES = [
108
+ "number",
109
+ "percent",
110
+ "currency",
111
+ ];
112
+ /** Conditional tone for one cell against its column's thresholds. */
113
+ export function toneForCell(col, value) {
114
+ if (col.type === "badge") {
115
+ const hit = col.tones?.find((t) => t.value === String(value));
116
+ return hit?.tone ?? null;
117
+ }
118
+ if (!NUMERIC_TYPES.includes(col.type))
119
+ return null;
120
+ if (typeof value !== "number" || !Number.isFinite(value))
121
+ return null;
122
+ const { good, warn, direction } = col;
123
+ const above = direction === "highIsGood";
124
+ if (good !== undefined && warn !== undefined) {
125
+ if (above)
126
+ return value >= good ? "good" : value >= warn ? "warn" : "bad";
127
+ return value <= good ? "good" : value <= warn ? "warn" : "bad";
128
+ }
129
+ if (good !== undefined)
130
+ return (above ? value >= good : value <= good) ? "good" : null;
131
+ if (warn !== undefined)
132
+ return (above ? value >= warn : value <= warn) ? "warn" : "bad";
133
+ return null;
134
+ }
135
+ const HINT_FLEX = {
136
+ xs: [1, 5],
137
+ sm: [2, 8],
138
+ md: [3, 11],
139
+ lg: [4, 14],
140
+ };
141
+ /** Text no longer than this stays on one line and sizes to content. */
142
+ const SHORT_TEXT_CHARS = 28;
143
+ /** Resolve every column's width (explicit hint first, then a default by
144
+ * column type and, for text, by the longest/average value in `rows`). */
145
+ export function resolveColumnLayout(columns, rows) {
146
+ const weights = columns.map((c) => {
147
+ const w = c.width;
148
+ if (w === "auto")
149
+ return null;
150
+ if (typeof w === "number")
151
+ return [w, 8];
152
+ if (w)
153
+ return HINT_FLEX[w];
154
+ if (c.type !== "text")
155
+ return null;
156
+ let max = 0;
157
+ let total = 0;
158
+ for (const r of rows) {
159
+ const len = String(r[c.key] ?? "").length;
160
+ if (len > max)
161
+ max = len;
162
+ total += len;
163
+ }
164
+ if (max <= SHORT_TEXT_CHARS)
165
+ return null;
166
+ const avg = rows.length ? total / rows.length : 0;
167
+ return HINT_FLEX[avg < 40 ? "sm" : avg < 100 ? "md" : "lg"];
168
+ });
169
+ const sum = weights.reduce((a, w) => a + (w ? w[0] : 0), 0);
170
+ return weights.map((w) => w
171
+ ? {
172
+ mode: "flex",
173
+ pct: Math.round((w[0] / sum) * 1000) / 10,
174
+ minRem: w[1],
175
+ }
176
+ : { mode: "shrink" });
177
+ }
178
+ /** Wide layout: explicit `wide`, else more than 4 columns. */
179
+ export function isWide(params) {
180
+ return params.wide ?? params.columns.length > 4;
181
+ }
182
+ // ── Display formatting ────────────────────────────────────────────────────
183
+ function parseDateValue(value) {
184
+ if (typeof value === "number")
185
+ return Number.isFinite(value) ? value : null;
186
+ if (typeof value !== "string")
187
+ return null;
188
+ const m = /^(\d{4})-(\d{2})(?:-(\d{2}))?$/.exec(value.trim());
189
+ if (m) {
190
+ const d = new Date(Number(m[1]), Number(m[2]) - 1, m[3] ? Number(m[3]) : 1);
191
+ return Number.isFinite(d.getTime()) ? d.getTime() : null;
192
+ }
193
+ const ms = new Date(value).getTime();
194
+ return Number.isFinite(ms) ? ms : null;
195
+ }
196
+ /** What a cell says (also what filtering and the CSV see). */
197
+ export function formatCell(value, col, currency) {
198
+ if (value === null || value === undefined || value === "")
199
+ return "n/a";
200
+ switch (col.type) {
201
+ case "number":
202
+ return typeof value === "number"
203
+ ? new Intl.NumberFormat("en-US", { maximumFractionDigits: 2 }).format(value)
204
+ : String(value);
205
+ case "percent":
206
+ return typeof value === "number"
207
+ ? `${new Intl.NumberFormat("en-US", { maximumFractionDigits: 2 }).format(value)}%`
208
+ : String(value);
209
+ case "currency":
210
+ return typeof value === "number"
211
+ ? new Intl.NumberFormat("en-US", {
212
+ style: "currency",
213
+ currency,
214
+ maximumFractionDigits: 2,
215
+ }).format(value)
216
+ : String(value);
217
+ case "date": {
218
+ const ms = parseDateValue(value);
219
+ return ms === null
220
+ ? String(value)
221
+ : new Intl.DateTimeFormat("en-US", {
222
+ year: "numeric",
223
+ month: "short",
224
+ day: "numeric",
225
+ }).format(ms);
226
+ }
227
+ default:
228
+ return String(value);
229
+ }
230
+ }
231
+ // ── Sort ──────────────────────────────────────────────────────────────────
232
+ /** Sort key per column type: numbers/date numerically (missing = lowest),
233
+ * text case-insensitively. */
234
+ export function sortValue(value, type) {
235
+ if (type === "date")
236
+ return parseDateValue(value) ?? Number.NEGATIVE_INFINITY;
237
+ if (NUMERIC_TYPES.includes(type))
238
+ return typeof value === "number" && Number.isFinite(value)
239
+ ? value
240
+ : Number.NEGATIVE_INFINITY;
241
+ return String(value ?? "").toLowerCase();
242
+ }
243
+ // ── Filtering ─────────────────────────────────────────────────────────────
244
+ /** Case-insensitive substring match across the DISPLAY value of every column. */
245
+ export function filterRows(rows, columns, query, currency) {
246
+ const needle = query.trim().toLowerCase();
247
+ if (!needle)
248
+ return rows;
249
+ return rows.filter((r) => columns.some((c) => formatCell(r[c.key] ?? null, c, currency)
250
+ .toLowerCase()
251
+ .includes(needle)));
252
+ }
253
+ // ── CSV ───────────────────────────────────────────────────────────────────
254
+ /** RFC-4180 CSV: quote fields containing comma/quote/newline; "" escapes ". */
255
+ export function toCsv(headers, rows) {
256
+ const esc = (v) => /[",\n\r]/.test(v) ? `"${v.replace(/"/g, '""')}"` : v;
257
+ return [headers, ...rows]
258
+ .map((r) => r.map((c) => esc(c ?? "")).join(","))
259
+ .join("\r\n");
260
+ }
261
+ /** Trigger a client-side download. No-ops (silently) where object URLs don't
262
+ * exist (SSR, jsdom) — tests assert on `toCsv` output instead. */
263
+ export function downloadCsv(filename, csv) {
264
+ if (typeof document === "undefined")
265
+ return;
266
+ if (typeof URL.createObjectURL !== "function")
267
+ return;
268
+ // BOM so Excel opens UTF-8 correctly.
269
+ const blob = new Blob(["\uFEFF" + csv], { type: "text/csv;charset=utf-8" });
270
+ const url = URL.createObjectURL(blob);
271
+ const a = document.createElement("a");
272
+ a.href = url;
273
+ a.download = filename;
274
+ document.body.appendChild(a);
275
+ a.click();
276
+ a.remove();
277
+ URL.revokeObjectURL(url);
278
+ }