@xemahq/ui-kernel 0.10.0 → 0.11.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 (377) hide show
  1. package/dist/lib/biome-host/agent-validation.d.ts.map +1 -1
  2. package/dist/lib/biome-host/agent-validation.js +26 -13
  3. package/dist/lib/biome-host/agent-validation.js.map +1 -1
  4. package/dist/lib/biome-host/biome-registry.d.ts.map +1 -1
  5. package/dist/lib/biome-host/biome-registry.js +27 -10
  6. package/dist/lib/biome-host/biome-registry.js.map +1 -1
  7. package/dist/lib/biome-host/biome-scope-hooks.d.ts.map +1 -1
  8. package/dist/lib/biome-host/biome-scope-hooks.js +2 -1
  9. package/dist/lib/biome-host/biome-scope-hooks.js.map +1 -1
  10. package/dist/lib/biome-host/biome-scoped-query.d.ts.map +1 -1
  11. package/dist/lib/biome-host/biome-scoped-query.js +5 -3
  12. package/dist/lib/biome-host/biome-scoped-query.js.map +1 -1
  13. package/dist/lib/biome-host/frontend-biome.d.ts +1 -1
  14. package/dist/lib/biome-host/frontend-biome.d.ts.map +1 -1
  15. package/dist/lib/biome-host/host-bridge.d.ts +1 -1
  16. package/dist/lib/biome-host/host-bridge.d.ts.map +1 -1
  17. package/dist/lib/biome-host/host-bridge.js.map +1 -1
  18. package/dist/lib/biome-host/i18n-hooks.d.ts.map +1 -1
  19. package/dist/lib/biome-host/i18n-hooks.js.map +1 -1
  20. package/dist/lib/biome-host/realtime-hooks.d.ts.map +1 -1
  21. package/dist/lib/biome-host/realtime-hooks.js.map +1 -1
  22. package/dist/lib/biome-host/session-contributions.d.ts +1 -1
  23. package/dist/lib/biome-host/session-contributions.d.ts.map +1 -1
  24. package/dist/lib/biome-host/use-mutation-with-error-toast.d.ts.map +1 -1
  25. package/dist/lib/biome-host/use-mutation-with-error-toast.js +3 -2
  26. package/dist/lib/biome-host/use-mutation-with-error-toast.js.map +1 -1
  27. package/dist/lib/biome-host/use-page-state.d.ts.map +1 -1
  28. package/dist/lib/biome-host/use-page-state.js +19 -10
  29. package/dist/lib/biome-host/use-page-state.js.map +1 -1
  30. package/dist/lib/capabilities/capability-provider.d.ts +1 -1
  31. package/dist/lib/capabilities/capability-provider.d.ts.map +1 -1
  32. package/dist/lib/capabilities/capability-provider.js +2 -2
  33. package/dist/lib/capabilities/capability-provider.js.map +1 -1
  34. package/dist/lib/capabilities/use-capability.d.ts +1 -1
  35. package/dist/lib/capabilities/use-capability.d.ts.map +1 -1
  36. package/dist/lib/capabilities/use-capability.js +2 -1
  37. package/dist/lib/capabilities/use-capability.js.map +1 -1
  38. package/dist/lib/contribution-registry/contribution-registry.d.ts.map +1 -1
  39. package/dist/lib/contribution-registry/contribution-registry.js +2 -1
  40. package/dist/lib/contribution-registry/contribution-registry.js.map +1 -1
  41. package/dist/lib/system-bus/deeplink.d.ts.map +1 -1
  42. package/dist/lib/system-bus/deeplink.js +4 -2
  43. package/dist/lib/system-bus/deeplink.js.map +1 -1
  44. package/dist/lib/system-bus/host-ports.d.ts +2 -2
  45. package/dist/lib/system-bus/host-ports.d.ts.map +1 -1
  46. package/dist/lib/system-bus/intent-registry.d.ts.map +1 -1
  47. package/dist/lib/system-bus/intent-registry.js +6 -3
  48. package/dist/lib/system-bus/intent-registry.js.map +1 -1
  49. package/dist/lib/system-bus/intents.d.ts +1 -1
  50. package/dist/lib/system-bus/intents.d.ts.map +1 -1
  51. package/dist/lib/system-bus/palette.d.ts +1 -1
  52. package/dist/lib/system-bus/palette.d.ts.map +1 -1
  53. package/dist/lib/system-bus/system-bus-builder.d.ts.map +1 -1
  54. package/dist/lib/system-bus/system-bus-builder.js +1 -1
  55. package/dist/lib/system-bus/system-bus-builder.js.map +1 -1
  56. package/dist/lib/system-bus/windows.d.ts +1 -1
  57. package/dist/lib/system-bus/windows.d.ts.map +1 -1
  58. package/dist/offline/outbox.d.ts +1 -0
  59. package/dist/offline/outbox.d.ts.map +1 -1
  60. package/dist/offline/outbox.js +4 -1
  61. package/dist/offline/outbox.js.map +1 -1
  62. package/dist/offline/react-hooks.d.ts +1 -1
  63. package/dist/offline/react-hooks.d.ts.map +1 -1
  64. package/dist/offline/react-hooks.js.map +1 -1
  65. package/dist/org-db/components/DbResultTable.d.ts.map +1 -1
  66. package/dist/org-db/components/DbResultTable.js +15 -6
  67. package/dist/org-db/components/DbResultTable.js.map +1 -1
  68. package/dist/registry/lib/agent-validation-host.d.ts.map +1 -1
  69. package/dist/registry/lib/agent-validation-host.js +1 -1
  70. package/dist/registry/lib/agent-validation-host.js.map +1 -1
  71. package/dist/registry/lib/biome-slot.d.ts.map +1 -1
  72. package/dist/registry/lib/biome-slot.js +5 -3
  73. package/dist/registry/lib/biome-slot.js.map +1 -1
  74. package/dist/registry/lib/primitives/SessionEventCard.d.ts.map +1 -1
  75. package/dist/registry/lib/primitives/SessionEventCard.js +14 -2
  76. package/dist/registry/lib/primitives/SessionEventCard.js.map +1 -1
  77. package/dist/registry/lib/primitives/SessionEventTimeline.d.ts.map +1 -1
  78. package/dist/registry/lib/primitives/SessionEventTimeline.js +6 -3
  79. package/dist/registry/lib/primitives/SessionEventTimeline.js.map +1 -1
  80. package/dist/registry/lib/primitives/SessionTabbedDrawer.d.ts.map +1 -1
  81. package/dist/registry/lib/primitives/SessionTabbedDrawer.js +10 -5
  82. package/dist/registry/lib/primitives/SessionTabbedDrawer.js.map +1 -1
  83. package/dist/registry/lib/session-context-provider.d.ts +1 -1
  84. package/dist/registry/lib/session-context-provider.d.ts.map +1 -1
  85. package/dist/registry/lib/session-context-provider.js.map +1 -1
  86. package/dist/registry/lib/session-selectors.d.ts.map +1 -1
  87. package/dist/registry/lib/session-selectors.js +35 -20
  88. package/dist/registry/lib/session-selectors.js.map +1 -1
  89. package/dist/session/comments/CommentRail.d.ts.map +1 -1
  90. package/dist/session/comments/CommentRail.js.map +1 -1
  91. package/dist/session/shell/SessionWorkspaceShell.d.ts.map +1 -1
  92. package/dist/session/shell/SessionWorkspaceShell.js.map +1 -1
  93. package/dist/session-kit/approvals/ApprovalCard.d.ts.map +1 -1
  94. package/dist/session-kit/approvals/ApprovalCard.js +6 -2
  95. package/dist/session-kit/approvals/ApprovalCard.js.map +1 -1
  96. package/dist/session-kit/approvals/ApprovalsCenter.d.ts.map +1 -1
  97. package/dist/session-kit/approvals/ApprovalsCenter.js +6 -3
  98. package/dist/session-kit/approvals/ApprovalsCenter.js.map +1 -1
  99. package/dist/session-kit/combobox/Combobox.d.ts.map +1 -1
  100. package/dist/session-kit/combobox/Combobox.js +20 -6
  101. package/dist/session-kit/combobox/Combobox.js.map +1 -1
  102. package/dist/session-kit/display/MD.d.ts.map +1 -1
  103. package/dist/session-kit/display/MD.js +7 -4
  104. package/dist/session-kit/display/MD.js.map +1 -1
  105. package/dist/ui/branding/app-branding-provider.d.ts.map +1 -1
  106. package/dist/ui/branding/app-branding-provider.js.map +1 -1
  107. package/dist/ui/branding/sanitize.d.ts.map +1 -1
  108. package/dist/ui/branding/sanitize.js +12 -6
  109. package/dist/ui/branding/sanitize.js.map +1 -1
  110. package/dist/ui/capture/document-preview.d.ts +1 -1
  111. package/dist/ui/capture/document-preview.d.ts.map +1 -1
  112. package/dist/ui/capture/document-preview.js +8 -6
  113. package/dist/ui/capture/document-preview.js.map +1 -1
  114. package/dist/ui/capture/field-spec-to-zod.d.ts.map +1 -1
  115. package/dist/ui/capture/field-spec-to-zod.js +45 -16
  116. package/dist/ui/capture/field-spec-to-zod.js.map +1 -1
  117. package/dist/ui/capture/field-spec-validate.d.ts.map +1 -1
  118. package/dist/ui/capture/field-spec-validate.js +79 -38
  119. package/dist/ui/capture/field-spec-validate.js.map +1 -1
  120. package/dist/ui/capture/field-spec.d.ts.map +1 -1
  121. package/dist/ui/capture/field-spec.js +17 -6
  122. package/dist/ui/capture/field-spec.js.map +1 -1
  123. package/dist/ui/capture/schema-field-input.d.ts.map +1 -1
  124. package/dist/ui/capture/schema-field-input.js +23 -18
  125. package/dist/ui/capture/schema-field-input.js.map +1 -1
  126. package/dist/ui/capture/schema-form.d.ts +1 -1
  127. package/dist/ui/capture/schema-form.d.ts.map +1 -1
  128. package/dist/ui/capture/schema-form.js +7 -6
  129. package/dist/ui/capture/schema-form.js.map +1 -1
  130. package/dist/ui/capture/use-prefill.d.ts.map +1 -1
  131. package/dist/ui/capture/use-prefill.js +32 -14
  132. package/dist/ui/capture/use-prefill.js.map +1 -1
  133. package/dist/ui/capture/use-schema-validation.d.ts +1 -1
  134. package/dist/ui/capture/use-schema-validation.d.ts.map +1 -1
  135. package/dist/ui/capture/use-schema-validation.js +13 -8
  136. package/dist/ui/capture/use-schema-validation.js.map +1 -1
  137. package/dist/ui/capture/use-wizard.d.ts.map +1 -1
  138. package/dist/ui/capture/use-wizard.js +23 -8
  139. package/dist/ui/capture/use-wizard.js.map +1 -1
  140. package/dist/ui/capture/value-format.d.ts.map +1 -1
  141. package/dist/ui/capture/value-format.js +6 -3
  142. package/dist/ui/capture/value-format.js.map +1 -1
  143. package/dist/ui/capture/wizard.d.ts.map +1 -1
  144. package/dist/ui/capture/wizard.js +3 -3
  145. package/dist/ui/capture/wizard.js.map +1 -1
  146. package/dist/ui/charts/bar-chart.d.ts +1 -1
  147. package/dist/ui/charts/bar-chart.d.ts.map +1 -1
  148. package/dist/ui/charts/bar-chart.js +1 -1
  149. package/dist/ui/charts/bar-chart.js.map +1 -1
  150. package/dist/ui/charts/chart-frame.d.ts +2 -2
  151. package/dist/ui/charts/chart-frame.d.ts.map +1 -1
  152. package/dist/ui/charts/chart-frame.js +4 -3
  153. package/dist/ui/charts/chart-frame.js.map +1 -1
  154. package/dist/ui/charts/chart-utils.d.ts.map +1 -1
  155. package/dist/ui/charts/chart-utils.js +32 -14
  156. package/dist/ui/charts/chart-utils.js.map +1 -1
  157. package/dist/ui/charts/donut-chart.d.ts +1 -1
  158. package/dist/ui/charts/donut-chart.d.ts.map +1 -1
  159. package/dist/ui/charts/donut-chart.js +7 -3
  160. package/dist/ui/charts/donut-chart.js.map +1 -1
  161. package/dist/ui/charts/line-chart.d.ts +1 -1
  162. package/dist/ui/charts/line-chart.d.ts.map +1 -1
  163. package/dist/ui/charts/line-chart.js +7 -4
  164. package/dist/ui/charts/line-chart.js.map +1 -1
  165. package/dist/ui/charts/sparkline.d.ts +1 -1
  166. package/dist/ui/charts/sparkline.d.ts.map +1 -1
  167. package/dist/ui/charts/sparkline.js +10 -6
  168. package/dist/ui/charts/sparkline.js.map +1 -1
  169. package/dist/ui/chrome/AsyncBoundary.d.ts +2 -2
  170. package/dist/ui/chrome/AsyncBoundary.d.ts.map +1 -1
  171. package/dist/ui/chrome/AsyncBoundary.js +3 -3
  172. package/dist/ui/chrome/AsyncBoundary.js.map +1 -1
  173. package/dist/ui/chrome/EmptyState.d.ts +19 -8
  174. package/dist/ui/chrome/EmptyState.d.ts.map +1 -1
  175. package/dist/ui/chrome/EmptyState.js +6 -4
  176. package/dist/ui/chrome/EmptyState.js.map +1 -1
  177. package/dist/ui/chrome/RecordCardList.d.ts +19 -0
  178. package/dist/ui/chrome/RecordCardList.d.ts.map +1 -0
  179. package/dist/ui/chrome/RecordCardList.js +12 -0
  180. package/dist/ui/chrome/RecordCardList.js.map +1 -0
  181. package/dist/ui/chrome/page-shell.d.ts.map +1 -1
  182. package/dist/ui/chrome/page-shell.js +9 -3
  183. package/dist/ui/chrome/page-shell.js.map +1 -1
  184. package/dist/ui/chrome/status-badge.d.ts.map +1 -1
  185. package/dist/ui/chrome/status-badge.js +1 -1
  186. package/dist/ui/chrome/status-badge.js.map +1 -1
  187. package/dist/ui/design-tokens.d.ts +4 -6
  188. package/dist/ui/design-tokens.d.ts.map +1 -1
  189. package/dist/ui/design-tokens.js +17 -11
  190. package/dist/ui/design-tokens.js.map +1 -1
  191. package/dist/ui/index.d.ts +1 -0
  192. package/dist/ui/index.d.ts.map +1 -1
  193. package/dist/ui/index.js +1 -0
  194. package/dist/ui/index.js.map +1 -1
  195. package/dist/ui/primitives/async-combobox.d.ts.map +1 -1
  196. package/dist/ui/primitives/async-combobox.js +4 -2
  197. package/dist/ui/primitives/async-combobox.js.map +1 -1
  198. package/dist/ui/primitives/badge.d.ts +2 -2
  199. package/dist/ui/primitives/badge.d.ts.map +1 -1
  200. package/dist/ui/primitives/badge.js +3 -3
  201. package/dist/ui/primitives/badge.js.map +1 -1
  202. package/dist/ui/primitives/button.d.ts +2 -2
  203. package/dist/ui/primitives/button.d.ts.map +1 -1
  204. package/dist/ui/primitives/button.js +5 -5
  205. package/dist/ui/primitives/button.js.map +1 -1
  206. package/dist/ui/primitives/overflow-tabs.d.ts.map +1 -1
  207. package/dist/ui/primitives/overflow-tabs.js +19 -12
  208. package/dist/ui/primitives/overflow-tabs.js.map +1 -1
  209. package/dist/ui/primitives/preview-device-frame.js +8 -4
  210. package/dist/ui/primitives/preview-device-frame.js.map +1 -1
  211. package/dist/ui/primitives/tag-multi-select.d.ts.map +1 -1
  212. package/dist/ui/primitives/tag-multi-select.js +10 -5
  213. package/dist/ui/primitives/tag-multi-select.js.map +1 -1
  214. package/dist/ui/primitives/url-preview-chrome.d.ts.map +1 -1
  215. package/dist/ui/primitives/url-preview-chrome.js.map +1 -1
  216. package/dist/vista/GenericCatalogueSurface.d.ts.map +1 -1
  217. package/dist/vista/GenericCatalogueSurface.js +5 -3
  218. package/dist/vista/GenericCatalogueSurface.js.map +1 -1
  219. package/dist/vista/VistaPanel.d.ts.map +1 -1
  220. package/dist/vista/VistaPanel.js +8 -4
  221. package/dist/vista/VistaPanel.js.map +1 -1
  222. package/dist/vista/html/CustomUiFrame.d.ts.map +1 -1
  223. package/dist/vista/html/CustomUiFrame.js +2 -1
  224. package/dist/vista/html/CustomUiFrame.js.map +1 -1
  225. package/dist/vista/html/custom-ui-frame-bridge.d.ts.map +1 -1
  226. package/dist/vista/html/custom-ui-frame-bridge.js +6 -3
  227. package/dist/vista/html/custom-ui-frame-bridge.js.map +1 -1
  228. package/dist/vista/html/custom-ui-intents.d.ts.map +1 -1
  229. package/dist/vista/html/custom-ui-intents.js +13 -15
  230. package/dist/vista/html/custom-ui-intents.js.map +1 -1
  231. package/dist/vista/surface-catalogue.d.ts.map +1 -1
  232. package/dist/vista/surface-catalogue.js +6 -3
  233. package/dist/vista/surface-catalogue.js.map +1 -1
  234. package/dist/vista/surfaces/FormSurface.d.ts.map +1 -1
  235. package/dist/vista/surfaces/FormSurface.js +20 -7
  236. package/dist/vista/surfaces/FormSurface.js.map +1 -1
  237. package/dist/vista/surfaces/TableSurface.d.ts.map +1 -1
  238. package/dist/vista/surfaces/TableSurface.js +2 -1
  239. package/dist/vista/surfaces/TableSurface.js.map +1 -1
  240. package/dist/vista/surfaces/blob-surfaces.d.ts.map +1 -1
  241. package/dist/vista/surfaces/blob-surfaces.js +7 -2
  242. package/dist/vista/surfaces/blob-surfaces.js.map +1 -1
  243. package/dist/vista/surfaces/elicitation-transport.d.ts.map +1 -1
  244. package/dist/vista/surfaces/elicitation-transport.js +14 -7
  245. package/dist/vista/surfaces/elicitation-transport.js.map +1 -1
  246. package/dist/vista/surfaces/file-surface-utils.d.ts.map +1 -1
  247. package/dist/vista/surfaces/file-surface-utils.js +8 -4
  248. package/dist/vista/surfaces/file-surface-utils.js.map +1 -1
  249. package/dist/vista/surfaces/register-surfaces.js +2 -1
  250. package/dist/vista/surfaces/register-surfaces.js.map +1 -1
  251. package/dist/vista/surfaces/text-surfaces.d.ts +1 -1
  252. package/dist/vista/surfaces/text-surfaces.d.ts.map +1 -1
  253. package/dist/vista/surfaces/text-surfaces.js +13 -7
  254. package/dist/vista/surfaces/text-surfaces.js.map +1 -1
  255. package/dist/vista/use-vista-tabs.d.ts.map +1 -1
  256. package/dist/vista/use-vista-tabs.js +8 -4
  257. package/dist/vista/use-vista-tabs.js.map +1 -1
  258. package/dist/vista/vista-code-renderer.d.ts.map +1 -1
  259. package/dist/vista/vista-code-renderer.js.map +1 -1
  260. package/dist/vista/vista-file-source.d.ts.map +1 -1
  261. package/dist/vista/vista-file-source.js +9 -5
  262. package/dist/vista/vista-file-source.js.map +1 -1
  263. package/dist/vista/vista-form-host.d.ts.map +1 -1
  264. package/dist/vista/vista-form-host.js +1 -1
  265. package/dist/vista/vista-form-host.js.map +1 -1
  266. package/dist/vista/vista-model.d.ts.map +1 -1
  267. package/dist/vista/vista-model.js +5 -3
  268. package/dist/vista/vista-model.js.map +1 -1
  269. package/dist/vista/vista-open-context.d.ts.map +1 -1
  270. package/dist/vista/vista-open-context.js +1 -1
  271. package/dist/vista/vista-open-context.js.map +1 -1
  272. package/dist/vista/vista-payloads.d.ts.map +1 -1
  273. package/dist/vista/vista-payloads.js +127 -63
  274. package/dist/vista/vista-payloads.js.map +1 -1
  275. package/dist/vista/vista-tabs-manifest.d.ts.map +1 -1
  276. package/dist/vista/vista-tabs-manifest.js +18 -9
  277. package/dist/vista/vista-tabs-manifest.js.map +1 -1
  278. package/dist/vista/vista-tools.d.ts.map +1 -1
  279. package/dist/vista/vista-tools.js +12 -6
  280. package/dist/vista/vista-tools.js.map +1 -1
  281. package/package.json +3 -3
  282. package/src/lib/biome-host/agent-validation.ts +37 -13
  283. package/src/lib/biome-host/biome-registry.ts +48 -13
  284. package/src/lib/biome-host/biome-scope-hooks.ts +3 -1
  285. package/src/lib/biome-host/biome-scoped-query.ts +7 -6
  286. package/src/lib/biome-host/frontend-biome.ts +1 -1
  287. package/src/lib/biome-host/host-bridge.ts +5 -4
  288. package/src/lib/biome-host/i18n-hooks.ts +1 -0
  289. package/src/lib/biome-host/realtime-hooks.ts +1 -0
  290. package/src/lib/biome-host/session-contributions.ts +1 -1
  291. package/src/lib/biome-host/use-mutation-with-error-toast.ts +4 -2
  292. package/src/lib/biome-host/use-page-state.ts +27 -10
  293. package/src/lib/capabilities/capability-provider.tsx +12 -5
  294. package/src/lib/capabilities/use-capability.ts +8 -4
  295. package/src/lib/contribution-registry/contribution-registry.ts +3 -1
  296. package/src/lib/system-bus/deeplink.ts +14 -4
  297. package/src/lib/system-bus/host-ports.ts +3 -7
  298. package/src/lib/system-bus/intent-registry.ts +12 -8
  299. package/src/lib/system-bus/intents.ts +6 -2
  300. package/src/lib/system-bus/palette.ts +2 -1
  301. package/src/lib/system-bus/system-bus-builder.ts +4 -2
  302. package/src/lib/system-bus/windows.ts +1 -1
  303. package/src/offline/outbox.test.ts +12 -3
  304. package/src/offline/outbox.ts +5 -1
  305. package/src/offline/react-hooks.ts +5 -2
  306. package/src/org-db/components/DbResultTable.tsx +48 -15
  307. package/src/registry/lib/agent-validation-host.ts +1 -2
  308. package/src/registry/lib/biome-slot.tsx +7 -4
  309. package/src/registry/lib/primitives/SessionEventCard.tsx +29 -5
  310. package/src/registry/lib/primitives/SessionEventTimeline.tsx +9 -3
  311. package/src/registry/lib/primitives/SessionTabbedDrawer.tsx +15 -5
  312. package/src/registry/lib/session-context-provider.tsx +1 -1
  313. package/src/registry/lib/session-selectors.ts +66 -27
  314. package/src/session/comments/CommentRail.tsx +2 -2
  315. package/src/session/shell/SessionWorkspaceShell.tsx +2 -2
  316. package/src/session-kit/approvals/ApprovalCard.tsx +7 -2
  317. package/src/session-kit/approvals/ApprovalsCenter.tsx +13 -4
  318. package/src/session-kit/combobox/Combobox.tsx +42 -11
  319. package/src/session-kit/display/MD.tsx +14 -5
  320. package/src/ui/branding/app-branding-provider.tsx +2 -3
  321. package/src/ui/branding/sanitize.ts +18 -6
  322. package/src/ui/capture/document-preview.tsx +84 -19
  323. package/src/ui/capture/field-spec-to-zod.ts +62 -14
  324. package/src/ui/capture/field-spec-validate.ts +132 -43
  325. package/src/ui/capture/field-spec.test.ts +2 -2
  326. package/src/ui/capture/field-spec.ts +41 -10
  327. package/src/ui/capture/schema-field-input.tsx +218 -38
  328. package/src/ui/capture/schema-form.tsx +54 -13
  329. package/src/ui/capture/use-prefill.ts +50 -17
  330. package/src/ui/capture/use-schema-validation.ts +45 -13
  331. package/src/ui/capture/use-wizard.ts +57 -11
  332. package/src/ui/capture/value-format.ts +14 -4
  333. package/src/ui/capture/wizard.tsx +9 -5
  334. package/src/ui/charts/bar-chart.tsx +8 -4
  335. package/src/ui/charts/chart-frame.tsx +18 -5
  336. package/src/ui/charts/chart-utils.ts +47 -15
  337. package/src/ui/charts/donut-chart.tsx +24 -6
  338. package/src/ui/charts/line-chart.tsx +34 -12
  339. package/src/ui/charts/sparkline.tsx +17 -9
  340. package/src/ui/chrome/AsyncBoundary.tsx +14 -6
  341. package/src/ui/chrome/EmptyState.tsx +116 -43
  342. package/src/ui/chrome/RecordCardList.tsx +98 -0
  343. package/src/ui/chrome/page-shell.tsx +32 -8
  344. package/src/ui/chrome/status-badge.tsx +8 -4
  345. package/src/ui/design-tokens.ts +39 -13
  346. package/src/ui/index.ts +5 -0
  347. package/src/ui/primitives/async-combobox.tsx +7 -3
  348. package/src/ui/primitives/badge.tsx +14 -5
  349. package/src/ui/primitives/button.tsx +13 -6
  350. package/src/ui/primitives/overflow-tabs.tsx +46 -16
  351. package/src/ui/primitives/preview-device-frame.tsx +12 -4
  352. package/src/ui/primitives/tag-multi-select.tsx +30 -9
  353. package/src/ui/primitives/url-preview-chrome.tsx +1 -0
  354. package/src/vista/GenericCatalogueSurface.tsx +7 -5
  355. package/src/vista/VistaPanel.tsx +12 -4
  356. package/src/vista/html/CustomUiFrame.spec.tsx +3 -1
  357. package/src/vista/html/CustomUiFrame.tsx +3 -1
  358. package/src/vista/html/custom-ui-frame-bridge.ts +9 -3
  359. package/src/vista/html/custom-ui-intents.spec.ts +3 -1
  360. package/src/vista/html/custom-ui-intents.ts +19 -15
  361. package/src/vista/surface-catalogue.ts +9 -3
  362. package/src/vista/surfaces/FormSurface.tsx +27 -10
  363. package/src/vista/surfaces/TableSurface.tsx +4 -3
  364. package/src/vista/surfaces/blob-surfaces.tsx +13 -3
  365. package/src/vista/surfaces/elicitation-transport.ts +21 -7
  366. package/src/vista/surfaces/file-surface-utils.ts +11 -4
  367. package/src/vista/surfaces/register-surfaces.tsx +3 -1
  368. package/src/vista/surfaces/text-surfaces.tsx +21 -8
  369. package/src/vista/use-vista-tabs.ts +12 -4
  370. package/src/vista/vista-code-renderer.tsx +6 -5
  371. package/src/vista/vista-file-source.tsx +15 -14
  372. package/src/vista/vista-form-host.tsx +3 -8
  373. package/src/vista/vista-model.ts +10 -3
  374. package/src/vista/vista-open-context.tsx +3 -8
  375. package/src/vista/vista-payloads.ts +186 -63
  376. package/src/vista/vista-tabs-manifest.ts +28 -13
  377. package/src/vista/vista-tools.ts +18 -6
