@cosmicdrift/kumiko-renderer 0.374.0 → 0.378.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 (477) hide show
  1. package/README.md +2 -2
  2. package/dist/app/action-form-support.d.ts +9 -2
  3. package/dist/app/action-form-support.js +24 -2
  4. package/dist/app/client-actions.d.ts +2 -2
  5. package/dist/app/column-renderers.js +1 -1
  6. package/dist/app/config-edit-shim.js +1 -1
  7. package/dist/app/content-preview.js +1 -6
  8. package/dist/app/custom-screens.js +1 -1
  9. package/dist/app/dashboard-body.d.ts +1 -1
  10. package/dist/app/entity-list-expanded-row.d.ts +1 -1
  11. package/dist/app/form-schema.d.ts +1 -1
  12. package/dist/app/form-schema.js +2 -2
  13. package/dist/app/kumiko-screen.d.ts +1 -1
  14. package/dist/app/kumiko-screen.js +10 -7
  15. package/dist/app/list-empty-content.d.ts +1 -1
  16. package/dist/app/list-facets.d.ts +1 -1
  17. package/dist/app/nav.js +2 -2
  18. package/dist/app/query-state-banners.d.ts +1 -1
  19. package/dist/app/reference-link.d.ts +1 -1
  20. package/dist/app/row-actions.d.ts +1 -1
  21. package/dist/app/secret-mint-body.d.ts +1 -1
  22. package/dist/app/secrets-edit-body.d.ts +1 -1
  23. package/dist/app/use-record-actions.d.ts +1 -1
  24. package/dist/app/write-failed-error.d.ts +1 -1
  25. package/dist/components/availability-options-select.d.ts +1 -1
  26. package/dist/components/embedded-list-field.d.ts +1 -1
  27. package/dist/components/embedded-list-field.js +1 -1
  28. package/dist/components/file-list-field.d.ts +1 -1
  29. package/dist/components/form-derivation-patch.d.ts +8 -0
  30. package/dist/components/form-derivation-patch.js +24 -0
  31. package/dist/components/form-screen-layout.d.ts +13 -0
  32. package/dist/components/form-screen-layout.js +13 -0
  33. package/dist/components/grid-cell-for-field.d.ts +1 -1
  34. package/dist/components/multi-select-checkboxes.d.ts +1 -1
  35. package/dist/components/multi-select-checkboxes.js +1 -1
  36. package/dist/components/query-options-select.d.ts +1 -1
  37. package/dist/components/related-list-section.d.ts +1 -1
  38. package/dist/components/render-edit-logic.d.ts +1 -1
  39. package/dist/components/render-edit-types.d.ts +6 -3
  40. package/dist/components/render-edit.d.ts +1 -1
  41. package/dist/components/render-edit.js +18 -3
  42. package/dist/components/render-field.d.ts +1 -1
  43. package/dist/components/render-field.js +12 -2
  44. package/dist/components/render-list.d.ts +1 -1
  45. package/dist/components/render-list.js +20 -4
  46. package/dist/components/write-form-section.d.ts +1 -1
  47. package/dist/components/write-form-section.js +1 -1
  48. package/dist/context/dispatcher-context.d.ts +1 -1
  49. package/dist/file-ids-of.d.ts +1 -0
  50. package/dist/file-ids-of.js +7 -0
  51. package/dist/flow-diagram/icons.d.ts +3 -0
  52. package/dist/flow-diagram/icons.js +14 -0
  53. package/dist/flow-diagram/index.d.ts +2 -0
  54. package/dist/flow-diagram/index.js +1 -0
  55. package/dist/flow-diagram/render.d.ts +3 -0
  56. package/dist/flow-diagram/render.js +234 -0
  57. package/dist/flow-diagram/types.d.ts +18 -0
  58. package/dist/flow-diagram/types.js +1 -0
  59. package/dist/format-when.js +1 -1
  60. package/dist/headless/apex/css.d.ts +3 -0
  61. package/dist/headless/apex/css.js +298 -0
  62. package/dist/headless/apex/index.d.ts +236 -0
  63. package/dist/headless/apex/index.js +377 -0
  64. package/dist/headless/apex/lightbox.d.ts +4 -0
  65. package/dist/headless/apex/lightbox.js +81 -0
  66. package/dist/headless/contracts/asset.d.ts +15 -0
  67. package/dist/headless/contracts/asset.js +17 -0
  68. package/dist/headless/contracts/index.d.ts +3 -0
  69. package/dist/headless/contracts/index.js +1 -0
  70. package/dist/headless/contracts/locale.d.ts +7 -0
  71. package/dist/headless/contracts/locale.js +11 -0
  72. package/dist/headless/contracts/primitives.d.ts +93 -0
  73. package/dist/headless/contracts/primitives.js +21 -0
  74. package/dist/headless/dispatcher/index.d.ts +2 -0
  75. package/dist/headless/dispatcher/index.js +1 -0
  76. package/dist/headless/dispatcher/types.d.ts +86 -0
  77. package/dist/headless/dispatcher/types.js +34 -0
  78. package/dist/headless/form/form-controller.d.ts +2 -0
  79. package/dist/headless/form/form-controller.js +409 -0
  80. package/dist/headless/form/index.d.ts +3 -0
  81. package/dist/headless/form/index.js +2 -0
  82. package/dist/headless/form/types.d.ts +76 -0
  83. package/dist/headless/form/types.js +1 -0
  84. package/dist/headless/form/zod-bridge.d.ts +10 -0
  85. package/dist/headless/form/zod-bridge.js +103 -0
  86. package/dist/headless/format/document-values.d.ts +12 -0
  87. package/dist/headless/format/document-values.js +70 -0
  88. package/dist/headless/format/escape.d.ts +5 -0
  89. package/dist/headless/format/escape.js +75 -0
  90. package/dist/headless/format/html-template.d.ts +9 -0
  91. package/dist/headless/format/html-template.js +39 -0
  92. package/dist/headless/format/index.d.ts +12 -0
  93. package/dist/headless/format/index.js +237 -0
  94. package/dist/headless/format/money.d.ts +3 -0
  95. package/dist/headless/format/money.js +39 -0
  96. package/dist/headless/index.d.ts +14 -0
  97. package/dist/headless/index.js +9 -0
  98. package/dist/headless/locale-routing/index.d.ts +41 -0
  99. package/dist/headless/locale-routing/index.js +145 -0
  100. package/dist/headless/nav/index.d.ts +2 -0
  101. package/dist/headless/nav/index.js +1 -0
  102. package/dist/headless/nav/resolve.d.ts +2 -0
  103. package/dist/headless/nav/resolve.js +71 -0
  104. package/dist/headless/nav/types.d.ts +26 -0
  105. package/dist/headless/nav/types.js +1 -0
  106. package/dist/headless/store/create-store.d.ts +2 -0
  107. package/dist/headless/store/create-store.js +43 -0
  108. package/dist/headless/store/equality.d.ts +1 -0
  109. package/dist/headless/store/equality.js +34 -0
  110. package/dist/headless/store/index.d.ts +3 -0
  111. package/dist/headless/store/index.js +2 -0
  112. package/dist/headless/store/types.d.ts +7 -0
  113. package/dist/headless/store/types.js +10 -0
  114. package/dist/headless/view-model/edit.d.ts +21 -0
  115. package/dist/headless/view-model/edit.js +512 -0
  116. package/dist/headless/view-model/embedded-list.d.ts +27 -0
  117. package/dist/headless/view-model/embedded-list.js +63 -0
  118. package/dist/headless/view-model/index.d.ts +7 -0
  119. package/dist/headless/view-model/index.js +3 -0
  120. package/dist/headless/view-model/list-file-display.d.ts +3 -0
  121. package/dist/headless/view-model/list-file-display.js +27 -0
  122. package/dist/headless/view-model/list.d.ts +16 -0
  123. package/dist/headless/view-model/list.js +229 -0
  124. package/dist/headless/view-model/types.d.ts +382 -0
  125. package/dist/headless/view-model/types.js +1 -0
  126. package/dist/hooks/use-ai-text.d.ts +1 -1
  127. package/dist/hooks/use-form.d.ts +1 -1
  128. package/dist/hooks/use-form.js +1 -1
  129. package/dist/hooks/use-mutation.d.ts +1 -1
  130. package/dist/hooks/use-query.d.ts +1 -1
  131. package/dist/hooks/use-store.d.ts +1 -1
  132. package/dist/hooks/use-store.js +7 -7
  133. package/dist/hooks/use-stream-handler.d.ts +1 -1
  134. package/dist/i18n-defaults.js +6 -0
  135. package/dist/i18n.d.ts +1 -1
  136. package/dist/i18n.js +1 -1
  137. package/dist/index.d.ts +3 -1
  138. package/dist/index.js +5 -4
  139. package/dist/live/csrf.d.ts +2 -0
  140. package/dist/live/csrf.js +60 -0
  141. package/dist/live/dispatcher-live.d.ts +7 -0
  142. package/dist/live/dispatcher-live.js +286 -0
  143. package/dist/live/envelopes.d.ts +101 -0
  144. package/dist/live/envelopes.js +35 -0
  145. package/dist/live/error-mapping.d.ts +16 -0
  146. package/dist/live/error-mapping.js +82 -0
  147. package/dist/live/index.d.ts +7 -0
  148. package/dist/live/index.js +5 -0
  149. package/dist/live/locale.d.ts +2 -0
  150. package/dist/live/locale.js +25 -0
  151. package/dist/live/sse-stream.d.ts +14 -0
  152. package/dist/live/sse-stream.js +128 -0
  153. package/dist/primitives.d.ts +45 -36
  154. package/dist/primitives.js +1 -1
  155. package/dist/session/session-ended.d.ts +1 -1
  156. package/dist/tokens.d.ts +3 -4
  157. package/dist/tokens.js +4 -5
  158. package/dist/web/app/app-schema-boot.d.ts +19 -0
  159. package/dist/web/app/app-schema-boot.js +124 -0
  160. package/dist/web/app/browser-locale.d.ts +22 -0
  161. package/dist/web/app/browser-locale.js +78 -0
  162. package/dist/web/app/client-plugin.d.ts +106 -0
  163. package/dist/web/app/client-plugin.js +12 -0
  164. package/dist/web/app/create-app.d.ts +104 -0
  165. package/dist/web/app/create-app.js +498 -0
  166. package/dist/web/app/create-public-surface.d.ts +36 -0
  167. package/dist/web/app/create-public-surface.js +40 -0
  168. package/dist/web/app/dashboard-body.d.ts +3 -0
  169. package/dist/web/app/dashboard-body.js +865 -0
  170. package/dist/web/app/dashboard-refresh.d.ts +6 -0
  171. package/dist/web/app/dashboard-refresh.js +15 -0
  172. package/dist/web/app/document-lang-sync.d.ts +4 -0
  173. package/dist/web/app/document-lang-sync.js +27 -0
  174. package/dist/web/app/draft-storage.d.ts +11 -0
  175. package/dist/web/app/draft-storage.js +53 -0
  176. package/dist/web/app/nav-providers-context.d.ts +13 -0
  177. package/dist/web/app/nav-providers-context.js +18 -0
  178. package/dist/web/app/nav.d.ts +40 -0
  179. package/dist/web/app/nav.js +231 -0
  180. package/dist/web/app/plain-content-editor.d.ts +3 -0
  181. package/dist/web/app/plain-content-editor.js +30 -0
  182. package/dist/web/app/relative-time.d.ts +10 -0
  183. package/dist/web/app/relative-time.js +56 -0
  184. package/dist/web/app/resolvers-context.d.ts +12 -0
  185. package/dist/web/app/resolvers-context.js +10 -0
  186. package/dist/web/app/rich-content-editor.d.ts +3 -0
  187. package/dist/web/app/rich-content-editor.js +15 -0
  188. package/dist/web/app/root-error-fallback.d.ts +2 -0
  189. package/dist/web/app/root-error-fallback.js +21 -0
  190. package/dist/web/app/screen-error-fallback.d.ts +6 -0
  191. package/dist/web/app/screen-error-fallback.js +17 -0
  192. package/dist/web/app/tiptap-editor.d.ts +3 -0
  193. package/dist/web/app/tiptap-editor.js +120 -0
  194. package/dist/web/app/toast-action-notifier.d.ts +5 -0
  195. package/dist/web/app/toast-action-notifier.js +17 -0
  196. package/dist/web/components/config-cascade.d.ts +13 -0
  197. package/dist/web/components/config-cascade.js +155 -0
  198. package/dist/web/components/config-source-badge.d.ts +6 -0
  199. package/dist/web/components/config-source-badge.js +55 -0
  200. package/dist/web/default-color-scheme.d.ts +2 -0
  201. package/dist/web/default-color-scheme.js +3 -0
  202. package/dist/web/icons.d.ts +94 -0
  203. package/dist/web/icons.js +100 -0
  204. package/dist/web/index.d.ts +78 -0
  205. package/dist/web/index.js +53 -0
  206. package/dist/web/layout/app-layout.d.ts +21 -0
  207. package/dist/web/layout/app-layout.js +8 -0
  208. package/dist/web/layout/avatar.d.ts +12 -0
  209. package/dist/web/layout/avatar.js +63 -0
  210. package/dist/web/layout/default-app-shell.d.ts +41 -0
  211. package/dist/web/layout/default-app-shell.js +16 -0
  212. package/dist/web/layout/editor-panel.d.ts +10 -0
  213. package/dist/web/layout/editor-panel.js +29 -0
  214. package/dist/web/layout/fill-classes.d.ts +9 -0
  215. package/dist/web/layout/fill-classes.js +15 -0
  216. package/dist/web/layout/filter-app-schema-navs.d.ts +7 -0
  217. package/dist/web/layout/filter-app-schema-navs.js +68 -0
  218. package/dist/web/layout/header-action-group.d.ts +6 -0
  219. package/dist/web/layout/header-action-group.js +8 -0
  220. package/dist/web/layout/header-overflow-menu.d.ts +4 -0
  221. package/dist/web/layout/header-overflow-menu.js +8 -0
  222. package/dist/web/layout/language-menu-items.d.ts +8 -0
  223. package/dist/web/layout/language-menu-items.js +16 -0
  224. package/dist/web/layout/language-switcher.d.ts +25 -0
  225. package/dist/web/layout/language-switcher.js +46 -0
  226. package/dist/web/layout/nav-tree.d.ts +19 -0
  227. package/dist/web/layout/nav-tree.js +536 -0
  228. package/dist/web/layout/page-header-slot.d.ts +25 -0
  229. package/dist/web/layout/page-header-slot.js +50 -0
  230. package/dist/web/layout/profile-menu.d.ts +13 -0
  231. package/dist/web/layout/profile-menu.js +6 -0
  232. package/dist/web/layout/shell-breadcrumb.d.ts +11 -0
  233. package/dist/web/layout/shell-breadcrumb.js +34 -0
  234. package/dist/web/layout/shell-header.d.ts +12 -0
  235. package/dist/web/layout/shell-header.js +159 -0
  236. package/dist/web/layout/sidebar-brand.d.ts +15 -0
  237. package/dist/web/layout/sidebar-brand.js +9 -0
  238. package/dist/web/layout/sidebar-panel.d.ts +41 -0
  239. package/dist/web/layout/sidebar-panel.js +107 -0
  240. package/dist/web/layout/sidebar-user.d.ts +8 -0
  241. package/dist/web/layout/sidebar-user.js +17 -0
  242. package/dist/web/layout/sidebar.d.ts +17 -0
  243. package/dist/web/layout/sidebar.js +11 -0
  244. package/dist/web/layout/target-resolver-stub.d.ts +13 -0
  245. package/dist/web/layout/target-resolver-stub.js +61 -0
  246. package/dist/web/layout/target-url.d.ts +12 -0
  247. package/dist/web/layout/target-url.js +77 -0
  248. package/dist/web/layout/theme-label.d.ts +15 -0
  249. package/dist/web/layout/theme-label.js +35 -0
  250. package/dist/web/layout/theme-menu-item.d.ts +12 -0
  251. package/dist/web/layout/theme-menu-item.js +16 -0
  252. package/dist/web/layout/theme-toggle.d.ts +17 -0
  253. package/dist/web/layout/theme-toggle.js +22 -0
  254. package/dist/web/layout/topbar.d.ts +8 -0
  255. package/dist/web/layout/topbar.js +4 -0
  256. package/dist/web/layout/workspace-shell.d.ts +63 -0
  257. package/dist/web/layout/workspace-shell.js +220 -0
  258. package/dist/web/layout/workspace-switcher.d.ts +15 -0
  259. package/dist/web/layout/workspace-switcher.js +36 -0
  260. package/dist/web/lib/accept-attr.d.ts +1 -0
  261. package/dist/web/lib/accept-attr.js +6 -0
  262. package/dist/web/lib/clamp.d.ts +1 -0
  263. package/dist/web/lib/clamp.js +3 -0
  264. package/dist/web/lib/cn.d.ts +6 -0
  265. package/dist/web/lib/cn.js +9 -0
  266. package/dist/web/lib/download.d.ts +2 -0
  267. package/dist/web/lib/download.js +24 -0
  268. package/dist/web/lib/file-ref-download.d.ts +15 -0
  269. package/dist/web/lib/file-ref-download.js +62 -0
  270. package/dist/web/lib/file-upload-form-data.d.ts +7 -0
  271. package/dist/web/lib/file-upload-form-data.js +11 -0
  272. package/dist/web/lib/resize-image.d.ts +1 -0
  273. package/dist/web/lib/resize-image.js +66 -0
  274. package/dist/web/lib/upload-file-ref.d.ts +9 -0
  275. package/dist/web/lib/upload-file-ref.js +29 -0
  276. package/dist/web/primitives/action-menu.d.ts +34 -0
  277. package/dist/web/primitives/action-menu.js +30 -0
  278. package/dist/web/primitives/calendar-popover.d.ts +13 -0
  279. package/dist/web/primitives/calendar-popover.js +76 -0
  280. package/dist/web/primitives/combobox.d.ts +56 -0
  281. package/dist/web/primitives/combobox.js +127 -0
  282. package/dist/web/primitives/date-field.d.ts +18 -0
  283. package/dist/web/primitives/date-field.js +74 -0
  284. package/dist/web/primitives/date-input.d.ts +1 -0
  285. package/dist/web/primitives/date-input.js +5 -0
  286. package/dist/web/primitives/date-parse.d.ts +11 -0
  287. package/dist/web/primitives/date-parse.js +159 -0
  288. package/dist/web/primitives/dialog.d.ts +3 -0
  289. package/dist/web/primitives/dialog.js +42 -0
  290. package/dist/web/primitives/drawer.d.ts +3 -0
  291. package/dist/web/primitives/drawer.js +17 -0
  292. package/dist/web/primitives/dropdown-menu.d.ts +15 -0
  293. package/dist/web/primitives/dropdown-menu.js +56 -0
  294. package/dist/web/primitives/embedded-list-input.d.ts +9 -0
  295. package/dist/web/primitives/embedded-list-input.js +382 -0
  296. package/dist/web/primitives/file-thumbnail.d.ts +31 -0
  297. package/dist/web/primitives/file-thumbnail.js +90 -0
  298. package/dist/web/primitives/file-upload.d.ts +21 -0
  299. package/dist/web/primitives/file-upload.js +56 -0
  300. package/dist/web/primitives/file-value-list.d.ts +3 -0
  301. package/dist/web/primitives/file-value-list.js +22 -0
  302. package/dist/web/primitives/index.d.ts +34 -0
  303. package/dist/web/primitives/index.js +2023 -0
  304. package/dist/web/primitives/json-view.d.ts +7 -0
  305. package/dist/web/primitives/json-view.js +84 -0
  306. package/dist/web/primitives/layout.d.ts +27 -0
  307. package/dist/web/primitives/layout.js +30 -0
  308. package/dist/web/primitives/lightbox.d.ts +3 -0
  309. package/dist/web/primitives/lightbox.js +36 -0
  310. package/dist/web/primitives/locale-number.d.ts +2 -0
  311. package/dist/web/primitives/locale-number.js +54 -0
  312. package/dist/web/primitives/located-timestamp-input.d.ts +22 -0
  313. package/dist/web/primitives/located-timestamp-input.js +22 -0
  314. package/dist/web/primitives/metric.d.ts +5 -0
  315. package/dist/web/primitives/metric.js +18 -0
  316. package/dist/web/primitives/modal-shell.d.ts +17 -0
  317. package/dist/web/primitives/modal-shell.js +9 -0
  318. package/dist/web/primitives/modal.d.ts +3 -0
  319. package/dist/web/primitives/modal.js +13 -0
  320. package/dist/web/primitives/money-input.d.ts +18 -0
  321. package/dist/web/primitives/money-input.js +122 -0
  322. package/dist/web/primitives/narrow-pinned-footer.d.ts +12 -0
  323. package/dist/web/primitives/narrow-pinned-footer.js +153 -0
  324. package/dist/web/primitives/number-input.d.ts +18 -0
  325. package/dist/web/primitives/number-input.js +53 -0
  326. package/dist/web/primitives/option-groups.d.ts +11 -0
  327. package/dist/web/primitives/option-groups.js +27 -0
  328. package/dist/web/primitives/page-header.d.ts +3 -0
  329. package/dist/web/primitives/page-header.js +52 -0
  330. package/dist/web/primitives/promo-panel.d.ts +3 -0
  331. package/dist/web/primitives/promo-panel.js +11 -0
  332. package/dist/web/primitives/segmented-select.d.ts +21 -0
  333. package/dist/web/primitives/segmented-select.js +62 -0
  334. package/dist/web/primitives/share-actions.d.ts +4 -0
  335. package/dist/web/primitives/share-actions.js +56 -0
  336. package/dist/web/primitives/status-badge.d.ts +3 -0
  337. package/dist/web/primitives/status-badge.js +5 -0
  338. package/dist/web/primitives/sticky-action-bar.d.ts +5 -0
  339. package/dist/web/primitives/sticky-action-bar.js +15 -0
  340. package/dist/web/primitives/tabs.d.ts +3 -0
  341. package/dist/web/primitives/tabs.js +107 -0
  342. package/dist/web/primitives/timestamp-input.d.ts +27 -0
  343. package/dist/web/primitives/timestamp-input.js +87 -0
  344. package/dist/web/primitives/toast.d.ts +19 -0
  345. package/dist/web/primitives/toast.js +63 -0
  346. package/dist/web/primitives/tz-input.d.ts +11 -0
  347. package/dist/web/primitives/tz-input.js +8 -0
  348. package/dist/web/primitives/tz-options.d.ts +4 -0
  349. package/dist/web/primitives/tz-options.js +17 -0
  350. package/dist/web/primitives/use-keyboard-inset.d.ts +1 -0
  351. package/dist/web/primitives/use-keyboard-inset.js +28 -0
  352. package/dist/web/primitives/use-narrow-viewport.d.ts +4 -0
  353. package/dist/web/primitives/use-narrow-viewport.js +46 -0
  354. package/dist/web/react-css-custom-properties.d.ts +6 -0
  355. package/dist/web/react-css-custom-properties.js +1 -0
  356. package/dist/web/sse/live-events.d.ts +15 -0
  357. package/dist/web/sse/live-events.js +148 -0
  358. package/dist/web/theme-plugin.d.ts +41 -0
  359. package/dist/web/theme-plugin.js +123 -0
  360. package/dist/web/tokens.d.ts +24 -0
  361. package/dist/web/tokens.js +203 -0
  362. package/dist/web/ui/avatar.d.ts +11 -0
  363. package/dist/web/ui/avatar.js +25 -0
  364. package/dist/web/ui/badge.d.ts +9 -0
  365. package/dist/web/ui/badge.js +26 -0
  366. package/dist/web/ui/breadcrumb.d.ts +11 -0
  367. package/dist/web/ui/breadcrumb.js +29 -0
  368. package/dist/web/ui/button.d.ts +10 -0
  369. package/dist/web/ui/button.js +37 -0
  370. package/dist/web/ui/checkbox.d.ts +4 -0
  371. package/dist/web/ui/checkbox.js +11 -0
  372. package/dist/web/ui/input.d.ts +3 -0
  373. package/dist/web/ui/input.js +8 -0
  374. package/dist/web/ui/label.d.ts +4 -0
  375. package/dist/web/ui/label.js +10 -0
  376. package/dist/web/ui/resizable.d.ts +7 -0
  377. package/dist/web/ui/resizable.js +16 -0
  378. package/dist/web/ui/separator.d.ts +4 -0
  379. package/dist/web/ui/separator.js +10 -0
  380. package/dist/web/ui/sheet.d.ts +14 -0
  381. package/dist/web/ui/sheet.js +42 -0
  382. package/dist/web/ui/sidebar.d.ts +73 -0
  383. package/dist/web/ui/sidebar.js +211 -0
  384. package/dist/web/ui/skeleton.d.ts +2 -0
  385. package/dist/web/ui/skeleton.js +7 -0
  386. package/dist/web/ui/switch.d.ts +6 -0
  387. package/dist/web/ui/switch.js +10 -0
  388. package/dist/web/ui/table.d.ts +10 -0
  389. package/dist/web/ui/table.js +30 -0
  390. package/dist/web/ui/tabs.d.ts +11 -0
  391. package/dist/web/ui/tabs.js +31 -0
  392. package/dist/web/ui/textarea.d.ts +3 -0
  393. package/dist/web/ui/textarea.js +8 -0
  394. package/dist/web/ui/tooltip.d.ts +7 -0
  395. package/dist/web/ui/tooltip.js +19 -0
  396. package/dist/web/ui/use-mobile.d.ts +1 -0
  397. package/dist/web/ui/use-mobile.js +16 -0
  398. package/dist/web/version/update-checker.d.ts +9 -0
  399. package/dist/web/version/update-checker.js +88 -0
  400. package/dist/web/widgets/ai-text-field.d.ts +36 -0
  401. package/dist/web/widgets/ai-text-field.js +137 -0
  402. package/dist/web/widgets/bounded-load-cache.d.ts +1 -0
  403. package/dist/web/widgets/bounded-load-cache.js +25 -0
  404. package/dist/web/widgets/chart-window.d.ts +58 -0
  405. package/dist/web/widgets/chart-window.js +190 -0
  406. package/dist/web/widgets/charts.d.ts +208 -0
  407. package/dist/web/widgets/charts.js +685 -0
  408. package/dist/web/widgets/collapsible-section.d.ts +10 -0
  409. package/dist/web/widgets/collapsible-section.js +17 -0
  410. package/dist/web/widgets/dashboard-list.d.ts +21 -0
  411. package/dist/web/widgets/dashboard-list.js +45 -0
  412. package/dist/web/widgets/detail-list.d.ts +15 -0
  413. package/dist/web/widgets/detail-list.js +8 -0
  414. package/dist/web/widgets/drawer.d.ts +65 -0
  415. package/dist/web/widgets/drawer.js +177 -0
  416. package/dist/web/widgets/feed-list.d.ts +13 -0
  417. package/dist/web/widgets/feed-list.js +9 -0
  418. package/dist/web/widgets/floating-panel.d.ts +30 -0
  419. package/dist/web/widgets/floating-panel.js +242 -0
  420. package/dist/web/widgets/form-fields.d.ts +93 -0
  421. package/dist/web/widgets/form-fields.js +50 -0
  422. package/dist/web/widgets/index.d.ts +28 -0
  423. package/dist/web/widgets/index.js +31 -0
  424. package/dist/web/widgets/infinity-list.d.ts +46 -0
  425. package/dist/web/widgets/infinity-list.js +211 -0
  426. package/dist/web/widgets/mode-switch.d.ts +21 -0
  427. package/dist/web/widgets/mode-switch.js +25 -0
  428. package/dist/web/widgets/pdf-preview.d.ts +10 -0
  429. package/dist/web/widgets/pdf-preview.js +140 -0
  430. package/dist/web/widgets/photo-slots.d.ts +29 -0
  431. package/dist/web/widgets/photo-slots.js +52 -0
  432. package/dist/web/widgets/plan-card.d.ts +36 -0
  433. package/dist/web/widgets/plan-card.js +13 -0
  434. package/dist/web/widgets/progress-bar.d.ts +19 -0
  435. package/dist/web/widgets/progress-bar.js +24 -0
  436. package/dist/web/widgets/progress-list.d.ts +19 -0
  437. package/dist/web/widgets/progress-list.js +11 -0
  438. package/dist/web/widgets/public-shell.d.ts +22 -0
  439. package/dist/web/widgets/public-shell.js +15 -0
  440. package/dist/web/widgets/query-table.d.ts +29 -0
  441. package/dist/web/widgets/query-table.js +30 -0
  442. package/dist/web/widgets/result-panel.d.ts +69 -0
  443. package/dist/web/widgets/result-panel.js +30 -0
  444. package/dist/web/widgets/section-card.d.ts +12 -0
  445. package/dist/web/widgets/section-card.js +9 -0
  446. package/dist/web/widgets/sheet-parts.d.ts +9 -0
  447. package/dist/web/widgets/sheet-parts.js +11 -0
  448. package/dist/web/widgets/side-by-side-table.d.ts +31 -0
  449. package/dist/web/widgets/side-by-side-table.js +11 -0
  450. package/dist/web/widgets/stat.d.ts +54 -0
  451. package/dist/web/widgets/stat.js +65 -0
  452. package/dist/web/widgets/states.d.ts +23 -0
  453. package/dist/web/widgets/states.js +20 -0
  454. package/dist/web/widgets/status-badge.d.ts +15 -0
  455. package/dist/web/widgets/status-badge.js +24 -0
  456. package/dist/web/widgets/step-bar.d.ts +35 -0
  457. package/dist/web/widgets/step-bar.js +60 -0
  458. package/dist/web/widgets/upload-zone.d.ts +24 -0
  459. package/dist/web/widgets/upload-zone.js +108 -0
  460. package/dist/web/widgets/use-draft.d.ts +20 -0
  461. package/dist/web/widgets/use-draft.js +21 -0
  462. package/dist/web/widgets/use-pointer-drag.d.ts +21 -0
  463. package/dist/web/widgets/use-pointer-drag.js +53 -0
  464. package/package.json +114 -7
  465. package/src/changes.json +92 -0
  466. package/src/web/fonts/OFL.txt +93 -0
  467. package/src/web/fonts/ibm-plex-mono-latin-400.woff2 +0 -0
  468. package/src/web/fonts/ibm-plex-mono-latin-500.woff2 +0 -0
  469. package/src/web/fonts/ibm-plex-mono-latin-ext-400.woff2 +0 -0
  470. package/src/web/fonts/ibm-plex-mono-latin-ext-500.woff2 +0 -0
  471. package/src/web/fonts/ibm-plex-sans-latin-400.woff2 +0 -0
  472. package/src/web/fonts/ibm-plex-sans-latin-500.woff2 +0 -0
  473. package/src/web/fonts/ibm-plex-sans-latin-600.woff2 +0 -0
  474. package/src/web/fonts/ibm-plex-sans-latin-ext-400.woff2 +0 -0
  475. package/src/web/fonts/ibm-plex-sans-latin-ext-500.woff2 +0 -0
  476. package/src/web/fonts/ibm-plex-sans-latin-ext-600.woff2 +0 -0
  477. package/src/web/styles.css +405 -0
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @cosmicdrift/kumiko-renderer
2
2
 
