@joewinke/jatui 0.36.3 → 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 (271) 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/dist/components/Button.svelte +8 -0
  267. package/dist/components/TextInput.svelte +39 -6
  268. package/dist/components/TextInput.svelte.d.ts +15 -7
  269. package/dist/components/basic/Checkbox.svelte +52 -14
  270. package/dist/components/basic/Checkbox.svelte.d.ts +11 -1
  271. package/package.json +11 -2
@@ -0,0 +1,513 @@
1
+ /**
2
+ * Artifact blocks (jatui `jatui/artifact-blocks`; origin MOS epic mos-ab*,
3
+ * moved into jatui by jatui-vsuzi so MOS and the jat IDE render ONE thing).
4
+ *
5
+ * A BLOCKS artifact is DATA, not code: a title plus an ordered list of block
6
+ * instances, each `{ id, type, params }`. The host renders every block with
7
+ * its own Svelte component (jatui, theme tokens, a11y), so an agent never
8
+ * hand-builds a chart, table or media picker in raw HTML again.
9
+ *
10
+ * Adding a block = one folder `blocks/<type>/` whose `block.ts`
11
+ * default-exports an `ArtifactBlockDef`, plus one line in `builtins.ts`
12
+ * (a library cannot discover folders at runtime the way a Vite app can).
13
+ * Hosts may add their own blocks with `registerBlocks()`.
14
+ *
15
+ * Everything that used to be a host import (comments API, composer,
16
+ * uploads, the review send, desk actions, listen, maps, 3D, sandbox…) goes
17
+ * through ONE typed object, the `HostAdapter` below. Contract: ./CONTRACT.md.
18
+ */
19
+ import type { Component, Snippet } from "svelte";
20
+ import type { z } from "zod";
21
+ import type { HistorySnapshot, HistoryVersion } from "./history.js";
22
+ /** Per-viewer state a block may persist (verdicts, notes, picks). JSON only. */
23
+ export type BlockState = Record<string, unknown>;
24
+ export interface BlockContext {
25
+ artifactId: string;
26
+ /** The artifact version being viewed; state is keyed per version. */
27
+ version: number;
28
+ blockId: string;
29
+ /** This viewer's saved state for THIS block (null = none yet). */
30
+ state: BlockState | null;
31
+ /**
32
+ * Persist this viewer's state for this block (debounced by the renderer;
33
+ * resolves when saved). Undefined when the viewer cannot save (anonymous
34
+ * share link, print/preview, tests).
35
+ */
36
+ saveState?: (next: BlockState) => Promise<void>;
37
+ /** Live data published for the artifact; {} when none. */
38
+ data: Record<string, unknown>;
39
+ /** True on a read-only surface — blocks must not show viewer chrome. */
40
+ readonly: boolean;
41
+ /**
42
+ * The section's own controls: the per-block comment pill, when the host
43
+ * has comments on. A block whose def says `hostsTools` renders them
44
+ * through <SectionTools> on its heading row; undefined = nothing to render.
45
+ */
46
+ tools?: Snippet;
47
+ /**
48
+ * Optional host services (maps loader, 3D explorer, sandboxed mockup
49
+ * frame, team lookup…) — `HostAdapter.services`. Always an object; a block
50
+ * whose service is missing degrades to a visible, quiet fallback.
51
+ */
52
+ services: BlockServices;
53
+ }
54
+ export interface BlockProps<P> {
55
+ params: P;
56
+ ctx: BlockContext;
57
+ }
58
+ /** A word in one block's verdict vocabulary (matches jatui ReviewProgress). */
59
+ export interface VerdictWord {
60
+ id: string;
61
+ label: string;
62
+ tone: "success" | "warning" | "error" | "info";
63
+ }
64
+ /** An item verdict, normalized across the item-review vocabularies. */
65
+ export type ItemVerdict = "approved" | "needs-work" | "rejected";
66
+ /** One item inside an item-review block, with this viewer's verdict on it. */
67
+ export interface ReviewItem {
68
+ id: string;
69
+ /** null = undecided (no verdict, untested, or awaiting a retest). */
70
+ verdict: ItemVerdict | null;
71
+ /** The block's own word for it (approve / redo / modify / pass / fail…). */
72
+ raw: string | null;
73
+ note?: string;
74
+ /** The note's attachments, read straight from the saved entry. */
75
+ attachments?: NoteAttachment[];
76
+ /** The viewer saved a verdict on this item (vs. an authored seed or a
77
+ * verdict from an earlier round, which answers nothing now). */
78
+ explicit: boolean;
79
+ /** The team reopened the item and this viewer owes the new round. */
80
+ retest: boolean;
81
+ }
82
+ /**
83
+ * Item-review hooks (jatui-vsuzi): blocks whose verdicts live PER ITEM
84
+ * inside their own state (checklist, media-picker, diff-review) declare
85
+ * this, and the core census, still-open walk and Send read their items
86
+ * through it — the core never hardcodes a block type. Params here are the
87
+ * AUTHORED params (untrusted JSON), not the parsed ones: the census runs on
88
+ * stored specs, server-side too.
89
+ */
90
+ export interface BlockItemReview {
91
+ /** The block's own verdict words (ids = ReviewItem.raw values). */
92
+ vocabulary: VerdictWord[];
93
+ /** A name for the block kind when params carry no title ("Checklist"). */
94
+ name: string;
95
+ /** The items and this state's verdict on each, in the block's order. */
96
+ items(params: unknown, state: unknown): ReviewItem[];
97
+ /** An item's title for a jump card; the item id when absent. */
98
+ itemLabel?(params: unknown, itemId: string): string;
99
+ /** Best-effort thumbnail URL for a jump card. */
100
+ itemThumb?(params: unknown, itemId: string): string | undefined;
101
+ }
102
+ export interface ArtifactBlockDef<P = unknown> {
103
+ /** Stable kebab-case id, equals the folder name: "chart", "media-picker". */
104
+ type: string;
105
+ /** Human label for the catalog. */
106
+ title: string;
107
+ /**
108
+ * One paragraph an AGENT reads to decide when to use this block and how to
109
+ * fill it (the catalog a host serves to agents).
110
+ */
111
+ description: string;
112
+ /** Validates params at publish; also the source of the catalog JSON Schema. */
113
+ schema: z.ZodType<P>;
114
+ component: Component<BlockProps<P>>;
115
+ /** A complete, valid params example (used in docs, catalog and tests). */
116
+ example: P;
117
+ /** True when the block saves per-viewer state (verdicts, picks, notes). */
118
+ interactive?: boolean;
119
+ /**
120
+ * Optional: `params.dataKey`-style binding. When set, the renderer passes
121
+ * `ctx.data[params[dataParam]]` so live data replaces inline params.
122
+ */
123
+ dataParam?: string;
124
+ /**
125
+ * Optional: true when these params make the block BREAK OUT of the reading
126
+ * column (a wide table). The renderer gives the per-block comment trigger
127
+ * the same breakout. Must agree with what the component itself renders.
128
+ */
129
+ wide?: (params: P) => boolean;
130
+ /**
131
+ * Optional: true when, for these params, the component renders
132
+ * <SectionTools ctx={ctx} /> on its heading row, so the section's Listen +
133
+ * comment controls sit beside the heading. The renderer then draws no
134
+ * controls row of its own above the block.
135
+ */
136
+ hostsTools?: (params: P) => boolean;
137
+ /** Item-review blocks only — see BlockItemReview. */
138
+ itemReview?: BlockItemReview;
139
+ /**
140
+ * Block types that present a WORK PRODUCT to judge (mockup, compare,
141
+ * collage, diff) set this: they take the block-level approve /
142
+ * needs-a-pass strip unless the spec says `params.reviewable: false`.
143
+ * Every other block is information (no strip, not a review unit) unless
144
+ * the spec opts in with `params.reviewable: true`.
145
+ */
146
+ reviewableByDefault?: boolean;
147
+ }
148
+ /**
149
+ * A group a card belongs to (PARAMS-SPEC §1/§5, jat-j49id): the renderer
150
+ * draws a header BETWEEN cards when the key changes, anchored
151
+ * `#group-<key>`; a `quiet` group may start collapsed.
152
+ */
153
+ export interface BlockGroup {
154
+ /** `[a-z0-9-]{1,32}` — question | decision | hold-human | … */
155
+ key: string;
156
+ /** ≤60, the header text ("Agent asked a question"). */
157
+ label: string;
158
+ quiet?: boolean;
159
+ }
160
+ export interface BlockInstance {
161
+ /** Unique within the artifact; stable across re-publishes (state keys on it). */
162
+ id: string;
163
+ type: string;
164
+ params: unknown;
165
+ /**
166
+ * Optional per-block OWNER — the agent (or role) that should hear about
167
+ * viewer decisions on this block. Never rendered; the host's owner-routing
168
+ * reads it SERVER-SIDE and the client never names it. Max 80 chars.
169
+ */
170
+ owner?: string;
171
+ /**
172
+ * Optional per-block jat task link (provider contract P11): a finished
173
+ * review answers THIS block's verdict on this task, as the viewer.
174
+ */
175
+ taskId?: string;
176
+ /**
177
+ * Optional, decision blocks with a `taskId` only: the jat-decision the
178
+ * card mirrors (`dec-…`). A `chose` on the card also answers it.
179
+ */
180
+ decisionId?: string;
181
+ }
182
+ export interface BlocksSpec {
183
+ version: 1;
184
+ title: string;
185
+ summary?: string;
186
+ blocks: BlockInstance[];
187
+ }
188
+ export interface BlockValidationError {
189
+ blockId: string;
190
+ type: string;
191
+ /** Dotted path into params, e.g. "series.0.points". */
192
+ path: string;
193
+ message: string;
194
+ }
195
+ export type AttachmentKind = "screen" | "voice" | "audio" | "video" | "image" | "file";
196
+ /**
197
+ * The descriptor one note attachment carries (stored by the HOST, never
198
+ * bytes here). Shape-compatible with MOS's noteAttachments.ts; jatui only
199
+ * displays it and passes it through.
200
+ */
201
+ export interface NoteAttachment {
202
+ /** Stored object name in the host's asset store. */
203
+ name: string;
204
+ /** Original filename for a picked file; the stored name for a recording. */
205
+ label?: string;
206
+ /** URL serving the bytes behind the host's access check. */
207
+ url: string;
208
+ contentType: string;
209
+ sizeBytes: number;
210
+ kind: AttachmentKind;
211
+ durationSeconds: number | null;
212
+ /** Best-effort LOCAL transcription of a recording — never cloud. */
213
+ transcript: string | null;
214
+ }
215
+ /**
216
+ * The host's upload leg: stores the bytes FIRST (never lose the blob) and
217
+ * returns the descriptor the note keeps.
218
+ */
219
+ export type ComposerUpload = (blob: Blob | File, lane: "file" | "clip", durationSeconds?: number) => Promise<NoteAttachment>;
220
+ /**
221
+ * The props every note composer takes — jatui's default text composer and
222
+ * any host composer (MOS's ReviewComposer is this shape). Either the
223
+ * composer renders its own submit row (`submitLabel` + `onSubmit`) or the
224
+ * host drives the send through `bind:text` / `bind:clips`.
225
+ */
226
+ export interface NoteComposerProps {
227
+ /** The surface's upload leg. Omitted → text-only (no attach affordances). */
228
+ upload?: ComposerUpload;
229
+ placeholder?: string;
230
+ label?: string;
231
+ maxLength?: number;
232
+ rows?: number;
233
+ submitLabel?: string;
234
+ onSubmit?: (payload: {
235
+ text: string;
236
+ clips: NoteAttachment[];
237
+ }) => void | Promise<void>;
238
+ busy?: boolean;
239
+ disabled?: boolean;
240
+ error?: string | null;
241
+ onInput?: (text: string) => void;
242
+ onBlur?: () => void;
243
+ clips?: NoteAttachment[];
244
+ onClipsChange?: (clips: NoteAttachment[]) => void;
245
+ maxClips?: number;
246
+ autofocus?: boolean;
247
+ text?: string;
248
+ class?: string;
249
+ }
250
+ export type ReviewVerdict = "approved" | "needs-pass" | "chose";
251
+ export interface VerdictEntry {
252
+ verdict: ReviewVerdict;
253
+ /** `chose` only: the letter picked. */
254
+ option?: string;
255
+ note?: string;
256
+ attachments?: NoteAttachment[];
257
+ }
258
+ /** The block-level verdict a viewer saves on an ordinary block. */
259
+ export interface BlockReviewState {
260
+ verdict?: "approved" | "needs-pass";
261
+ note?: string;
262
+ attachments?: NoteAttachment[];
263
+ }
264
+ /**
265
+ * The per-item verdicts map a review's answer carries for item-review
266
+ * blocks: `{ blockId: { itemId: { verdict, note?, attachments? } } }`.
267
+ */
268
+ export type SentItemsMap = Record<string, Record<string, {
269
+ verdict: string;
270
+ note?: string;
271
+ attachments?: NoteAttachment[];
272
+ }>>;
273
+ /**
274
+ * What the host hands the view about THIS viewer's last Send on this
275
+ * version. The view seeds its done state from it, so a reload remembers.
276
+ */
277
+ export interface SentAnswer {
278
+ /** ISO timestamp of the Send. */
279
+ sentAt: string;
280
+ /** The Send's event id (the delivery poll's key). */
281
+ eventId?: string;
282
+ /** When the owner got it; null = queued. */
283
+ deliveredAt?: string | null;
284
+ /** False when nobody owns the page, so nothing will ever deliver it. */
285
+ deliverable?: boolean;
286
+ /** Who the answer reached (the publisher's label). */
287
+ sentTo: string | null;
288
+ verdicts?: Record<string, VerdictEntry>;
289
+ items?: SentItemsMap;
290
+ }
291
+ /** One folded earlier round (a page that superseded older rounds). */
292
+ export interface FoldedRound {
293
+ slug: string;
294
+ title: string;
295
+ version: number;
296
+ publishedBy: string;
297
+ /** ISO timestamp. */
298
+ publishedAt: string;
299
+ reason?: string | null;
300
+ /** Every viewer's locked verdicts/notes (jatui RoundHistory entries). */
301
+ entries: import("../components/review/reviewSummary").ReviewRound[];
302
+ }
303
+ /** One comment in a block's thread. */
304
+ export interface BlockComment {
305
+ id: string;
306
+ body: string;
307
+ resolved: boolean;
308
+ /** ISO timestamp. */
309
+ created_at: string;
310
+ /** True when THIS viewer posted it (the host stamps it). */
311
+ mine?: boolean;
312
+ attachments?: NoteAttachment[] | null;
313
+ }
314
+ /** Per-block comment threads. Every call may throw; the drawer says so. */
315
+ export interface CommentsService {
316
+ load(args: {
317
+ artifactId: string;
318
+ version: number;
319
+ blockId: string;
320
+ }): Promise<BlockComment[]>;
321
+ /** Resolves with the stored comment. Throw an Error with a human message. */
322
+ post(args: {
323
+ artifactId: string;
324
+ version: number;
325
+ blockId: string;
326
+ body: string;
327
+ attachments: NoteAttachment[];
328
+ }): Promise<BlockComment>;
329
+ /** Flip the poster's OWN resolved flag. */
330
+ setResolved(args: {
331
+ artifactId: string;
332
+ commentId: string;
333
+ resolved: boolean;
334
+ }): Promise<void>;
335
+ }
336
+ /** What a Send answered. */
337
+ export interface ReviewSendResult {
338
+ answered: boolean;
339
+ sentTo?: string | null;
340
+ delivery?: {
341
+ eventId?: string | null;
342
+ delivered?: boolean;
343
+ deliverable?: boolean;
344
+ };
345
+ error?: string;
346
+ }
347
+ /** The review moment's network legs. */
348
+ export interface ReviewService {
349
+ /**
350
+ * Finish review: ONE answer to the linked task. `version` is the layout
351
+ * version THIS tab answered — a stale tab answering an older version must
352
+ * be detectable (the host stores verdicts per version). `taskId` is the
353
+ * page's linked task; `blockTasks` maps each block that carries its own
354
+ * task link (provider contract P11) to `{ taskId, decisionId }`, so the
355
+ * host answers each linked block on its own task.
356
+ */
357
+ send(args: {
358
+ artifactId: string;
359
+ version: number;
360
+ taskId: string | null;
361
+ blockTasks: Record<string, {
362
+ taskId: string;
363
+ decisionId: string | null;
364
+ }>;
365
+ verdicts: Record<string, VerdictEntry>;
366
+ text?: string;
367
+ attachments?: NoteAttachment[];
368
+ }): Promise<ReviewSendResult>;
369
+ /**
370
+ * "Done reviewing" (no linked task): record that this viewer finished
371
+ * this version. Throw an Error with a human message on failure — the view
372
+ * shows it beside the control. Omit → no Done-reviewing control and no
373
+ * auto-send; a page whose picks then go nowhere says so.
374
+ */
375
+ markReviewed?(args: {
376
+ artifactId: string;
377
+ version: number;
378
+ taskId: string | null;
379
+ }): Promise<void>;
380
+ /**
381
+ * Poll a queued Send's delivery stamp. Omit → every Send reads as
382
+ * delivered the moment `send` resolves (nothing would ever stop a
383
+ * "Sending…" state otherwise).
384
+ */
385
+ deliveryStatus?(args: {
386
+ artifactId: string;
387
+ eventId: string;
388
+ }): Promise<{
389
+ delivered: boolean;
390
+ deliveredAt?: string | null;
391
+ }>;
392
+ /**
393
+ * A drafted note the host keeps in the viewer's state (MOS: the desk's
394
+ * `desk:note`). The Finish composer pre-fills from it; `label` names
395
+ * where it came from ("Drafted on your desk: Needs work").
396
+ */
397
+ draftNote?(blocks: Record<string, unknown>): {
398
+ note: string;
399
+ label: string;
400
+ } | null;
401
+ }
402
+ /** The page as it was at one instant. */
403
+ export interface HistoryPastState {
404
+ at: string;
405
+ version: number;
406
+ kind: "html" | "blocks";
407
+ spec: BlocksSpec | null;
408
+ data: Record<string, unknown>;
409
+ snapshotId: string | null;
410
+ dataAt: string | null;
411
+ beforeTrail: boolean;
412
+ }
413
+ /** The history scrubber's two reads. Omit → no History control. */
414
+ export interface HistoryService {
415
+ timeline(args: {
416
+ artifactId: string;
417
+ }): Promise<{
418
+ versions: HistoryVersion[];
419
+ snapshots: HistorySnapshot[];
420
+ trailStart?: string | null;
421
+ }>;
422
+ at(args: {
423
+ artifactId: string;
424
+ at: string;
425
+ }): Promise<HistoryPastState>;
426
+ }
427
+ /**
428
+ * Live data refresh. Omit → the page shows the data it was given, with no
429
+ * "live" claim. A host that is rate limited throws an object with
430
+ * `status: 429` (e.g. `Object.assign(new Error("slow down"), { status: 429 })`):
431
+ * the page keeps the last good data and its freshness line says a refresh
432
+ * is pending; any other throw reads as a failed refresh.
433
+ */
434
+ export interface LiveDataService {
435
+ fetch(args: {
436
+ artifactId: string;
437
+ }): Promise<{
438
+ data: Record<string, unknown>;
439
+ dataUpdatedAt: string | null;
440
+ }>;
441
+ /** Poll cadence; default 30s. */
442
+ intervalMs?: number;
443
+ }
444
+ /** What a block's Listen control reads (its own section). */
445
+ export interface BlockListenArgs {
446
+ /** The section id the segments are grouped under (`block-<id>`). */
447
+ group: string;
448
+ /** "What this page is" — completes "Listen to: <label>". */
449
+ label: string;
450
+ /** CSS selector of the section to highlight / follow. */
451
+ anchor: string;
452
+ }
453
+ /** The done states' "Back to desk / Next review" slot. */
454
+ export interface NextActionsArgs {
455
+ compact: boolean;
456
+ autofocus: boolean;
457
+ /** The full-size placement offers a Next key binding. */
458
+ nextKey: boolean;
459
+ }
460
+ /**
461
+ * Optional services a block may use. Every key is optional; block tasks
462
+ * refine the shapes they consume. A missing service is a visible, quiet
463
+ * fallback inside that block — never a throw.
464
+ */
465
+ export interface BlockServices {
466
+ /** Map block: load Google Maps (jatui's loadGoogleMapsAPI fits). */
467
+ loadGoogleMaps?: (opts: {
468
+ libraries?: string[];
469
+ }) => Promise<unknown>;
470
+ /** Explainer block: a 3D explorer component. */
471
+ explorer3d?: Component<Record<string, unknown>>;
472
+ /** Mockup block: the `sandbox` attribute for untrusted HTML frames. */
473
+ sandboxAttr?: string;
474
+ /** Team lookup for review chips (ids → display names). */
475
+ teamLookup?: (ids: string[]) => Promise<Record<string, string>>;
476
+ [key: string]: unknown;
477
+ }
478
+ /**
479
+ * ONE typed object the host passes to BlocksArtifactView (or BlockRenderer).
480
+ * Every key is optional and its absence DEGRADES TO READ-ONLY, LOUDLY: no
481
+ * `comments` → no comment pills; no `review.send` → no Finish review; no
482
+ * `review.markReviewed` → no Done reviewing and no auto-send. A page that
483
+ * carries answerable content but cannot send it shows a notice: "read-only"
484
+ * without `onSaveBlock` (a view prop — blocks then get no saveState),
485
+ * "unsent" when picks save but no review leg sends them.
486
+ */
487
+ export interface HostAdapter {
488
+ /** Note composer (verdict notes, comments, the Finish note). Default: jatui text composer. */
489
+ composer?: Component<NoteComposerProps>;
490
+ /** Upload leg factory, handed to the composer. Omit → text-only notes. */
491
+ upload?: (artifactId: string) => ComposerUpload;
492
+ /** Attachment chip renderer. Default: a labelled link chip. */
493
+ attachmentChip?: Component<{
494
+ clip: NoteAttachment;
495
+ }>;
496
+ comments?: CommentsService;
497
+ review?: ReviewService;
498
+ history?: HistoryService;
499
+ liveData?: LiveDataService;
500
+ /** A block's Listen control (jatui ListenControl fits). Omit → no Listen. */
501
+ listen?: Snippet<[BlockListenArgs]>;
502
+ /** Header crumb slot (team / "Artifacts" / "Your desk"). */
503
+ crumb?: Snippet;
504
+ /** "Back to desk / Next review" in the done states. */
505
+ nextActions?: Snippet<[NextActionsArgs]>;
506
+ /** Right-click menu on the title ("Copy reference for an agent"…). */
507
+ titleMenu?: {
508
+ header?: string;
509
+ items: import("../components/ContextMenu.types.js").ContextMenuItem[];
510
+ };
511
+ /** Optional block services (maps, 3D, sandbox, team). */
512
+ services?: BlockServices;
513
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -187,6 +187,14 @@
187
187
  {/if}
188
188
 
189
189
  <style>
190
+ /* ── Flat by default ──────────────────────────────────────────
191
+ DaisyUI v5 gives colored variants (primary, error, …) a drop shadow
192
+ through --btn-shadow. jatui buttons are flat. Only the variable is
193
+ cleared, so a consumer `shadow-*` utility still applies when wanted. */
194
+ .jatui-btn {
195
+ --btn-shadow: 0 0 0 0 transparent;
196
+ }
197
+
190
198
  /* ── Press Squish ─────────────────────────────────────────────
191
199
  Quick down on :active, spring back on release. Transform-only.
192
200
  Local @media guard — motion.css is the backstop but not guaranteed. */
@@ -7,8 +7,35 @@
7
7
  * opt-in floatingLabel prop (label translates/scales on focus-or-filled, pure CSS).
8
8
  */
9
9
 
10
- interface Props {
11
- label: string;
10
+ import type { HTMLInputAttributes } from 'svelte/elements';
11
+
12
+ /**
13
+ * Any other native attribute (aria-label, aria-labelledby, data-*, title,
14
+ * list, inputmode, step, min, max, event handlers…) passes straight through
15
+ * to the <input>. `label` is optional: a compact input with no visible label
16
+ * must pass `aria-label` (or `aria-labelledby`) to get an accessible name.
17
+ */
18
+ interface Props
19
+ extends Omit<
20
+ HTMLInputAttributes,
21
+ | 'value'
22
+ | 'type'
23
+ | 'size'
24
+ | 'class'
25
+ | 'id'
26
+ | 'name'
27
+ | 'autocomplete'
28
+ | 'placeholder'
29
+ | 'required'
30
+ | 'disabled'
31
+ | 'readonly'
32
+ | 'maxlength'
33
+ | 'minlength'
34
+ | 'pattern'
35
+ | 'children'
36
+ > {
37
+ /** Visible label. Omit it only with `aria-label` / `aria-labelledby`. */
38
+ label?: string;
12
39
  value?: string;
13
40
  placeholder?: string;
14
41
  type?: 'text' | 'email' | 'password' | 'number' | 'tel' | 'url';
@@ -54,7 +81,8 @@
54
81
  class: className = '',
55
82
  id = `text-input-${Math.random().toString(36).substr(2, 9)}`,
56
83
  name = '',
57
- autocomplete = ''
84
+ autocomplete = '',
85
+ ...rest
58
86
  }: Props = $props();
59
87
 
60
88
  const sizeClass = $derived({ sm: 'input-sm', md: '', lg: 'input-lg' }[size]);
@@ -97,7 +125,7 @@
97
125
  </script>
98
126
 
99
127
  <div class="form-control w-full" class:jatui-float-wrap={floatingLabel}>
100
- {#if !floatingLabel}
128
+ {#if label && !floatingLabel}
101
129
  <label for={id} class="label">
102
130
  <span class="text-[0.8125rem] font-medium text-base-content/85">
103
131
  {label}
@@ -110,6 +138,7 @@
110
138
 
111
139
  <div class:jatui-float-field={floatingLabel}>
112
140
  <input
141
+ {...rest}
113
142
  bind:this={inputEl}
114
143
  {id}
115
144
  {name}
@@ -124,12 +153,16 @@
124
153
  autocomplete={autocomplete as AutoFill}
125
154
  bind:value
126
155
  class={inputClass}
127
- aria-describedby={error ? `${id}-error` : helpText ? `${id}-help` : undefined}
156
+ aria-describedby={error
157
+ ? `${id}-error`
158
+ : helpText
159
+ ? `${id}-help`
160
+ : rest['aria-describedby']}
128
161
  aria-invalid={error ? 'true' : 'false'}
129
162
  onanimationend={() => inputEl?.classList.remove('jatui-input-shake')}
130
163
  />
131
164
 
132
- {#if floatingLabel}
165
+ {#if label && floatingLabel}
133
166
  <label for={id} class="jatui-float-label">
134
167
  {label}
135
168
  {#if required}
@@ -1,12 +1,20 @@
1
1
  /**
2
- * TextInput Component
3
- *
4
- * Labeled text input with validation, error state, help text, and character count.
5
- * Adds: motion-token error shake (embedded keyframe, no host-app dependency),
6
- * opt-in floatingLabel prop (label translates/scales on focus-or-filled, pure CSS).
2
+ * TextInput Component
3
+ *
4
+ * Labeled text input with validation, error state, help text, and character count.
5
+ * Adds: motion-token error shake (embedded keyframe, no host-app dependency),
6
+ * opt-in floatingLabel prop (label translates/scales on focus-or-filled, pure CSS).
7
+ */
8
+ import type { HTMLInputAttributes } from 'svelte/elements';
9
+ /**
10
+ * Any other native attribute (aria-label, aria-labelledby, data-*, title,
11
+ * list, inputmode, step, min, max, event handlers…) passes straight through
12
+ * to the <input>. `label` is optional: a compact input with no visible label
13
+ * must pass `aria-label` (or `aria-labelledby`) to get an accessible name.
7
14
  */
8
- interface Props {
9
- label: string;
15
+ interface Props extends Omit<HTMLInputAttributes, 'value' | 'type' | 'size' | 'class' | 'id' | 'name' | 'autocomplete' | 'placeholder' | 'required' | 'disabled' | 'readonly' | 'maxlength' | 'minlength' | 'pattern' | 'children'> {
16
+ /** Visible label. Omit it only with `aria-label` / `aria-labelledby`. */
17
+ label?: string;
10
18
  value?: string;
11
19
  placeholder?: string;
12
20
  type?: 'text' | 'email' | 'password' | 'number' | 'tel' | 'url';