@@ -33,28 +33,33 @@ import {
33
33
  } from '../../index';
34
34
 
35
35
  function sortByWeight<
36
- T extends { readonly id: string; readonly weight?: number; readonly order?: number },
36
+ T extends {
37
+ readonly id: string;
38
+ readonly weight?: number;
39
+ readonly order?: number;
40
+ },
37
41
  >(items: readonly T[]): readonly T[] {
38
42
  return [...items].sort((a, b) => {
39
43
  const aw = a.weight ?? a.order ?? 100;
40
44
  const bw = b.weight ?? b.order ?? 100;
41
- if (aw !== bw) return aw - bw;
45
+ if (aw !== bw) {
46
+ return aw - bw;
47
+ }
42
48
  return a.id.localeCompare(b.id);
43
49
  });
44
50
  }
45
51
 
46
- type PredicateOf<T> = T extends { readonly appliesTo?: (...args: infer A) => boolean }
52
+ type PredicateOf<T> = T extends {
53
+ readonly appliesTo?: (...args: infer A) => boolean;
54
+ }
47
55
  ? (...args: A) => boolean
48
56
  : never;
49
57
 
50
- function applies<T extends { readonly appliesTo?: (...args: never[]) => boolean }>(
51
- item: T,
52
- args: Parameters<PredicateOf<T>>,
53
- ): boolean {
58
+ function applies<
59
+ T extends { readonly appliesTo?: (...args: never[]) => boolean },
60
+ >(item: T, args: Parameters<PredicateOf<T>>): boolean {
54
61
  const predicate = item.appliesTo as PredicateOf<T> | undefined;
55
- return predicate === null || predicate === undefined
56
- ? true
57
- : predicate(...args);
62
+ return predicate === undefined ? true : predicate(...args);
58
63
  }
59
64
 
60
65
  // ── Slash commands ────────────────────────────────────────────────────
@@ -67,7 +72,9 @@ export function useSessionSlashCommands(
67
72
  const out: SlashCommandContribution[] = [];
68
73
  for (const biome of biomeRegistry.list()) {
69
74
  for (const cmd of biome.session?.slashCommands ?? []) {
70
- if (!applies(cmd, [session])) continue;
75
+ if (!applies(cmd, [session])) {
76
+ continue;
77
+ }
71
78
  out.push(cmd);
72
79
  }
73
80
  }
@@ -86,7 +93,9 @@ export function useSessionDrawerTabs(
86
93
  const out: SecondaryDrawerTabContribution[] = [];
87
94
  for (const biome of biomeRegistry.list()) {
88
95
  for (const tab of biome.session?.secondaryDrawerTabs ?? []) {
89
- if (!applies(tab, [session])) continue;
96
+ if (!applies(tab, [session])) {
97
+ continue;
98
+ }
90
99
  out.push(tab);
91
100
  }
92
101
  }
@@ -116,12 +125,18 @@ export function useActivityRenderer(
116
125
  const candidates: ActivityRendererContribution[] = [];
117
126
  for (const biome of biomeRegistry.list()) {
118
127
  for (const r of biome.session?.activityRenderers ?? []) {
119
- if (r.entryKind !== event.kind) continue;
120
- if (!applies(r, [{ session, event }])) continue;
128
+ if (r.entryKind !== event.kind) {
129
+ continue;
130
+ }
131
+ if (!applies(r, [{ session, event }])) {
132
+ continue;
133
+ }
121
134
  candidates.push(r);
122
135
  }
123
136
  }
124
- if (candidates.length === 0) return null;
137
+ if (candidates.length === 0) {
138
+ return null;
139
+ }
125
140
  return sortByWeight(candidates)[0] ?? null;
126
141
  // eslint-disable-next-line react-hooks/exhaustive-deps
127
142
  }, [revision, session, event]);
@@ -132,24 +147,38 @@ export function useActivityRenderer(
132
147
  type ToolMatch = 'exact' | 'glob' | 'none';
133
148
 
134
149
  function matchToolName(toolName: string, eventName: string): ToolMatch {
135
- if (toolName === eventName) return 'exact';
136
- if (toolName.endsWith('.*') && eventName.startsWith(toolName.slice(0, -1))) return 'glob';
150
+ if (toolName === eventName) {
151
+ return 'exact';
152
+ }
153
+ if (toolName.endsWith('.*') && eventName.startsWith(toolName.slice(0, -1))) {
154
+ return 'glob';
155
+ }
137
156
  return 'none';
138
157
  }
139
158
 
140
159
  function collectToolCallCandidates(
141
160
  session: SessionContext,
142
161
  event: SessionToolCallEvent,
143
- ): { exact: ToolCallRendererContribution[]; glob: ToolCallRendererContribution[] } {
162
+ ): {
163
+ exact: ToolCallRendererContribution[];
164
+ glob: ToolCallRendererContribution[];
165
+ } {
144
166
  const exact: ToolCallRendererContribution[] = [];
145
167
  const glob: ToolCallRendererContribution[] = [];
146
168
  for (const biome of biomeRegistry.list()) {
147
169
  for (const r of biome.session?.toolCallRenderers ?? []) {
148
170
  const match = matchToolName(r.toolName, event.name);
149
- if (match === 'none') continue;
150
- if (!applies(r, [{ session, event }])) continue;
151
- if (match === 'exact') exact.push(r);
152
- else glob.push(r);
171
+ if (match === 'none') {
172
+ continue;
173
+ }
174
+ if (!applies(r, [{ session, event }])) {
175
+ continue;
176
+ }
177
+ if (match === 'exact') {
178
+ exact.push(r);
179
+ } else {
180
+ glob.push(r);
181
+ }
153
182
  }
154
183
  }
155
184
  return { exact, glob };
@@ -168,8 +197,12 @@ export function useToolCallRenderer(
168
197
  const revision = useBiomeRegistryRevision();
169
198
  return useMemo(() => {
170
199
  const { exact, glob } = collectToolCallCandidates(session, event);
171
- if (exact.length > 0) return sortByWeight(exact)[0] ?? null;
172
- if (glob.length > 0) return sortByWeight(glob)[0] ?? null;
200
+ if (exact.length > 0) {
201
+ return sortByWeight(exact)[0] ?? null;
202
+ }
203
+ if (glob.length > 0) {
204
+ return sortByWeight(glob)[0] ?? null;
205
+ }
173
206
  return null;
174
207
  // eslint-disable-next-line react-hooks/exhaustive-deps
175
208
  }, [revision, session, event]);
@@ -185,7 +218,9 @@ export function useSessionMutationBars(
185
218
  const out: MutationBarContribution[] = [];
186
219
  for (const biome of biomeRegistry.list()) {
187
220
  for (const bar of biome.session?.mutationBars ?? []) {
188
- if (!applies(bar, [session])) continue;
221
+ if (!applies(bar, [session])) {
222
+ continue;
223
+ }
189
224
  out.push(bar);
190
225
  }
191
226
  }
@@ -204,7 +239,9 @@ export function useSessionHeaderChips(
204
239
  const out: HeaderChipContribution[] = [];
205
240
  for (const biome of biomeRegistry.list()) {
206
241
  for (const chip of biome.session?.headerChips ?? []) {
207
- if (!applies(chip, [session])) continue;
242
+ if (!applies(chip, [session])) {
243
+ continue;
244
+ }
208
245
  out.push(chip);
209
246
  }
210
247
  }
@@ -223,7 +260,9 @@ export function useSessionAttachmentClasses(
223
260
  const out: AttachmentClassContribution[] = [];
224
261
  for (const biome of biomeRegistry.list()) {
225
262
  for (const cls of biome.session?.attachmentClasses ?? []) {
226
- if (!applies(cls, [session])) continue;
263
+ if (!applies(cls, [session])) {
264
+ continue;
265
+ }
227
266
  out.push(cls);
228
267
  }
229
268
  }
@@ -1,7 +1,7 @@
1
- import type { ReactNode } from 'react';
2
-
3
1
  import { cn } from '../lib/cn';
4
2
 
3
+ import type { ReactNode } from 'react';
4
+
5
5
  /**
6
6
  * Generic, data-layer-agnostic comment shape. Host surfaces map their
7
7
  * own DTOs (KB `DocumentCommentResponseDto`, workflow `InquiryReply`,
@@ -1,7 +1,7 @@
1
- import type { CSSProperties, ReactNode, MouseEvent, RefObject } from 'react';
2
-
3
1
  import { cn } from '../lib/cn';
4
2
 
3
+ import type { CSSProperties, ReactNode, MouseEvent, RefObject } from 'react';
4
+
5
5
  interface SessionWorkspaceShellProps {
6
6
  /**
7
7
  * Container ref from `useHorizontalSplit`. The shell forwards mouse
@@ -68,7 +68,9 @@ export function ApprovalCard({
68
68
  const approveLabel = resolveApproveLabel(request, quorum, explicit);
69
69
 
70
70
  function resolve(d: ApprovalDecision): void {
71
- if (decision === undefined) setLocalDecision(d);
71
+ if (decision === undefined) {
72
+ setLocalDecision(d);
73
+ }
72
74
  onResolve(d, request);
73
75
  }
74
76
 
@@ -209,7 +211,10 @@ export function ApprovalCard({
209
211
 
210
212
  {/* SCOPED biome body */}
211
213
  <div
212
- style={{ padding: '10px 14px', background: 'hsl(var(--paper) / 0.5)' }}
214
+ style={{
215
+ padding: '10px 14px',
216
+ background: 'hsl(var(--paper) / 0.5)',
217
+ }}
213
218
  >
214
219
  <div
215
220
  style={{
@@ -52,8 +52,11 @@ export function ApprovalsCenter({
52
52
  const toggle = useCallback((id: string) => {
53
53
  setSelected((prev) => {
54
54
  const next = new Set(prev);
55
- if (next.has(id)) next.delete(id);
56
- else next.add(id);
55
+ if (next.has(id)) {
56
+ next.delete(id);
57
+ } else {
58
+ next.add(id);
59
+ }
57
60
  return next;
58
61
  });
59
62
  }, []);
@@ -71,7 +74,9 @@ export function ApprovalsCenter({
71
74
  const approveSelected = useCallback(() => {
72
75
  for (const id of selected) {
73
76
  const it = items.find((x) => x.id === id);
74
- if (it) onResolve(ApprovalDecision.Approved, it);
77
+ if (it) {
78
+ onResolve(ApprovalDecision.Approved, it);
79
+ }
75
80
  }
76
81
  setSelected(new Set());
77
82
  }, [selected, items, onResolve]);
@@ -302,7 +307,11 @@ function ApprovalRow({
302
307
  }}
303
308
  >
304
309
  {onOpen && (
305
- <ApprovalButton variant="ghost" size="xs" onClick={() => onOpen(item)}>
310
+ <ApprovalButton
311
+ variant="ghost"
312
+ size="xs"
313
+ onClick={() => onOpen(item)}
314
+ >
306
315
  Open session
307
316
  </ApprovalButton>
308
317
  )}
@@ -108,7 +108,9 @@ const POP_STYLE: CSSProperties = {
108
108
  overflow: 'hidden',
109
109
  };
110
110
 
111
- export function Combobox<V extends string>(props: ComboboxProps<V>): ReactElement {
111
+ export function Combobox<V extends string>(
112
+ props: ComboboxProps<V>,
113
+ ): ReactElement {
112
114
  const {
113
115
  items,
114
116
  trigger,
@@ -134,12 +136,16 @@ export function Combobox<V extends string>(props: ComboboxProps<V>): ReactElemen
134
136
  // Move focus to the search field when the dropdown opens (replaces the
135
137
  // a11y-discouraged `autoFocus` attribute).
136
138
  useEffect(() => {
137
- if (open && showSearch) searchRef.current?.focus();
139
+ if (open && showSearch) {
140
+ searchRef.current?.focus();
141
+ }
138
142
  }, [open, showSearch]);
139
143
 
140
144
  const filtered = query
141
145
  ? items.filter((it) =>
142
- `${it.label} ${it.hint ?? ''}`.toLowerCase().includes(query.toLowerCase()),
146
+ `${it.label} ${it.hint ?? ''}`
147
+ .toLowerCase()
148
+ .includes(query.toLowerCase()),
143
149
  )
144
150
  : items;
145
151
 
@@ -181,7 +187,9 @@ export function Combobox<V extends string>(props: ComboboxProps<V>): ReactElemen
181
187
  }}
182
188
  >
183
189
  {icons?.search && (
184
- <span style={{ display: 'inline-flex', color: 'hsl(var(--ink-3))' }}>
190
+ <span
191
+ style={{ display: 'inline-flex', color: 'hsl(var(--ink-3))' }}
192
+ >
185
193
  {icons.search}
186
194
  </span>
187
195
  )}
@@ -200,7 +208,10 @@ export function Combobox<V extends string>(props: ComboboxProps<V>): ReactElemen
200
208
  }}
201
209
  />
202
210
  {items.length > 0 && (
203
- <span className="mono" style={{ fontSize: 10, color: 'hsl(var(--ink-4))' }}>
211
+ <span
212
+ className="mono"
213
+ style={{ fontSize: 10, color: 'hsl(var(--ink-4))' }}
214
+ >
204
215
  {filtered.length}/{items.length}
205
216
  </span>
206
217
  )}
@@ -223,12 +234,15 @@ export function Combobox<V extends string>(props: ComboboxProps<V>): ReactElemen
223
234
  padding: '7px 9px',
224
235
  borderRadius: 7,
225
236
  textAlign: 'left',
226
- background: singleSelected ? 'hsl(var(--accent) / 0.6)' : 'transparent',
237
+ background: singleSelected
238
+ ? 'hsl(var(--accent) / 0.6)'
239
+ : 'transparent',
227
240
  transition: 'background 140ms ease',
228
241
  }}
229
242
  onMouseEnter={(e) => {
230
243
  if (!singleSelected) {
231
- e.currentTarget.style.background = 'hsl(var(--paper-sunk))';
244
+ e.currentTarget.style.background =
245
+ 'hsl(var(--paper-sunk))';
232
246
  }
233
247
  }}
234
248
  onMouseLeave={(e) => {
@@ -238,7 +252,13 @@ export function Combobox<V extends string>(props: ComboboxProps<V>): ReactElemen
238
252
  }}
239
253
  >
240
254
  {it.icon && (
241
- <span style={{ display: 'inline-flex', color: 'hsl(var(--ink-3))', flexShrink: 0 }}>
255
+ <span
256
+ style={{
257
+ display: 'inline-flex',
258
+ color: 'hsl(var(--ink-3))',
259
+ flexShrink: 0,
260
+ }}
261
+ >
242
262
  {it.icon}
243
263
  </span>
244
264
  )}
@@ -272,7 +292,10 @@ export function Combobox<V extends string>(props: ComboboxProps<V>): ReactElemen
272
292
  )}
273
293
  </span>
274
294
  {it.kind && (
275
- <span className="cap" style={{ fontSize: 8.5, flexShrink: 0 }}>
295
+ <span
296
+ className="cap"
297
+ style={{ fontSize: 8.5, flexShrink: 0 }}
298
+ >
276
299
  {it.kind}
277
300
  </span>
278
301
  )}
@@ -294,7 +317,13 @@ export function Combobox<V extends string>(props: ComboboxProps<V>): ReactElemen
294
317
  </span>
295
318
  ) : (
296
319
  on && (
297
- <span style={{ display: 'inline-flex', color: 'hsl(var(--primary))', flexShrink: 0 }}>
320
+ <span
321
+ style={{
322
+ display: 'inline-flex',
323
+ color: 'hsl(var(--primary))',
324
+ flexShrink: 0,
325
+ }}
326
+ >
298
327
  {icons?.check}
299
328
  </span>
300
329
  )
@@ -316,7 +345,9 @@ export function Combobox<V extends string>(props: ComboboxProps<V>): ReactElemen
316
345
  )}
317
346
  </div>
318
347
  {footer && (
319
- <div style={{ borderTop: '1px solid hsl(var(--rule))', padding: 6 }}>
348
+ <div
349
+ style={{ borderTop: '1px solid hsl(var(--rule))', padding: 6 }}
350
+ >
320
351
  {footer}
321
352
  </div>
322
353
  )}
@@ -33,10 +33,15 @@ function renderInline(text: string): ReactNode[] {
33
33
  // Split on bold or inline-code tokens, keeping the delimiters.
34
34
  const parts = text.split(/(\*\*[^*]+\*\*|`[^`]+`)/g);
35
35
  parts.forEach((part, index) => {
36
- if (!part) return;
36
+ if (!part) {
37
+ return;
38
+ }
37
39
  if (part.startsWith('**') && part.endsWith('**')) {
38
40
  nodes.push(
39
- <strong key={index} style={{ fontWeight: 600, color: 'hsl(var(--ink))' }}>
41
+ <strong
42
+ key={index}
43
+ style={{ fontWeight: 600, color: 'hsl(var(--ink))' }}
44
+ >
40
45
  {part.slice(2, -2)}
41
46
  </strong>,
42
47
  );
@@ -53,8 +58,12 @@ function renderInline(text: string): ReactNode[] {
53
58
  // Plain text — preserve hard line breaks.
54
59
  const lines = part.split('\n');
55
60
  lines.forEach((line, lineIndex) => {
56
- if (lineIndex > 0) nodes.push(<br key={`${index}-br-${lineIndex}`} />);
57
- if (line) nodes.push(<Fragment key={`${index}-t-${lineIndex}`}>{line}</Fragment>);
61
+ if (lineIndex > 0) {
62
+ nodes.push(<br key={`${index}-br-${lineIndex}`} />);
63
+ }
64
+ if (line) {
65
+ nodes.push(<Fragment key={`${index}-t-${lineIndex}`}>{line}</Fragment>);
66
+ }
58
67
  });
59
68
  });
60
69
  return nodes;
@@ -65,7 +74,7 @@ export interface MDProps {
65
74
  }
66
75
 
67
76
  export function MD({ children }: MDProps): ReactElement {
68
- const text = String(children ?? '');
77
+ const text = children;
69
78
  const blocks = text.split(/\n\n+/);
70
79
  return (
71
80
  <div style={{ display: 'flex', flexDirection: 'column', gap: 9 }}>
@@ -20,20 +20,19 @@
20
20
  // ═══════════════════════════════════════════════════════════════════════════
21
21
  import * as React from 'react';
22
22
 
23
- import type { BrandingConfig } from '@xemahq/kernel-contracts/app-platform';
24
-
25
23
  import { cn } from '../cn';
26
24
  import {
27
25
  AppBrandingContext,
28
26
  type AppBrandingContextValue,
29
27
  } from './app-branding-context';
30
-
31
28
  import {
32
29
  sanitizeCssCustomPropertyName,
33
30
  sanitizeCssValue,
34
31
  sanitizeLogoUrl,
35
32
  } from './sanitize';
36
33
 
34
+ import type { BrandingConfig } from '@xemahq/kernel-contracts/app-platform';
35
+
37
36
  /** CSS custom property carrying the app's resolved primary brand color. */
38
37
  export const APP_PRIMARY_COLOR_VAR = '--app-primary-color';
39
38
 
@@ -30,7 +30,9 @@ const CSS_CUSTOM_PROPERTY_NAME = /^[a-zA-Z_][a-zA-Z0-9_-]*$/;
30
30
  function hasControlChar(value: string): boolean {
31
31
  for (let i = 0; i < value.length; i += 1) {
32
32
  const code = value.charCodeAt(i);
33
- if (code < 0x20 || code === 0x7f) return true;
33
+ if (code < 0x20 || code === 0x7f) {
34
+ return true;
35
+ }
34
36
  }
35
37
  return false;
36
38
  }
@@ -41,9 +43,15 @@ function hasControlChar(value: string): boolean {
41
43
  */
42
44
  export function sanitizeCssValue(raw: string): string | null {
43
45
  const value = raw.trim();
44
- if (value.length === 0) return null;
45
- if (CSS_VALUE_UNSAFE.test(value)) return null;
46
- if (hasControlChar(value)) return null;
46
+ if (value.length === 0) {
47
+ return null;
48
+ }
49
+ if (CSS_VALUE_UNSAFE.test(value)) {
50
+ return null;
51
+ }
52
+ if (hasControlChar(value)) {
53
+ return null;
54
+ }
47
55
  return value;
48
56
  }
49
57
 
@@ -53,7 +61,9 @@ export function sanitizeCssValue(raw: string): string | null {
53
61
  */
54
62
  export function sanitizeCssCustomPropertyName(rawKey: string): string | null {
55
63
  const name = rawKey.trim();
56
- if (!CSS_CUSTOM_PROPERTY_NAME.test(name)) return null;
64
+ if (!CSS_CUSTOM_PROPERTY_NAME.test(name)) {
65
+ return null;
66
+ }
57
67
  return `--${name}`;
58
68
  }
59
69
 
@@ -63,7 +73,9 @@ export function sanitizeCssCustomPropertyName(rawKey: string): string | null {
63
73
  * is refused (returns `undefined`) so it never reaches `src`.
64
74
  */
65
75
  export function sanitizeLogoUrl(raw: string | undefined): string | undefined {
66
- if (raw === undefined) return undefined;
76
+ if (raw === undefined) {
77
+ return undefined;
78
+ }
67
79
  let parsed: URL;
68
80
  try {
69
81
  parsed = new URL(raw);
@@ -9,8 +9,14 @@
9
9
  import { type ReactNode } from 'react';
10
10
 
11
11
  import { cn } from '../cn';
12
-
13
- import { CaptureFieldType, type CaptureFieldSpec, type CaptureSchema, type CaptureSection, type CaptureValues, toSections } from './field-spec';
12
+ import {
13
+ CaptureFieldType,
14
+ type CaptureFieldSpec,
15
+ type CaptureSchema,
16
+ type CaptureSection,
17
+ type CaptureValues,
18
+ toSections,
19
+ } from './field-spec';
14
20
  import { formatScalar } from './value-format';
15
21
 
16
22
  export interface DocumentPreviewProps {
@@ -28,18 +34,44 @@ export interface DocumentPreviewProps {
28
34
  * @example
29
35
  * <DocumentPreview title="Review" sections={sections} values={values} />
30
36
  */
31
- export function DocumentPreview({ fields, sections, schema, values, title, emptyText = '—', className }: DocumentPreviewProps) {
37
+ export function DocumentPreview({
38
+ fields,
39
+ sections,
40
+ schema,
41
+ values,
42
+ title,
43
+ emptyText = '—',
44
+ className,
45
+ }: DocumentPreviewProps) {
32
46
  const resolved = toSections(sections ?? (fields ? fields : schema) ?? []);
33
47
  return (
34
- <article className={cn('rounded-xl border border-border bg-card p-5 text-card-foreground shadow-sm sm:p-6', className)}>
35
- {title ? <h2 className="mb-4 text-title font-semibold tracking-tight text-ink">{title}</h2> : null}
48
+ <article
49
+ className={cn(
50
+ 'rounded-xl border border-border bg-card p-5 text-card-foreground shadow-sm sm:p-6',
51
+ className,
52
+ )}
53
+ >
54
+ {title ? (
55
+ <h2 className="mb-4 text-title font-semibold tracking-tight text-ink">
56
+ {title}
57
+ </h2>
58
+ ) : null}
36
59
  <div className="space-y-6">
37
60
  {resolved.map((section) => (
38
61
  <section key={section.key}>
39
- {section.title ? <h3 className="mb-2 border-b border-rule pb-1 text-caption font-semibold uppercase tracking-wider text-ink-3">{section.title}</h3> : null}
62
+ {section.title ? (
63
+ <h3 className="mb-2 border-b border-rule pb-1 text-caption font-semibold uppercase tracking-wider text-ink-3">
64
+ {section.title}
65
+ </h3>
66
+ ) : null}
40
67
  <dl className="grid grid-cols-1 gap-x-6 gap-y-3 sm:grid-cols-[minmax(8rem,12rem)_1fr]">
41
68
  {section.fields.map((field) => (
42
- <FieldRow key={field.key} field={field} value={values[field.key]} emptyText={emptyText} />
69
+ <FieldRow
70
+ key={field.key}
71
+ field={field}
72
+ value={values[field.key]}
73
+ emptyText={emptyText}
74
+ />
43
75
  ))}
44
76
  </dl>
45
77
  </section>
@@ -49,25 +81,49 @@ export function DocumentPreview({ fields, sections, schema, values, title, empty
49
81
  );
50
82
  }
51
83
 
52
- function FieldRow({ field, value, emptyText }: { field: CaptureFieldSpec; value: unknown; emptyText: string }) {
84
+ function FieldRow({
85
+ field,
86
+ value,
87
+ emptyText,
88
+ }: {
89
+ field: CaptureFieldSpec;
90
+ value: unknown;
91
+ emptyText: string;
92
+ }) {
53
93
  return (
54
94
  <>
55
- <dt className="text-body-1 font-medium text-ink-3 sm:text-right">{field.label}</dt>
56
- <dd className="min-w-0 text-body-1 text-ink">{renderValue(field, value, emptyText)}</dd>
95
+ <dt className="text-body-1 font-medium text-ink-3 sm:text-right">
96
+ {field.label}
97
+ </dt>
98
+ <dd className="min-w-0 text-body-1 text-ink">
99
+ {renderValue(field, value, emptyText)}
100
+ </dd>
57
101
  </>
58
102
  );
59
103
  }
60
104
 
61
- function renderValue(field: CaptureFieldSpec, value: unknown, emptyText: string): ReactNode {
105
+ function renderValue(
106
+ field: CaptureFieldSpec,
107
+ value: unknown,
108
+ emptyText: string,
109
+ ): ReactNode {
62
110
  if (field.type === CaptureFieldType.Object) {
63
- const record = (value && typeof value === 'object' && !Array.isArray(value) ? value : null) as CaptureValues | null;
64
- if (!record) return <span className="text-ink-3">{emptyText}</span>;
111
+ const record = (
112
+ value && typeof value === 'object' && !Array.isArray(value) ? value : null
113
+ ) as CaptureValues | null;
114
+ if (!record) {
115
+ return <span className="text-ink-3">{emptyText}</span>;
116
+ }
65
117
  return (
66
118
  <dl className="space-y-1 rounded-md border border-rule bg-paper-elev/40 p-2">
67
119
  {(field.fields ?? []).map((child) => (
68
120
  <div key={child.key} className="flex flex-wrap gap-2">
69
- <dt className="text-caption font-medium text-ink-3">{child.label}:</dt>
70
- <dd className="text-caption text-ink">{renderValue(child, record[child.key], emptyText)}</dd>
121
+ <dt className="text-caption font-medium text-ink-3">
122
+ {child.label}:
123
+ </dt>
124
+ <dd className="text-caption text-ink">
125
+ {renderValue(child, record[child.key], emptyText)}
126
+ </dd>
71
127
  </div>
72
128
  ))}
73
129
  </dl>
@@ -75,19 +131,28 @@ function renderValue(field: CaptureFieldSpec, value: unknown, emptyText: string)
75
131
  }
76
132
  if (field.type === CaptureFieldType.List) {
77
133
  const items = (Array.isArray(value) ? value : []) as CaptureValues[];
78
- if (items.length === 0) return <span className="text-ink-3">{emptyText}</span>;
134
+ if (items.length === 0) {
135
+ return <span className="text-ink-3">{emptyText}</span>;
136
+ }
79
137
  return (
80
138
  <ol className="space-y-2">
81
139
  {items.map((item, index) => (
82
- <li key={index} className="rounded-md border border-rule bg-paper-elev/40 p-2">
140
+ <li
141
+ key={index}
142
+ className="rounded-md border border-rule bg-paper-elev/40 p-2"
143
+ >
83
144
  <p className="mb-1 text-caption font-medium text-ink-3">
84
145
  {field.label} #{index + 1}
85
146
  </p>
86
147
  <dl className="space-y-1">
87
148
  {(field.fields ?? []).map((child) => (
88
149
  <div key={child.key} className="flex flex-wrap gap-2">
89
- <dt className="text-caption font-medium text-ink-3">{child.label}:</dt>
90
- <dd className="text-caption text-ink">{renderValue(child, item[child.key], emptyText)}</dd>
150
+ <dt className="text-caption font-medium text-ink-3">
151
+ {child.label}:
152
+ </dt>
153
+ <dd className="text-caption text-ink">
154
+ {renderValue(child, item[child.key], emptyText)}
155
+ </dd>
91
156
  </div>
92
157
  ))}
93
158
  </dl>