3
- Platform-agnostic React renderer for Kumiko screens: primitives contract, hooks, `KumikoScreen`, navigation and SSE abstractions. No DOM, no `EventSource`, no `react-dom`.
3
+ React renderer for Kumiko screens: primitives contract, hooks, `KumikoScreen`, navigation and SSE abstractions. The root entry has no DOM and no `EventSource`; the subpaths add the web bindings (`/web`), UI logic (`/headless`) and the HTTP dispatcher (`/live`).
4
4
 
5
5
  ## Install
6
6
 
@@ -8,6 +8,6 @@ Platform-agnostic React renderer for Kumiko screens: primitives contract, hooks,
8
8
  bun add @cosmicdrift/kumiko-renderer
9
9
  ```
10
10
 
11
- Pair it with `@cosmicdrift/kumiko-renderer-web` for the browser.
11
+ Import the browser bindings from `@cosmicdrift/kumiko-renderer/web`.
12
12
 
13
13
  Documentation: https://kumiko.rocks
@@ -1,6 +1,6 @@
1
- import type { ActionFormLoad } from "@cosmicdrift/kumiko-framework/ui-types";
2
- import type { DispatcherError, Translate } from "@cosmicdrift/kumiko-headless";
1
+ import type { ActionFormLoad, ActionFormSuccessFact } from "@cosmicdrift/kumiko-framework/ui-types";
3
2
  import { type ReactNode } from "react";
3
+ import type { DispatcherError, Translate } from "../headless/index.ts";
4
4
  /** Record id of a `load` form: the route path id, else the drawer prefill `id`
5
5
  * (the clicked row), else the URL `id` param. Only the id is read from these
6
6
  * sources, never another value. */
@@ -42,10 +42,17 @@ export type ResolvedSuccessLink = {
42
42
  readonly href: string;
43
43
  readonly onPress: () => void;
44
44
  };
45
+ export type ResolvedSuccessFact = {
46
+ readonly key: string;
47
+ readonly label: string;
48
+ readonly lines: readonly string[];
49
+ };
45
50
  export type ActionFormSuccessState = {
46
51
  readonly text: string;
47
52
  readonly links: readonly ResolvedSuccessLink[];
53
+ readonly facts: readonly ResolvedSuccessFact[];
48
54
  };
55
+ export declare function resolveSuccessFacts(facts: readonly ActionFormSuccessFact[] | undefined, data: unknown, translate: (key: string) => string, locale: string): readonly ResolvedSuccessFact[];
49
56
  export declare function ActionFormSuccessBanner({ success, }: {
50
57
  readonly success: ActionFormSuccessState;
51
58
  }): ReactNode;
@@ -68,7 +68,29 @@ export function ActionFormLoadStatus({ state, screenId, translate, }) {
68
68
  return (_jsxs(Banner, { padded: true, variant: "error", testId: "kumiko-screen-action-form-missing-id", children: ["Screen ", _jsx(Text, { variant: "code", children: screenId }), " (actionForm with load) needs a record id in the path or the clicked row."] }));
69
69
  }
70
70
  }
71
+ function factLine(entry, locale) {
72
+ if (typeof entry === "number")
73
+ return entry.toLocaleString(locale);
74
+ if (typeof entry === "string")
75
+ return entry;
76
+ if (typeof entry === "object" && entry !== null && "label" in entry) {
77
+ return typeof entry.label === "string" ? entry.label : undefined;
78
+ }
79
+ return undefined;
80
+ }
81
+ export function resolveSuccessFacts(facts, data, translate, locale) {
82
+ const resolved = [];
83
+ (facts ?? []).forEach((fact, index) => {
84
+ const value = propertyOf(data, fact.field);
85
+ const entries = Array.isArray(value) ? value : [value];
86
+ const lines = entries.flatMap((entry) => factLine(entry, locale) ?? []);
87
+ if (lines.length > 0) {
88
+ resolved.push({ key: String(index), label: translate(fact.label), lines });
89
+ }
90
+ });
91
+ return resolved;
92
+ }
71
93
  export function ActionFormSuccessBanner({ success, }) {
72
- const { Banner, Link } = usePrimitives();
73
- return (_jsxs(Banner, { variant: "info", testId: "action-form-success", children: [success.text, success.links.map((link) => (_jsx(Link, { href: link.href, onPress: link.onPress, className: "ml-2 underline", testId: `action-form-success-link-${link.key}`, children: link.label }, link.key)))] }));
94
+ const { Banner, Link, Text } = usePrimitives();
95
+ return (_jsxs(Banner, { variant: "info", testId: "action-form-success", children: [success.text, success.facts.map((fact) => (_jsxs(Text, { testId: `action-form-success-fact-${fact.key}`, children: [fact.label, ": ", fact.lines.join(", ")] }, fact.key))), success.links.map((link) => (_jsx(Link, { href: link.href, onPress: link.onPress, className: "ml-2 underline", testId: `action-form-success-link-${link.key}`, children: link.label }, link.key)))] }));
74
96
  }
@@ -1,6 +1,6 @@
1
1
  import type { RowActionClientAction } from "@cosmicdrift/kumiko-framework/ui-types";
2
- import type { Translate } from "@cosmicdrift/kumiko-headless";
3
2
  import { type ReactNode } from "react";
3
+ import type { Translate } from "../headless/index.ts";
4
4
  export type ClientActionOutcome = {
5
5
  readonly ok: true;
6
6
  }
@@ -16,7 +16,7 @@ export type ActionNotice = {
16
16
  readonly text: string;
17
17
  };
18
18
  /** Shows the outcome of a client action. The platform layer provides it
19
- * (renderer-web: a toast); without one a failure is thrown to the action
19
+ * (renderer/web: a toast); without one a failure is thrown to the action
20
20
  * host's own error surface and a success stays silent. */
21
21
  export type ActionNotifier = (notice: ActionNotice) => void;
22
22
  export type ClientActionRuntime = {
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  // Column-Renderer-Map: client-side Lookup für ListColumn-Spalten die im
3
3
  // Schema einen PlatformComponent-Renderer (`{ react: { __component: "Name" } }`)
4
- // statt einer String-Funktion angeben. createKumikoApp im renderer-web sammelt
4
+ // statt einer String-Funktion angeben. createKumikoApp im renderer/web sammelt
5
5
  // alle clientFeatures.columnRenderers und mountet den Provider; der DataTable-
6
6
  // Cell-Renderer schlägt den Component über `useColumnRenderer(name)` nach.
7
7
  //
@@ -12,8 +12,8 @@
12
12
  // zukünftiger Boot-Validator die schema.entities-Map cross-referenziert,
13
13
  // brechen die Type-Lies hier silent. Dann ist Zeit für eine echte
14
14
  // RenderConfigEdit-Komponente die direkt fields nimmt.
15
- import { I18N_KEY_PARAM } from "@cosmicdrift/kumiko-headless";
16
15
  import * as z from "zod";
16
+ import { I18N_KEY_PARAM } from "../headless/index.js";
17
17
  const CONFIG_EDIT_PSEUDO_ENTITY = "__config-edit__";
18
18
  /** Baut eine minimale EntityDefinition aus den Inline-Fields des
19
19
  * ConfigEdit-Screens. RenderEdit + computeEditViewModel iterieren
@@ -1,11 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- // Read-only render of a content editor's format with the collection's
3
- // example variableSchema values substituted in for `{{name}}` — reuses the
4
- // same registered editor the collection edits with (readOnly), so "rich"
5
- // renders formatted HTML and "plain"/"markdown" render as text through the
6
- // exact same component, no separate render path per format.
7
- import { escapeHtmlAttr } from "@cosmicdrift/kumiko-headless";
8
2
  import { useId } from "react";
3
+ import { escapeHtmlAttr } from "../headless/index.js";
9
4
  import { useContentEditor } from "./content-editors.js";
10
5
  const VARIABLE_PATTERN = /\{\{\s*(\w+)\s*\}\}/g;
11
6
  const noop = () => { };
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  // Custom-Screen-Components-Map: client-side Lookup für Screens vom Typ
3
3
  // `custom`. KumikoScreen schaut hier nach `screen.id` (oder qn) und
4
- // rendert die passende Component. createKumikoApp im renderer-web sammelt
4
+ // rendert die passende Component. createKumikoApp im renderer/web sammelt
5
5
  // alle clientFeatures.components und mountet den Provider; Tests die
6
6
  // einzelne Custom-Screens prüfen wollen, mounten den Provider direkt.
7
7
  import { createContext, useContext } from "react";
@@ -1,6 +1,6 @@
1
1
  import type { DashboardScreenDefinition } from "@cosmicdrift/kumiko-framework/ui-types";
2
- import type { Translate } from "@cosmicdrift/kumiko-headless";
3
2
  import { type ComponentType, type ReactNode } from "react";
3
+ import type { Translate } from "../headless/index.ts";
4
4
  export type DashboardBodyProps = {
5
5
  readonly featureName: string;
6
6
  readonly screen: DashboardScreenDefinition;
@@ -1,6 +1,6 @@
1
1
  import type { RowActionDrawer } from "@cosmicdrift/kumiko-framework/ui-types";
2
- import type { EditRelatedListSectionViewModel, ListRowViewModel, Translate } from "@cosmicdrift/kumiko-headless";
3
2
  import { type ReactNode } from "react";
3
+ import type { EditRelatedListSectionViewModel, ListRowViewModel, Translate } from "../headless/index.ts";
4
4
  export declare function EntityListExpandedRow({ section, row, featureName, translate, expansionNonce, openDrawer, onAfterWrite, onSubListInvalidated, }: {
5
5
  readonly section: EditRelatedListSectionViewModel;
6
6
  readonly row: ListRowViewModel;
@@ -1,6 +1,6 @@
1
1
  import type { EntityDefinition, EntityEditScreenDefinition } from "@cosmicdrift/kumiko-framework/ui-types";
2
- import { type EditFormMode } from "@cosmicdrift/kumiko-headless";
3
2
  import * as z from "zod";
3
+ import { type EditFormMode } from "../headless/index.ts";
4
4
  export declare function isPresent(value: unknown): boolean;
5
5
  export declare const REQUIRED_FIELD_I18N_KEY = "kumiko.validation.required";
6
6
  export declare const OPTION_NOT_AVAILABLE_I18N_KEY = "kumiko.validation.optionNotAvailable";
@@ -1,6 +1,6 @@
1
1
  import { evalFieldCondition, findUnavailableSelectOptions, isUnchangedValue, NO_WIDGET_FIELD_TYPES, } from "@cosmicdrift/kumiko-framework/ui-types";
2
- import { I18N_KEY_PARAM } from "@cosmicdrift/kumiko-headless";
3
2
  import * as z from "zod";
3
+ import { I18N_KEY_PARAM } from "../headless/index.js";
4
4
  import { layoutEditFields } from "./layout-fields.js";
5
5
  // `required` means "has a value", not "is truthy" — `false` and `0` count
6
6
  // as present, only the actually-empty representations don't.
@@ -103,7 +103,7 @@ export function buildFormSchema(entity, screen, verb, unchangedFrom) {
103
103
  code: "custom",
104
104
  path: [spec.field],
105
105
  message: `"${spec.field}" is required.`,
106
- // I18N_KEY_PARAM override, see packages/headless/src/form/zod-bridge.ts.
106
+ // I18N_KEY_PARAM override, see packages/renderer/src/headless/form/zod-bridge.ts.
107
107
  params: { [I18N_KEY_PARAM]: REQUIRED_FIELD_I18N_KEY },
108
108
  });
109
109
  }
@@ -1,6 +1,6 @@
1
1
  import type { ScreenDefinition } from "@cosmicdrift/kumiko-framework/ui-types";
2
- import type { FormValues, ListRowViewModel, Translate } from "@cosmicdrift/kumiko-headless";
3
2
  import { type ReactNode } from "react";
3
+ import type { FormValues, ListRowViewModel, Translate } from "../headless/index.ts";
4
4
  import { type ListSort } from "../hooks/use-list-url-state.ts";
5
5
  import type { FeatureSchema } from "./feature-schema.ts";
6
6
  import { qualifyScreenId } from "./qualify-screen-id.ts";
@@ -1,11 +1,11 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { evalFieldCondition, isRecordLocked, isWriteFormEditSection, metricField, parseRefTarget, } from "@cosmicdrift/kumiko-framework/ui-types";
3
- import { applyFormatSpec, buildOptionLabels, computeRelatedListSectionViewModel, fieldLabelKey, fieldOptionLabelKey, isSafeHref, } from "@cosmicdrift/kumiko-headless";
4
3
  import { resolveActionIcon } from "@cosmicdrift/kumiko-types/action-icon";
5
4
  import { TENANT_CURRENCY_CONFIG_KEY } from "@cosmicdrift/kumiko-types/fields";
6
5
  import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
7
6
  import { isPlainObject, propertyOf } from "@cosmicdrift/kumiko-types/type-guards";
8
7
  import { Fragment, useCallback, useEffect, useMemo, useRef, useState } from "react";
8
+ import { withDerivedValues } from "../components/form-derivation-patch.js";
9
9
  import { QueryOptionLabel, resolveOptionsQueryPayload, } from "../components/query-options-select.js";
10
10
  import { extractCreatedId, extractIdField } from "../components/reference-create-dialog.js";
11
11
  import { RenderEdit, resolveRecordTitle, } from "../components/render-edit.js";
@@ -14,6 +14,7 @@ import { useDispatcher, useOptionalDispatcher } from "../context/dispatcher-cont
14
14
  import { useIsEmbeddedScreen } from "../context/embedded-screen-context.js";
15
15
  import { useUserRoles } from "../context/user-roles-context.js";
16
16
  import { useOptionalCurrentUser } from "../current-user.js";
17
+ import { applyFormatSpec, buildOptionLabels, computeRelatedListSectionViewModel, fieldLabelKey, fieldOptionLabelKey, isSafeHref, } from "../headless/index.js";
17
18
  import { REFERENCE_LIST_LOOKUP_LIMIT } from "../hooks/reference-limits.js";
18
19
  import { PAGE_SIZE_OPTIONS, useListUrlState } from "../hooks/use-list-url-state.js";
19
20
  import { useQuery } from "../hooks/use-query.js";
@@ -24,7 +25,7 @@ import { PageHeaderSlotAvailableProvider, usePageHeaderCompact, usePageHeaderSlo
24
25
  import { statusToneForOptionTone, statusToneForValue, usePrimitives, } from "../primitives.js";
25
26
  import { screenFillsHeight } from "../screen-fills-height.js";
26
27
  import { actionFormSubmittableFields, synthesizeActionFormEntity, synthesizeActionFormScreen, } from "./action-form-shim.js";
27
- import { ActionFormLoadStatus, ActionFormSuccessBanner, isSecretFormField, resolveActionFormRecordId, useActionFormLoad, } from "./action-form-support.js";
28
+ import { ActionFormLoadStatus, ActionFormSuccessBanner, isSecretFormField, resolveActionFormRecordId, resolveSuccessFacts, useActionFormLoad, } from "./action-form-support.js";
28
29
  import { useAppFeatures } from "./app-features-context.js";
29
30
  import { useClientActionRuntime } from "./client-actions.js";
30
31
  import { buildConfigEditSchema, synthesizeConfigEditEntity, synthesizeConfigEditScreen, } from "./config-edit-shim.js";
@@ -190,12 +191,12 @@ function renderScreenBody({ schema, screen, translate, entityId, onRowClick, onC
190
191
  }
191
192
  // Injection-Body für dashboard-Screens: die Panel-Implementierung (StatCard,
192
193
  // Charts) ist plattform-spezifisch und kommt aus dem DashboardBody-Context
193
- // (renderer-web registriert die Web-Variante in createKumikoApp).
194
+ // (renderer/web registriert die Web-Variante in createKumikoApp).
194
195
  function DashboardScreenBody({ featureName, screen, translate, }) {
195
196
  const { Banner, Text } = usePrimitives();
196
197
  const Body = useDashboardBody();
197
198
  if (Body === undefined) {
198
- return (_jsxs(Banner, { padded: true, variant: "info", testId: "kumiko-screen-dashboard-placeholder", children: ["Dashboard screen ", _jsx(Text, { variant: "code", children: screen.id }), " \u2014 kein Dashboard-Body registriert (createKumikoApp aus ", _jsx(Text, { variant: "code", children: "kumiko-renderer-web" }), " wired ihn automatisch)."] }));
199
+ return (_jsxs(Banner, { padded: true, variant: "info", testId: "kumiko-screen-dashboard-placeholder", children: ["Dashboard screen ", _jsx(Text, { variant: "code", children: screen.id }), " \u2014 no dashboard body registered (createKumikoApp from ", _jsx(Text, { variant: "code", children: "kumiko-renderer/web" }), " wires it automatically)."] }));
199
200
  }
200
201
  return (_jsx(Body, { featureName: featureName, screen: screen, ...(translate !== undefined && { translate }) }));
201
202
  }
@@ -1448,7 +1449,7 @@ function EntityListBody({ schema, screen, entity, translate, onRowClick, }) {
1448
1449
  const runNavigate = useCallback((action, row) => {
1449
1450
  if (action.entity !== undefined) {
1450
1451
  // Entity-Targets (fw#2228) lösen sich erst in der NavApi-Impl gegen
1451
- // ALLE Features auf (resolveTarget in renderer-web/nav.tsx) — dieses
1452
+ // ALLE Features auf (resolveTarget in renderer/web/nav.tsx) — dieses
1452
1453
  // Package kennt nur `schema` (das eine aufrufende Feature) und kann
1453
1454
  // detailFor cross-feature nicht selbst nachschlagen.
1454
1455
  const explicit = action.entityId !== undefined ? String(row.values[action.entityId] ?? "") : undefined;
@@ -2549,6 +2550,7 @@ function ActionFormBody({ schema, screen, translate, entityId, initialOverrides,
2549
2550
  handoffValues,
2550
2551
  loadedValues,
2551
2552
  ]);
2553
+ const derivedInitial = useMemo(() => withDerivedValues(initial, screen.derive !== undefined ? screen : undefined), [initial, screen]);
2552
2554
  const t = useTranslation();
2553
2555
  const effectiveTranslate = translate ?? t;
2554
2556
  const summary = useMemo(() => resolveActionFormSummary(screen.summary, initialOverrides, effectiveTranslate, locale), [screen.summary, initialOverrides, effectiveTranslate, locale]);
@@ -2573,13 +2575,14 @@ function ActionFormBody({ schema, screen, translate, entityId, initialOverrides,
2573
2575
  return;
2574
2576
  }
2575
2577
  if (screen.redirect === undefined) {
2576
- const hasSuccessLinks = (screen.successLinks?.length ?? 0) > 0;
2578
+ const hasSuccessLinks = (screen.successLinks?.length ?? 0) > 0 || (screen.successFacts?.length ?? 0) > 0;
2577
2579
  const publish = (text) => {
2578
2580
  if (successSequence.current !== sequence)
2579
2581
  return;
2580
2582
  setSuccess({
2581
2583
  text,
2582
2584
  links: resolveSuccessLinks(screen.successLinks, result.data, schema, appFeatures, nav, effectiveTranslate),
2585
+ facts: resolveSuccessFacts(screen.successFacts, result.data, effectiveTranslate, locale),
2583
2586
  });
2584
2587
  };
2585
2588
  const messageKey = screen.successMessage;
@@ -2649,7 +2652,7 @@ function ActionFormBody({ schema, screen, translate, entityId, initialOverrides,
2649
2652
  if (loadState !== undefined && loadState.status !== "ready") {
2650
2653
  return (_jsx(ActionFormLoadStatus, { state: loadState, screenId: screen.id, translate: effectiveTranslate }));
2651
2654
  }
2652
- return (_jsx(RenderEdit, { screen: synthScreen, entity: synthEntity, featureName: schema.featureName, initial: initial,
2655
+ return (_jsx(RenderEdit, { screen: synthScreen, entity: synthEntity, featureName: schema.featureName, initial: derivedInitial, ...(screen.derive !== undefined && { formDerivation: screen }),
2653
2656
  // Extension-Sections im actionForm sehen die initialen Form-Values
2654
2657
  // (inkl. searchParams-Prefill, z.B. ?incidentId=…) als initialValues
2655
2658
  // — anders als im entityEdit gibt es hier keinen record, aus dem
@@ -1,6 +1,6 @@
1
1
  import type { ListEmptyStateSpec } from "@cosmicdrift/kumiko-framework/ui-types";
2
- import type { Translate } from "@cosmicdrift/kumiko-headless";
3
2
  import type { ListEmptyStateContent } from "../components/list-empty-state.tsx";
3
+ import type { Translate } from "../headless/index.ts";
4
4
  import { buildRecordActions } from "./row-actions.ts";
5
5
  type ActionBindings = Pick<Parameters<typeof buildRecordActions>[0], "nav" | "host" | "dispatcher" | "openDrawer" | "onWriteSuccess" | "clientActions">;
6
6
  export declare function useListEmptyContent(spec: ListEmptyStateSpec | undefined, translate: Translate, bindings: ActionBindings): ListEmptyStateContent | undefined;
@@ -1,5 +1,5 @@
1
1
  import type { EntityListFacetConfig, ListFacetSpec } from "@cosmicdrift/kumiko-framework/ui-types";
2
- import type { Translate } from "@cosmicdrift/kumiko-headless";
2
+ import type { Translate } from "../headless/index.ts";
3
3
  import type { DataTableFacet, DataTableFacetChip } from "../primitives.tsx";
4
4
  export type ResolvedFacetSpec = {
5
5
  readonly field: string;
package/dist/app/nav.js CHANGED
@@ -76,7 +76,7 @@ export function hasDetailScreen(features, entity) {
76
76
  }
77
77
  // Resolves a NavTarget to the ScreenTarget form navigate/replace/hrefFor
78
78
  // operate on. Pure — no context, no I/O — so callers can use it outside
79
- // React too (see resolve-at-NavApi-build alternative in renderer-web).
79
+ // React too (see resolve-at-NavApi-build alternative in renderer/web).
80
80
  export function resolveTarget(features, target) {
81
81
  if ("screenId" in target)
82
82
  return target;
@@ -151,7 +151,7 @@ export function useOptionalNav() {
151
151
  export function useNav() {
152
152
  const api = useContext(NavContext);
153
153
  if (api === undefined) {
154
- throw new Error("useNav: no <NavProvider> mounted above this component. Plattform-Packages (z.B. @cosmicdrift/kumiko-renderer-web) liefern eine Default-Impl über createKumikoApp.");
154
+ throw new Error("useNav: no <NavProvider> mounted above this component. Plattform-Packages (z.B. @cosmicdrift/kumiko-renderer/web) liefern eine Default-Impl über createKumikoApp.");
155
155
  }
156
156
  return api;
157
157
  }
@@ -1,5 +1,5 @@
1
- import type { DispatcherError, Translate } from "@cosmicdrift/kumiko-headless";
2
1
  import type { ReactNode } from "react";
2
+ import type { DispatcherError, Translate } from "../headless/index.ts";
3
3
  export declare function QueryLoadingBanner(): ReactNode;
4
4
  export declare function QueryErrorBanner({ error, translate, onRetry, }: {
5
5
  readonly error: DispatcherError;
@@ -1,4 +1,4 @@
1
- import type { CellLink } from "@cosmicdrift/kumiko-headless";
1
+ import type { CellLink } from "../headless/index.ts";
2
2
  /** Link to a referenced record's detail screen, or undefined when there is no
3
3
  * navigation, the user may not open that screen, or no detail screen exists. */
4
4
  export type ReferenceLinkResolver = (refEntity: string, id: string) => CellLink | undefined;
@@ -1,7 +1,7 @@
1
1
  import type { EntityEditScreenDefinition, RelatedListToolbarAction, RowAction, RowActionClientAction, RowActionDrawer, RowActionNavigate, RowActionWriteHandler, RowFieldExtractor, ToolbarAction } from "@cosmicdrift/kumiko-framework/ui-types";
2
- import type { Dispatcher, ListRowViewModel, Translate } from "@cosmicdrift/kumiko-headless";
3
2
  import type { RenderEditAction } from "../components/render-edit-types.ts";
4
3
  import type { ToolbarActionButton } from "../components/render-list.tsx";
4
+ import type { Dispatcher, ListRowViewModel, Translate } from "../headless/index.ts";
5
5
  import type { DataTableRowAction } from "../primitives.tsx";
6
6
  import { type ClientActionRuntime } from "./client-actions.tsx";
7
7
  import type { NavApi } from "./nav.tsx";
@@ -1,6 +1,6 @@
1
1
  import type { SecretMintScreenDefinition } from "@cosmicdrift/kumiko-framework/ui-types";
2
- import type { Translate } from "@cosmicdrift/kumiko-headless";
3
2
  import { type ReactNode } from "react";
3
+ import type { Translate } from "../headless/index.ts";
4
4
  import type { FeatureSchema } from "./feature-schema.ts";
5
5
  export type SecretMintBodyProps = {
6
6
  readonly schema: FeatureSchema;
@@ -1,6 +1,6 @@
1
1
  import type { SecretsEditScreenDefinition } from "@cosmicdrift/kumiko-framework/ui-types";
2
- import type { Translate } from "@cosmicdrift/kumiko-headless";
3
2
  import { type ReactNode } from "react";
3
+ import type { Translate } from "../headless/index.ts";
4
4
  export type SecretsEditBodyProps = {
5
5
  readonly screen: SecretsEditScreenDefinition;
6
6
  readonly translate?: Translate;
@@ -1,6 +1,6 @@
1
1
  import type { RowAction } from "@cosmicdrift/kumiko-framework/ui-types";
2
- import type { Translate } from "@cosmicdrift/kumiko-headless";
3
2
  import type { RenderEditAction } from "../components/render-edit-types.ts";
3
+ import type { Translate } from "../headless/index.ts";
4
4
  /** Header actions on a record shown by a screen that has no drawer host
5
5
  * (dashboards): writeHandler, navigate and clientAction, `onWriteSuccess` after a success. */
6
6
  export declare function useRecordActions(options: {
@@ -1,4 +1,4 @@
1
- import type { DispatcherError } from "@cosmicdrift/kumiko-headless";
1
+ import type { DispatcherError } from "../headless/index.ts";
2
2
  export declare class WriteFailedError extends Error {
3
3
  readonly dispatcherError: DispatcherError;
4
4
  constructor(error: DispatcherError, message: string);
@@ -1,6 +1,6 @@
1
- import type { EditFieldViewModel } from "@cosmicdrift/kumiko-headless";
2
1
  import type { OptionsQueryPayload } from "@cosmicdrift/kumiko-types/fields";
3
2
  import { type ReactNode } from "react";
3
+ import type { EditFieldViewModel } from "../headless/index.ts";
4
4
  export type SelectOptionEntry = {
5
5
  readonly value: string;
6
6
  readonly label: string;
@@ -1,5 +1,5 @@
1
- import type { EditFieldViewModel, FieldIssue } from "@cosmicdrift/kumiko-headless";
2
1
  import { type ReactNode } from "react";
2
+ import type { EditFieldViewModel, FieldIssue } from "../headless/index.ts";
3
3
  export type EmbeddedListFieldProps = {
4
4
  readonly field: EditFieldViewModel;
5
5
  readonly id: string;
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { computeDerivedCellValue, currencyDecimals, groupEmbeddedListIssues, roundDerivedCellValue, sumEmbeddedListColumn, } from "@cosmicdrift/kumiko-headless";
3
2
  import { useState } from "react";
3
+ import { computeDerivedCellValue, currencyDecimals, groupEmbeddedListIssues, roundDerivedCellValue, sumEmbeddedListColumn, } from "../headless/index.js";
4
4
  import { REFERENCE_COMBOBOX_LIMIT } from "../hooks/reference-limits.js";
5
5
  import { useQuery } from "../hooks/use-query.js";
6
6
  import { referenceOptionSource } from "../hooks/use-reference-lookup.js";
@@ -1,5 +1,5 @@
1
- import type { EditFieldViewModel } from "@cosmicdrift/kumiko-headless";
2
1
  import type { ReactNode } from "react";
2
+ import type { EditFieldViewModel } from "../headless/index.ts";
3
3
  export type FileListFieldProps = {
4
4
  readonly field: EditFieldViewModel;
5
5
  readonly id: string;
@@ -0,0 +1,8 @@
1
+ import type { FormDerivationScreen } from "@cosmicdrift/kumiko-framework/ui-types";
2
+ /** The derived values that differ from the current form values, or undefined
3
+ * when everything is already up to date. A derived value that no longer
4
+ * resolves is reported as `undefined`. */
5
+ export declare function changedDerivedValues(values: unknown, screen: FormDerivationScreen): Record<string, unknown> | undefined;
6
+ /** `values` with every derived field already resolved, so the form's baseline
7
+ * matches what the live recomputation would produce and starts out clean. */
8
+ export declare function withDerivedValues<TValues extends Record<string, unknown>>(values: TValues, screen: FormDerivationScreen | undefined): TValues;
@@ -0,0 +1,24 @@
1
+ import { applyFormDerivations, isUnchangedValue } from "@cosmicdrift/kumiko-framework/ui-types";
2
+ import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
3
+ /** The derived values that differ from the current form values, or undefined
4
+ * when everything is already up to date. A derived value that no longer
5
+ * resolves is reported as `undefined`. */
6
+ export function changedDerivedValues(values, screen) {
7
+ const next = applyFormDerivations(values, screen);
8
+ if (!isPlainObject(values) || !isPlainObject(next))
9
+ return undefined;
10
+ const patch = {};
11
+ for (const target of Object.keys(screen.derive ?? {})) {
12
+ if (!isUnchangedValue(values[target], next[target]))
13
+ patch[target] = next[target];
14
+ }
15
+ return Object.keys(patch).length === 0 ? undefined : patch;
16
+ }
17
+ /** `values` with every derived field already resolved, so the form's baseline
18
+ * matches what the live recomputation would produce and starts out clean. */
19
+ export function withDerivedValues(values, screen) {
20
+ if (screen === undefined)
21
+ return values;
22
+ const patch = changedDerivedValues(values, screen);
23
+ return patch === undefined ? values : { ...values, ...patch };
24
+ }
@@ -0,0 +1,13 @@
1
+ import type { ReactNode } from "react";
2
+ import { type FormWidth } from "../primitives.tsx";
3
+ export type FormScreenLayoutProps = {
4
+ readonly children: ReactNode;
5
+ readonly description?: ReactNode;
6
+ readonly actions?: ReactNode;
7
+ readonly secondaryActions?: ReactNode;
8
+ readonly onSubmit?: () => void;
9
+ readonly width?: FormWidth;
10
+ readonly testId?: string;
11
+ };
12
+ /** For custom screens: the standard form screen layout; fill it with `Section` (title, icon, subtitle). */
13
+ export declare function FormScreenLayout({ children, description, actions, secondaryActions, onSubmit, width, testId, }: FormScreenLayoutProps): ReactNode;
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { usePrimitives } from "../primitives.js";
3
+ const FORM_SCREEN_LAYOUT_PROPS = {
4
+ screenForm: true,
5
+ fillHeight: true,
6
+ stickyActions: true,
7
+ };
8
+ const NOOP = () => { };
9
+ /** For custom screens: the standard form screen layout; fill it with `Section` (title, icon, subtitle). */
10
+ export function FormScreenLayout({ children, description, actions, secondaryActions, onSubmit = NOOP, width, testId, }) {
11
+ const { Form } = usePrimitives();
12
+ return (_jsx(Form, { onSubmit: onSubmit, ...FORM_SCREEN_LAYOUT_PROPS, ...(description !== undefined && { subtitle: description }), ...(actions !== undefined && { actions }), ...(secondaryActions !== undefined && { secondaryActions }), ...(width !== undefined && { width }), ...(testId !== undefined && { testId }), children: children }));
13
+ }
@@ -1,5 +1,5 @@
1
- import type { EditFieldViewModel, FieldIssue } from "@cosmicdrift/kumiko-headless";
2
1
  import type { ReactNode } from "react";
2
+ import type { EditFieldViewModel, FieldIssue } from "../headless/index.ts";
3
3
  import type { FieldCellWidth, FieldProps, usePrimitives } from "../primitives.tsx";
4
4
  export type GridCellForFieldProps = {
5
5
  readonly field: EditFieldViewModel;
@@ -1,5 +1,5 @@
1
- import type { EditFieldViewModel } from "@cosmicdrift/kumiko-headless";
2
1
  import type { ReactNode } from "react";
2
+ import type { EditFieldViewModel } from "../headless/index.ts";
3
3
  export type MultiSelectCheckboxOption = {
4
4
  readonly value: string;
5
5
  readonly label: string;
@@ -5,7 +5,7 @@ import { usePrimitives } from "../primitives.js";
5
5
  // as a visible checkbox plus a select-all toggle, built purely from the
6
6
  // platform-neutral Primitives contract (Grid/GridCell/Field/Input kind
7
7
  // "boolean", the same primitive `case "boolean"` uses in render-field.tsx).
8
- // No renderer-web import here — this file must stay usable from Expo too.
8
+ // No renderer/web import here — this file must stay usable from Expo too.
9
9
  export function MultiSelectCheckboxes({ field, id, options, value, onChange, }) {
10
10
  const { Grid, GridCell, Field, Input, Button } = usePrimitives();
11
11
  const t = useTranslation();
@@ -1,6 +1,6 @@
1
- import type { EditFieldViewModel } from "@cosmicdrift/kumiko-headless";
2
1
  import { type OptionsQueryPayload } from "@cosmicdrift/kumiko-types/fields";
3
2
  import { type ReactNode } from "react";
3
+ import type { EditFieldViewModel } from "../headless/index.ts";
4
4
  type ResolvedOptionsQueryPayload = Readonly<Record<string, string | number | boolean>>;
5
5
  export declare function resolveOptionsQueryPayload(payload: OptionsQueryPayload, row: Readonly<Record<string, unknown>>): ResolvedOptionsQueryPayload;
6
6
  type QueryOptionsSelectProps = {
@@ -1,6 +1,6 @@
1
1
  import type { RowActionDrawer } from "@cosmicdrift/kumiko-framework/ui-types";
2
- import type { EditRelatedListSectionViewModel, Translate } from "@cosmicdrift/kumiko-headless";
3
2
  import { type ReactNode } from "react";
3
+ import type { EditRelatedListSectionViewModel, Translate } from "../headless/index.ts";
4
4
  export declare function RelatedListSection({ section, parentId, record, featureName, translate, hideTitle, grow, onOpenDrawer, actions, embedded, onAfterWrite, refreshToken, }: {
5
5
  readonly section: EditRelatedListSectionViewModel;
6
6
  readonly parentId: string;
@@ -1,4 +1,4 @@
1
- import type { DispatcherError, EditFieldViewModel, EditSectionViewModel, SubmitResult } from "@cosmicdrift/kumiko-headless";
1
+ import type { DispatcherError, EditFieldViewModel, EditSectionViewModel, SubmitResult } from "../headless/index.ts";
2
2
  export declare function hasEditableSection(sections: readonly EditSectionViewModel[]): boolean;
3
3
  export declare function resolveExtensionEntityId(entityIdProp: string | null | undefined, vmId: string | null): string | null;
4
4
  export declare function shouldNotifyCaller(result: SubmitResult<unknown>, extensionsPersisted: boolean): boolean;
@@ -1,7 +1,7 @@
1
- import type { ActionFormFooterAction, EntityDefinition, EntityEditScreenDefinition, IconKey, RowAction, RowActionDrawer } from "@cosmicdrift/kumiko-framework/ui-types";
2
- import type { DispatcherError, FormSnapshot, FormValues, SubmitResult, Translate } from "@cosmicdrift/kumiko-headless";
1
+ import type { ActionFormFooterAction, EntityDefinition, EntityEditScreenDefinition, FormDerivationScreen, IconKey, RowAction, RowActionDrawer } from "@cosmicdrift/kumiko-framework/ui-types";
3
2
  import type { ReactNode } from "react";
4
3
  import type * as z from "zod";
4
+ import type { DispatcherError, FormSnapshot, FormValues, SubmitResult, Translate } from "../headless/index.ts";
5
5
  export type RenderEditProps<TValues extends FormValues, TCtx = unknown> = {
6
6
  readonly screen: EntityEditScreenDefinition;
7
7
  /** Screen id used for the `screen:<id>.title`/`.subtitle` lookups and as the
@@ -59,7 +59,7 @@ export type RenderEditProps<TValues extends FormValues, TCtx = unknown> = {
59
59
  /** Copy-link action (issue #912) — only set in update mode (create mode
60
60
  * has no entity id yet, hence no permalink). The callback is already fully
61
61
  * bound (URL building + clipboard happen outside, in
62
- * `@cosmicdrift/kumiko-renderer-web`'s RoutedScreen — this platform-neutral
62
+ * `@cosmicdrift/kumiko-renderer/web`'s RoutedScreen — this platform-neutral
63
63
  * package must not touch `navigator`/`window`, see
64
64
  * guard-renderer-boundaries). undefined = no button. */
65
65
  readonly onCopyLink?: () => Promise<void> | void;
@@ -204,6 +204,9 @@ export type RenderEditProps<TValues extends FormValues, TCtx = unknown> = {
204
204
  * `disabled`, which locks the whole form. For a gate the host owns, e.g.
205
205
  * an acknowledgement checkbox in `leadContent`. */
206
206
  readonly submitBlocked?: boolean;
207
+ /** actionForm `derive`: derived fields are recomputed into the form state on every
208
+ * change and render read-only. */
209
+ readonly formDerivation?: FormDerivationScreen;
207
210
  /** Show the unsaved-changes footer (count, Discard, "Save changes") even
208
211
  * without an entity id or a screen-height form — for hosts that edit an
209
212
  * existing server-side record through `customSubmit` (configEdit, also when
@@ -1,4 +1,4 @@
1
- import type { FormValues } from "@cosmicdrift/kumiko-headless";
1
+ import type { FormValues } from "../headless/index.ts";
2
2
  import type { RenderEditProps } from "./render-edit-types.ts";
3
3
  export type { RenderEditAction, RenderEditChangeState, RenderEditControls, RenderEditProps, } from "./render-edit-types.ts";
4
4
  import { type ReactNode } from "react";