@cosmicdrift/kumiko-renderer 0.374.0 → 0.377.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 (455) 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 +7 -6
  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/grid-cell-for-field.d.ts +1 -1
  30. package/dist/components/multi-select-checkboxes.d.ts +1 -1
  31. package/dist/components/multi-select-checkboxes.js +1 -1
  32. package/dist/components/query-options-select.d.ts +1 -1
  33. package/dist/components/related-list-section.d.ts +1 -1
  34. package/dist/components/render-edit-logic.d.ts +1 -1
  35. package/dist/components/render-edit-types.d.ts +2 -2
  36. package/dist/components/render-edit.d.ts +1 -1
  37. package/dist/components/render-edit.js +4 -2
  38. package/dist/components/render-field.d.ts +1 -1
  39. package/dist/components/render-field.js +4 -1
  40. package/dist/components/render-list.d.ts +1 -1
  41. package/dist/components/render-list.js +20 -4
  42. package/dist/components/write-form-section.d.ts +1 -1
  43. package/dist/components/write-form-section.js +1 -1
  44. package/dist/context/dispatcher-context.d.ts +1 -1
  45. package/dist/format-when.js +1 -1
  46. package/dist/headless/apex/css.d.ts +3 -0
  47. package/dist/headless/apex/css.js +298 -0
  48. package/dist/headless/apex/index.d.ts +236 -0
  49. package/dist/headless/apex/index.js +377 -0
  50. package/dist/headless/apex/lightbox.d.ts +4 -0
  51. package/dist/headless/apex/lightbox.js +81 -0
  52. package/dist/headless/contracts/asset.d.ts +15 -0
  53. package/dist/headless/contracts/asset.js +17 -0
  54. package/dist/headless/contracts/index.d.ts +3 -0
  55. package/dist/headless/contracts/index.js +1 -0
  56. package/dist/headless/contracts/locale.d.ts +7 -0
  57. package/dist/headless/contracts/locale.js +11 -0
  58. package/dist/headless/contracts/primitives.d.ts +93 -0
  59. package/dist/headless/contracts/primitives.js +21 -0
  60. package/dist/headless/dispatcher/index.d.ts +2 -0
  61. package/dist/headless/dispatcher/index.js +1 -0
  62. package/dist/headless/dispatcher/types.d.ts +86 -0
  63. package/dist/headless/dispatcher/types.js +34 -0
  64. package/dist/headless/form/form-controller.d.ts +2 -0
  65. package/dist/headless/form/form-controller.js +409 -0
  66. package/dist/headless/form/index.d.ts +3 -0
  67. package/dist/headless/form/index.js +2 -0
  68. package/dist/headless/form/types.d.ts +76 -0
  69. package/dist/headless/form/types.js +1 -0
  70. package/dist/headless/form/zod-bridge.d.ts +10 -0
  71. package/dist/headless/form/zod-bridge.js +103 -0
  72. package/dist/headless/format/document-values.d.ts +12 -0
  73. package/dist/headless/format/document-values.js +70 -0
  74. package/dist/headless/format/escape.d.ts +5 -0
  75. package/dist/headless/format/escape.js +75 -0
  76. package/dist/headless/format/html-template.d.ts +9 -0
  77. package/dist/headless/format/html-template.js +39 -0
  78. package/dist/headless/format/index.d.ts +12 -0
  79. package/dist/headless/format/index.js +237 -0
  80. package/dist/headless/format/money.d.ts +3 -0
  81. package/dist/headless/format/money.js +39 -0
  82. package/dist/headless/index.d.ts +14 -0
  83. package/dist/headless/index.js +9 -0
  84. package/dist/headless/locale-routing/index.d.ts +41 -0
  85. package/dist/headless/locale-routing/index.js +145 -0
  86. package/dist/headless/nav/index.d.ts +2 -0
  87. package/dist/headless/nav/index.js +1 -0
  88. package/dist/headless/nav/resolve.d.ts +2 -0
  89. package/dist/headless/nav/resolve.js +71 -0
  90. package/dist/headless/nav/types.d.ts +26 -0
  91. package/dist/headless/nav/types.js +1 -0
  92. package/dist/headless/store/create-store.d.ts +2 -0
  93. package/dist/headless/store/create-store.js +43 -0
  94. package/dist/headless/store/equality.d.ts +1 -0
  95. package/dist/headless/store/equality.js +34 -0
  96. package/dist/headless/store/index.d.ts +3 -0
  97. package/dist/headless/store/index.js +2 -0
  98. package/dist/headless/store/types.d.ts +7 -0
  99. package/dist/headless/store/types.js +10 -0
  100. package/dist/headless/view-model/edit.d.ts +18 -0
  101. package/dist/headless/view-model/edit.js +501 -0
  102. package/dist/headless/view-model/embedded-list.d.ts +27 -0
  103. package/dist/headless/view-model/embedded-list.js +63 -0
  104. package/dist/headless/view-model/index.d.ts +7 -0
  105. package/dist/headless/view-model/index.js +3 -0
  106. package/dist/headless/view-model/list-file-display.d.ts +3 -0
  107. package/dist/headless/view-model/list-file-display.js +27 -0
  108. package/dist/headless/view-model/list.d.ts +16 -0
  109. package/dist/headless/view-model/list.js +229 -0
  110. package/dist/headless/view-model/types.d.ts +382 -0
  111. package/dist/headless/view-model/types.js +1 -0
  112. package/dist/hooks/use-ai-text.d.ts +1 -1
  113. package/dist/hooks/use-form.d.ts +1 -1
  114. package/dist/hooks/use-form.js +1 -1
  115. package/dist/hooks/use-mutation.d.ts +1 -1
  116. package/dist/hooks/use-query.d.ts +1 -1
  117. package/dist/hooks/use-store.d.ts +1 -1
  118. package/dist/hooks/use-store.js +7 -7
  119. package/dist/hooks/use-stream-handler.d.ts +1 -1
  120. package/dist/i18n.d.ts +1 -1
  121. package/dist/i18n.js +1 -1
  122. package/dist/index.js +4 -4
  123. package/dist/live/csrf.d.ts +2 -0
  124. package/dist/live/csrf.js +60 -0
  125. package/dist/live/dispatcher-live.d.ts +7 -0
  126. package/dist/live/dispatcher-live.js +286 -0
  127. package/dist/live/envelopes.d.ts +101 -0
  128. package/dist/live/envelopes.js +35 -0
  129. package/dist/live/error-mapping.d.ts +16 -0
  130. package/dist/live/error-mapping.js +82 -0
  131. package/dist/live/index.d.ts +7 -0
  132. package/dist/live/index.js +5 -0
  133. package/dist/live/locale.d.ts +2 -0
  134. package/dist/live/locale.js +25 -0
  135. package/dist/live/sse-stream.d.ts +14 -0
  136. package/dist/live/sse-stream.js +128 -0
  137. package/dist/primitives.d.ts +35 -36
  138. package/dist/primitives.js +1 -1
  139. package/dist/session/session-ended.d.ts +1 -1
  140. package/dist/tokens.d.ts +3 -4
  141. package/dist/tokens.js +4 -5
  142. package/dist/web/app/app-schema-boot.d.ts +19 -0
  143. package/dist/web/app/app-schema-boot.js +124 -0
  144. package/dist/web/app/browser-locale.d.ts +22 -0
  145. package/dist/web/app/browser-locale.js +78 -0
  146. package/dist/web/app/client-plugin.d.ts +106 -0
  147. package/dist/web/app/client-plugin.js +12 -0
  148. package/dist/web/app/create-app.d.ts +104 -0
  149. package/dist/web/app/create-app.js +498 -0
  150. package/dist/web/app/create-public-surface.d.ts +36 -0
  151. package/dist/web/app/create-public-surface.js +40 -0
  152. package/dist/web/app/dashboard-body.d.ts +3 -0
  153. package/dist/web/app/dashboard-body.js +865 -0
  154. package/dist/web/app/dashboard-refresh.d.ts +6 -0
  155. package/dist/web/app/dashboard-refresh.js +15 -0
  156. package/dist/web/app/document-lang-sync.d.ts +4 -0
  157. package/dist/web/app/document-lang-sync.js +27 -0
  158. package/dist/web/app/draft-storage.d.ts +11 -0
  159. package/dist/web/app/draft-storage.js +53 -0
  160. package/dist/web/app/nav-providers-context.d.ts +13 -0
  161. package/dist/web/app/nav-providers-context.js +18 -0
  162. package/dist/web/app/nav.d.ts +40 -0
  163. package/dist/web/app/nav.js +231 -0
  164. package/dist/web/app/plain-content-editor.d.ts +3 -0
  165. package/dist/web/app/plain-content-editor.js +30 -0
  166. package/dist/web/app/relative-time.d.ts +10 -0
  167. package/dist/web/app/relative-time.js +56 -0
  168. package/dist/web/app/resolvers-context.d.ts +12 -0
  169. package/dist/web/app/resolvers-context.js +10 -0
  170. package/dist/web/app/rich-content-editor.d.ts +3 -0
  171. package/dist/web/app/rich-content-editor.js +15 -0
  172. package/dist/web/app/root-error-fallback.d.ts +2 -0
  173. package/dist/web/app/root-error-fallback.js +21 -0
  174. package/dist/web/app/screen-error-fallback.d.ts +6 -0
  175. package/dist/web/app/screen-error-fallback.js +17 -0
  176. package/dist/web/app/tiptap-editor.d.ts +3 -0
  177. package/dist/web/app/tiptap-editor.js +120 -0
  178. package/dist/web/app/toast-action-notifier.d.ts +5 -0
  179. package/dist/web/app/toast-action-notifier.js +17 -0
  180. package/dist/web/components/config-cascade.d.ts +13 -0
  181. package/dist/web/components/config-cascade.js +155 -0
  182. package/dist/web/components/config-source-badge.d.ts +6 -0
  183. package/dist/web/components/config-source-badge.js +55 -0
  184. package/dist/web/default-color-scheme.d.ts +2 -0
  185. package/dist/web/default-color-scheme.js +3 -0
  186. package/dist/web/icons.d.ts +94 -0
  187. package/dist/web/icons.js +100 -0
  188. package/dist/web/index.d.ts +78 -0
  189. package/dist/web/index.js +53 -0
  190. package/dist/web/layout/app-layout.d.ts +21 -0
  191. package/dist/web/layout/app-layout.js +8 -0
  192. package/dist/web/layout/avatar.d.ts +12 -0
  193. package/dist/web/layout/avatar.js +63 -0
  194. package/dist/web/layout/default-app-shell.d.ts +41 -0
  195. package/dist/web/layout/default-app-shell.js +16 -0
  196. package/dist/web/layout/editor-panel.d.ts +10 -0
  197. package/dist/web/layout/editor-panel.js +29 -0
  198. package/dist/web/layout/fill-classes.d.ts +9 -0
  199. package/dist/web/layout/fill-classes.js +15 -0
  200. package/dist/web/layout/filter-app-schema-navs.d.ts +7 -0
  201. package/dist/web/layout/filter-app-schema-navs.js +68 -0
  202. package/dist/web/layout/header-action-group.d.ts +6 -0
  203. package/dist/web/layout/header-action-group.js +8 -0
  204. package/dist/web/layout/header-overflow-menu.d.ts +4 -0
  205. package/dist/web/layout/header-overflow-menu.js +8 -0
  206. package/dist/web/layout/language-menu-items.d.ts +8 -0
  207. package/dist/web/layout/language-menu-items.js +16 -0
  208. package/dist/web/layout/language-switcher.d.ts +25 -0
  209. package/dist/web/layout/language-switcher.js +46 -0
  210. package/dist/web/layout/nav-tree.d.ts +19 -0
  211. package/dist/web/layout/nav-tree.js +536 -0
  212. package/dist/web/layout/page-header-slot.d.ts +25 -0
  213. package/dist/web/layout/page-header-slot.js +50 -0
  214. package/dist/web/layout/profile-menu.d.ts +13 -0
  215. package/dist/web/layout/profile-menu.js +6 -0
  216. package/dist/web/layout/shell-breadcrumb.d.ts +11 -0
  217. package/dist/web/layout/shell-breadcrumb.js +34 -0
  218. package/dist/web/layout/shell-header.d.ts +12 -0
  219. package/dist/web/layout/shell-header.js +159 -0
  220. package/dist/web/layout/sidebar-brand.d.ts +15 -0
  221. package/dist/web/layout/sidebar-brand.js +9 -0
  222. package/dist/web/layout/sidebar-panel.d.ts +41 -0
  223. package/dist/web/layout/sidebar-panel.js +107 -0
  224. package/dist/web/layout/sidebar-user.d.ts +8 -0
  225. package/dist/web/layout/sidebar-user.js +17 -0
  226. package/dist/web/layout/sidebar.d.ts +17 -0
  227. package/dist/web/layout/sidebar.js +11 -0
  228. package/dist/web/layout/target-resolver-stub.d.ts +13 -0
  229. package/dist/web/layout/target-resolver-stub.js +61 -0
  230. package/dist/web/layout/target-url.d.ts +12 -0
  231. package/dist/web/layout/target-url.js +77 -0
  232. package/dist/web/layout/theme-label.d.ts +15 -0
  233. package/dist/web/layout/theme-label.js +35 -0
  234. package/dist/web/layout/theme-menu-item.d.ts +12 -0
  235. package/dist/web/layout/theme-menu-item.js +16 -0
  236. package/dist/web/layout/theme-toggle.d.ts +17 -0
  237. package/dist/web/layout/theme-toggle.js +22 -0
  238. package/dist/web/layout/topbar.d.ts +8 -0
  239. package/dist/web/layout/topbar.js +4 -0
  240. package/dist/web/layout/workspace-shell.d.ts +63 -0
  241. package/dist/web/layout/workspace-shell.js +220 -0
  242. package/dist/web/layout/workspace-switcher.d.ts +15 -0
  243. package/dist/web/layout/workspace-switcher.js +36 -0
  244. package/dist/web/lib/accept-attr.d.ts +1 -0
  245. package/dist/web/lib/accept-attr.js +6 -0
  246. package/dist/web/lib/clamp.d.ts +1 -0
  247. package/dist/web/lib/clamp.js +3 -0
  248. package/dist/web/lib/cn.d.ts +6 -0
  249. package/dist/web/lib/cn.js +9 -0
  250. package/dist/web/lib/download.d.ts +2 -0
  251. package/dist/web/lib/download.js +24 -0
  252. package/dist/web/lib/file-ref-download.d.ts +15 -0
  253. package/dist/web/lib/file-ref-download.js +62 -0
  254. package/dist/web/lib/file-upload-form-data.d.ts +7 -0
  255. package/dist/web/lib/file-upload-form-data.js +11 -0
  256. package/dist/web/lib/resize-image.d.ts +1 -0
  257. package/dist/web/lib/resize-image.js +66 -0
  258. package/dist/web/lib/upload-file-ref.d.ts +9 -0
  259. package/dist/web/lib/upload-file-ref.js +29 -0
  260. package/dist/web/primitives/action-menu.d.ts +34 -0
  261. package/dist/web/primitives/action-menu.js +30 -0
  262. package/dist/web/primitives/calendar-popover.d.ts +13 -0
  263. package/dist/web/primitives/calendar-popover.js +76 -0
  264. package/dist/web/primitives/combobox.d.ts +56 -0
  265. package/dist/web/primitives/combobox.js +127 -0
  266. package/dist/web/primitives/date-field.d.ts +18 -0
  267. package/dist/web/primitives/date-field.js +74 -0
  268. package/dist/web/primitives/date-input.d.ts +1 -0
  269. package/dist/web/primitives/date-input.js +5 -0
  270. package/dist/web/primitives/date-parse.d.ts +11 -0
  271. package/dist/web/primitives/date-parse.js +159 -0
  272. package/dist/web/primitives/dialog.d.ts +3 -0
  273. package/dist/web/primitives/dialog.js +42 -0
  274. package/dist/web/primitives/drawer.d.ts +3 -0
  275. package/dist/web/primitives/drawer.js +17 -0
  276. package/dist/web/primitives/dropdown-menu.d.ts +15 -0
  277. package/dist/web/primitives/dropdown-menu.js +56 -0
  278. package/dist/web/primitives/embedded-list-input.d.ts +9 -0
  279. package/dist/web/primitives/embedded-list-input.js +382 -0
  280. package/dist/web/primitives/file-thumbnail.d.ts +25 -0
  281. package/dist/web/primitives/file-thumbnail.js +90 -0
  282. package/dist/web/primitives/file-upload.d.ts +21 -0
  283. package/dist/web/primitives/file-upload.js +56 -0
  284. package/dist/web/primitives/index.d.ts +34 -0
  285. package/dist/web/primitives/index.js +2021 -0
  286. package/dist/web/primitives/json-view.d.ts +7 -0
  287. package/dist/web/primitives/json-view.js +84 -0
  288. package/dist/web/primitives/layout.d.ts +27 -0
  289. package/dist/web/primitives/layout.js +30 -0
  290. package/dist/web/primitives/lightbox.d.ts +3 -0
  291. package/dist/web/primitives/lightbox.js +36 -0
  292. package/dist/web/primitives/locale-number.d.ts +2 -0
  293. package/dist/web/primitives/locale-number.js +54 -0
  294. package/dist/web/primitives/located-timestamp-input.d.ts +22 -0
  295. package/dist/web/primitives/located-timestamp-input.js +22 -0
  296. package/dist/web/primitives/metric.d.ts +5 -0
  297. package/dist/web/primitives/metric.js +18 -0
  298. package/dist/web/primitives/modal-shell.d.ts +17 -0
  299. package/dist/web/primitives/modal-shell.js +9 -0
  300. package/dist/web/primitives/modal.d.ts +3 -0
  301. package/dist/web/primitives/modal.js +13 -0
  302. package/dist/web/primitives/money-input.d.ts +18 -0
  303. package/dist/web/primitives/money-input.js +122 -0
  304. package/dist/web/primitives/narrow-pinned-footer.d.ts +12 -0
  305. package/dist/web/primitives/narrow-pinned-footer.js +153 -0
  306. package/dist/web/primitives/number-input.d.ts +18 -0
  307. package/dist/web/primitives/number-input.js +53 -0
  308. package/dist/web/primitives/option-groups.d.ts +11 -0
  309. package/dist/web/primitives/option-groups.js +27 -0
  310. package/dist/web/primitives/page-header.d.ts +3 -0
  311. package/dist/web/primitives/page-header.js +52 -0
  312. package/dist/web/primitives/promo-panel.d.ts +3 -0
  313. package/dist/web/primitives/promo-panel.js +11 -0
  314. package/dist/web/primitives/segmented-select.d.ts +21 -0
  315. package/dist/web/primitives/segmented-select.js +62 -0
  316. package/dist/web/primitives/share-actions.d.ts +4 -0
  317. package/dist/web/primitives/share-actions.js +56 -0
  318. package/dist/web/primitives/status-badge.d.ts +3 -0
  319. package/dist/web/primitives/status-badge.js +5 -0
  320. package/dist/web/primitives/sticky-action-bar.d.ts +5 -0
  321. package/dist/web/primitives/sticky-action-bar.js +15 -0
  322. package/dist/web/primitives/tabs.d.ts +3 -0
  323. package/dist/web/primitives/tabs.js +107 -0
  324. package/dist/web/primitives/timestamp-input.d.ts +27 -0
  325. package/dist/web/primitives/timestamp-input.js +87 -0
  326. package/dist/web/primitives/toast.d.ts +19 -0
  327. package/dist/web/primitives/toast.js +63 -0
  328. package/dist/web/primitives/tz-input.d.ts +11 -0
  329. package/dist/web/primitives/tz-input.js +8 -0
  330. package/dist/web/primitives/tz-options.d.ts +4 -0
  331. package/dist/web/primitives/tz-options.js +17 -0
  332. package/dist/web/primitives/use-keyboard-inset.d.ts +1 -0
  333. package/dist/web/primitives/use-keyboard-inset.js +28 -0
  334. package/dist/web/primitives/use-narrow-viewport.d.ts +4 -0
  335. package/dist/web/primitives/use-narrow-viewport.js +46 -0
  336. package/dist/web/react-css-custom-properties.d.ts +6 -0
  337. package/dist/web/react-css-custom-properties.js +1 -0
  338. package/dist/web/sse/live-events.d.ts +15 -0
  339. package/dist/web/sse/live-events.js +148 -0
  340. package/dist/web/theme-plugin.d.ts +41 -0
  341. package/dist/web/theme-plugin.js +123 -0
  342. package/dist/web/tokens.d.ts +24 -0
  343. package/dist/web/tokens.js +203 -0
  344. package/dist/web/ui/avatar.d.ts +11 -0
  345. package/dist/web/ui/avatar.js +25 -0
  346. package/dist/web/ui/badge.d.ts +9 -0
  347. package/dist/web/ui/badge.js +26 -0
  348. package/dist/web/ui/breadcrumb.d.ts +11 -0
  349. package/dist/web/ui/breadcrumb.js +29 -0
  350. package/dist/web/ui/button.d.ts +10 -0
  351. package/dist/web/ui/button.js +37 -0
  352. package/dist/web/ui/checkbox.d.ts +4 -0
  353. package/dist/web/ui/checkbox.js +11 -0
  354. package/dist/web/ui/input.d.ts +3 -0
  355. package/dist/web/ui/input.js +8 -0
  356. package/dist/web/ui/label.d.ts +4 -0
  357. package/dist/web/ui/label.js +10 -0
  358. package/dist/web/ui/resizable.d.ts +7 -0
  359. package/dist/web/ui/resizable.js +16 -0
  360. package/dist/web/ui/separator.d.ts +4 -0
  361. package/dist/web/ui/separator.js +10 -0
  362. package/dist/web/ui/sheet.d.ts +14 -0
  363. package/dist/web/ui/sheet.js +42 -0
  364. package/dist/web/ui/sidebar.d.ts +73 -0
  365. package/dist/web/ui/sidebar.js +211 -0
  366. package/dist/web/ui/skeleton.d.ts +2 -0
  367. package/dist/web/ui/skeleton.js +7 -0
  368. package/dist/web/ui/switch.d.ts +6 -0
  369. package/dist/web/ui/switch.js +10 -0
  370. package/dist/web/ui/table.d.ts +10 -0
  371. package/dist/web/ui/table.js +30 -0
  372. package/dist/web/ui/tabs.d.ts +11 -0
  373. package/dist/web/ui/tabs.js +31 -0
  374. package/dist/web/ui/textarea.d.ts +3 -0
  375. package/dist/web/ui/textarea.js +8 -0
  376. package/dist/web/ui/tooltip.d.ts +7 -0
  377. package/dist/web/ui/tooltip.js +19 -0
  378. package/dist/web/ui/use-mobile.d.ts +1 -0
  379. package/dist/web/ui/use-mobile.js +16 -0
  380. package/dist/web/version/update-checker.d.ts +9 -0
  381. package/dist/web/version/update-checker.js +88 -0
  382. package/dist/web/widgets/ai-text-field.d.ts +36 -0
  383. package/dist/web/widgets/ai-text-field.js +137 -0
  384. package/dist/web/widgets/chart-window.d.ts +58 -0
  385. package/dist/web/widgets/chart-window.js +190 -0
  386. package/dist/web/widgets/charts.d.ts +208 -0
  387. package/dist/web/widgets/charts.js +685 -0
  388. package/dist/web/widgets/collapsible-section.d.ts +10 -0
  389. package/dist/web/widgets/collapsible-section.js +17 -0
  390. package/dist/web/widgets/dashboard-list.d.ts +21 -0
  391. package/dist/web/widgets/dashboard-list.js +45 -0
  392. package/dist/web/widgets/detail-list.d.ts +15 -0
  393. package/dist/web/widgets/detail-list.js +8 -0
  394. package/dist/web/widgets/drawer.d.ts +65 -0
  395. package/dist/web/widgets/drawer.js +142 -0
  396. package/dist/web/widgets/feed-list.d.ts +13 -0
  397. package/dist/web/widgets/feed-list.js +9 -0
  398. package/dist/web/widgets/floating-panel.d.ts +30 -0
  399. package/dist/web/widgets/floating-panel.js +242 -0
  400. package/dist/web/widgets/form-fields.d.ts +93 -0
  401. package/dist/web/widgets/form-fields.js +50 -0
  402. package/dist/web/widgets/index.d.ts +27 -0
  403. package/dist/web/widgets/index.js +30 -0
  404. package/dist/web/widgets/infinity-list.d.ts +46 -0
  405. package/dist/web/widgets/infinity-list.js +211 -0
  406. package/dist/web/widgets/mode-switch.d.ts +21 -0
  407. package/dist/web/widgets/mode-switch.js +25 -0
  408. package/dist/web/widgets/photo-slots.d.ts +29 -0
  409. package/dist/web/widgets/photo-slots.js +52 -0
  410. package/dist/web/widgets/plan-card.d.ts +36 -0
  411. package/dist/web/widgets/plan-card.js +13 -0
  412. package/dist/web/widgets/progress-bar.d.ts +19 -0
  413. package/dist/web/widgets/progress-bar.js +24 -0
  414. package/dist/web/widgets/progress-list.d.ts +19 -0
  415. package/dist/web/widgets/progress-list.js +11 -0
  416. package/dist/web/widgets/public-shell.d.ts +22 -0
  417. package/dist/web/widgets/public-shell.js +15 -0
  418. package/dist/web/widgets/query-table.d.ts +29 -0
  419. package/dist/web/widgets/query-table.js +30 -0
  420. package/dist/web/widgets/result-panel.d.ts +69 -0
  421. package/dist/web/widgets/result-panel.js +30 -0
  422. package/dist/web/widgets/section-card.d.ts +12 -0
  423. package/dist/web/widgets/section-card.js +9 -0
  424. package/dist/web/widgets/sheet-parts.d.ts +9 -0
  425. package/dist/web/widgets/sheet-parts.js +11 -0
  426. package/dist/web/widgets/side-by-side-table.d.ts +31 -0
  427. package/dist/web/widgets/side-by-side-table.js +11 -0
  428. package/dist/web/widgets/stat.d.ts +54 -0
  429. package/dist/web/widgets/stat.js +65 -0
  430. package/dist/web/widgets/states.d.ts +23 -0
  431. package/dist/web/widgets/states.js +20 -0
  432. package/dist/web/widgets/status-badge.d.ts +15 -0
  433. package/dist/web/widgets/status-badge.js +24 -0
  434. package/dist/web/widgets/step-bar.d.ts +35 -0
  435. package/dist/web/widgets/step-bar.js +60 -0
  436. package/dist/web/widgets/upload-zone.d.ts +24 -0
  437. package/dist/web/widgets/upload-zone.js +108 -0
  438. package/dist/web/widgets/use-draft.d.ts +20 -0
  439. package/dist/web/widgets/use-draft.js +21 -0
  440. package/dist/web/widgets/use-pointer-drag.d.ts +21 -0
  441. package/dist/web/widgets/use-pointer-drag.js +53 -0
  442. package/package.json +105 -7
  443. package/src/changes.json +53 -0
  444. package/src/web/fonts/OFL.txt +93 -0
  445. package/src/web/fonts/ibm-plex-mono-latin-400.woff2 +0 -0
  446. package/src/web/fonts/ibm-plex-mono-latin-500.woff2 +0 -0
  447. package/src/web/fonts/ibm-plex-mono-latin-ext-400.woff2 +0 -0
  448. package/src/web/fonts/ibm-plex-mono-latin-ext-500.woff2 +0 -0
  449. package/src/web/fonts/ibm-plex-sans-latin-400.woff2 +0 -0
  450. package/src/web/fonts/ibm-plex-sans-latin-500.woff2 +0 -0
  451. package/src/web/fonts/ibm-plex-sans-latin-600.woff2 +0 -0
  452. package/src/web/fonts/ibm-plex-sans-latin-ext-400.woff2 +0 -0
  453. package/src/web/fonts/ibm-plex-sans-latin-ext-500.woff2 +0 -0
  454. package/src/web/fonts/ibm-plex-sans-latin-ext-600.woff2 +0 -0
  455. package/src/web/styles.css +401 -0
@@ -0,0 +1,377 @@
1
+ // Apex marketing-surface renderer — turns a typed page description into a
2
+ // complete static HTML string. The shared structure (header/hero/feature-grid/
3
+ // pricing-grid/info-grid/final-cta/footer) lives here; apps pass only their data,
4
+ // brand tokens (brand.tokensCss) and content. Server-side, zero React, one
5
+ // cacheable HTTP response. See APEX_STRUCTURAL_CSS for the CSS contract.
6
+ import { escapeHtml } from "../format/index.js";
7
+ import { APEX_STRUCTURAL_CSS } from "./css.js";
8
+ import { APEX_LIGHTBOX_HTML, APEX_LIGHTBOX_SCRIPT } from "./lightbox.js";
9
+ export { APEX_NAV_MENU_CSS, APEX_NAV_TOGGLE_RESPONSIVE_CSS, APEX_STRUCTURAL_CSS } from "./css.js";
10
+ export { APEX_LIGHTBOX_HTML, APEX_LIGHTBOX_SCRIPT, APEX_LIGHTBOX_SCRIPT_CSP_HASH, } from "./lightbox.js";
11
+ // JSON in <script>-Kontext: `<` als < serialisieren, damit weder
12
+ // `</script>` noch `<!--` aus dem Block ausbrechen kann (JSON bleibt valide).
13
+ function scriptSafeJsonHtml(value) {
14
+ return JSON.stringify(value).replace(/</g, "\\u003c");
15
+ }
16
+ function dim(img) {
17
+ return `${img.width !== undefined ? ` width="${img.width}"` : ""}${img.height !== undefined ? ` height="${img.height}"` : ""}`;
18
+ }
19
+ function svgIcon(innerHtml) {
20
+ return `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${innerHtml}</svg>`;
21
+ }
22
+ function renderCta(cta) {
23
+ const variant = cta.variant ?? "primary";
24
+ const cls = variant === "link" ? "" : ` class="btn btn-${variant}"`;
25
+ return `<a${cls} href="${escapeHtml(cta.href)}">${escapeHtml(cta.label)}</a>`;
26
+ }
27
+ function renderSectionHead(s) {
28
+ if (s.eyebrow === undefined && s.heading === undefined && s.sub === undefined)
29
+ return "";
30
+ const eyebrow = s.eyebrow !== undefined ? `<span class="eyebrow">${escapeHtml(s.eyebrow)}</span>` : "";
31
+ const heading = s.heading !== undefined ? `<h2>${escapeHtml(s.heading)}</h2>` : "";
32
+ const sub = s.sub !== undefined ? `<p>${escapeHtml(s.sub)}</p>` : "";
33
+ return `<div class="section-head">${eyebrow}${heading}${sub}</div>`;
34
+ }
35
+ function bandAttrs(muted, id) {
36
+ const cls = muted === false ? "" : ` class="features"`;
37
+ const idAttr = id !== undefined ? ` id="${escapeHtml(id)}"` : "";
38
+ return cls + idAttr;
39
+ }
40
+ function renderHero(s) {
41
+ const logo = s.logo !== undefined
42
+ ? `<img class="hero-pony" src="${escapeHtml(s.logo.src)}" alt="${escapeHtml(s.logo.alt)}"${dim(s.logo)} />`
43
+ : "";
44
+ const ctasHtml = (s.ctas ?? []).map(renderCta).join("\n ");
45
+ const meta = s.metaHtml !== undefined ? `<p class="hero-meta">${s.metaHtml}</p>` : "";
46
+ const visual = s.screenshot !== undefined
47
+ ? `<div class="hero-visual"><div class="shot-frame"><div class="shot-bar"><span></span><span></span><span></span></div><img src="${escapeHtml(s.screenshot.src)}" alt="${escapeHtml(s.screenshot.alt)}"${dim(s.screenshot)} loading="eager" /></div></div>`
48
+ : "";
49
+ return `<section class="hero">
50
+ <div class="container hero-grid">
51
+ <div class="hero-copy">
52
+ ${logo}<h1>${escapeHtml(s.title)}</h1>
53
+ <p class="tagline">${escapeHtml(s.tagline)}</p>
54
+ ${ctasHtml !== "" ? `<div class="hero-cta">${ctasHtml}</div>` : ""}
55
+ ${meta}
56
+ </div>
57
+ ${visual}
58
+ </div>
59
+ </section>`;
60
+ }
61
+ function renderFeatureGrid(s) {
62
+ const cardsHtml = s.items
63
+ .map((f) => `<article class="feature">
64
+ ${f.icon !== undefined ? `<div class="feature-icon">${svgIcon(f.icon)}</div>` : ""}<h3>${escapeHtml(f.title)}</h3>
65
+ <p>${escapeHtml(f.desc)}</p>
66
+ </article>`)
67
+ .join("\n ");
68
+ return `<section${bandAttrs(s.muted, s.id)}>
69
+ <div class="container">
70
+ ${renderSectionHead(s)}
71
+ <div class="feature-grid">
72
+ ${cardsHtml}
73
+ </div>
74
+ </div>
75
+ </section>`;
76
+ }
77
+ function renderPricingCard(t) {
78
+ const featured = t.featured === true;
79
+ const badge = t.badge !== undefined ? `<span class="price-badge">${escapeHtml(t.badge)}</span>` : "";
80
+ const cap = t.capLine !== undefined ? [`<li class="price-cap">${escapeHtml(t.capLine)}</li>`] : [];
81
+ const benefits = t.benefits.map((b) => `<li>${escapeHtml(b)}</li>`);
82
+ const itemsHtml = [...cap, ...benefits].join("\n ");
83
+ const per = t.priceSuffix !== undefined ? `<span>${escapeHtml(t.priceSuffix)}</span>` : "";
84
+ const tagline = t.tagline !== undefined ? `<p class="price-tagline">${escapeHtml(t.tagline)}</p>` : "";
85
+ // Delegates to renderCta so a `variant: "link"` tier CTA gets the same
86
+ // class-free anchor as everywhere else instead of re-deriving the class
87
+ // string here (a prior inline duplicate had no "link" case, always
88
+ // emitting `.btn-link`, which the structural CSS never defines).
89
+ const cta = t.cta.variant === undefined
90
+ ? renderCta({ ...t.cta, variant: featured ? "primary" : "secondary" })
91
+ : renderCta(t.cta);
92
+ return `<article class="price-card${featured ? " price-card--featured" : ""}">
93
+ ${badge}<h3>${escapeHtml(t.name)}</h3>
94
+ ${tagline}<div class="price-amount">${escapeHtml(t.amount)}${per}</div>
95
+ <ul class="price-list">
96
+ ${itemsHtml}
97
+ </ul>
98
+ ${cta}
99
+ </article>`;
100
+ }
101
+ function renderPricingGrid(s) {
102
+ const cardsHtml = s.tiers.map(renderPricingCard).join("\n ");
103
+ const idAttr = s.id !== undefined ? ` id="${escapeHtml(s.id)}"` : "";
104
+ return `<section${idAttr}>
105
+ <div class="container">
106
+ ${renderSectionHead(s)}
107
+ <div class="price-grid">
108
+ ${cardsHtml}
109
+ </div>
110
+ </div>
111
+ </section>`;
112
+ }
113
+ function renderInfoGrid(s) {
114
+ const itemsHtml = s.items
115
+ .map((i) => `<div class="trust-item">
116
+ <h3>${escapeHtml(i.title)}</h3>
117
+ <p>${escapeHtml(i.desc)}</p>
118
+ </div>`)
119
+ .join("\n ");
120
+ return `<section${bandAttrs(s.muted, s.id)}>
121
+ <div class="container">
122
+ ${renderSectionHead(s)}
123
+ <div class="trust-grid">
124
+ ${itemsHtml}
125
+ </div>
126
+ </div>
127
+ </section>`;
128
+ }
129
+ function renderFinalCta(s) {
130
+ const img = s.image !== undefined
131
+ ? `<img class="final-cta-pony" src="${escapeHtml(s.image.src)}" alt="${escapeHtml(s.image.alt)}"${dim(s.image)} />`
132
+ : "";
133
+ const sub = s.sub !== undefined ? `<p>${escapeHtml(s.sub)}</p>` : "";
134
+ return `<section class="final-cta">
135
+ <div class="container">
136
+ ${img}<h2>${escapeHtml(s.heading)}</h2>
137
+ ${sub}${renderCta(s.cta)}
138
+ </div>
139
+ </section>`;
140
+ }
141
+ function renderSection(s) {
142
+ switch (s.kind) {
143
+ case "hero":
144
+ return renderHero(s);
145
+ case "feature-grid":
146
+ return renderFeatureGrid(s);
147
+ case "pricing-grid":
148
+ return renderPricingGrid(s);
149
+ case "info-grid":
150
+ return renderInfoGrid(s);
151
+ case "final-cta":
152
+ return renderFinalCta(s);
153
+ case "html":
154
+ return s.html;
155
+ }
156
+ }
157
+ function renderNavMenu(m) {
158
+ const itemsHtml = m.items
159
+ .map((it) => `<a class="nav-menu__item" href="${escapeHtml(it.href)}">${it.icon !== undefined ? `<span class="nav-menu__icon">${svgIcon(it.icon)}</span>` : ""}<span class="nav-menu__text"><span class="nav-menu__title">${escapeHtml(it.title)}</span>${it.desc !== undefined ? `<span class="nav-menu__desc">${escapeHtml(it.desc)}</span>` : ""}</span></a>`)
160
+ .join("");
161
+ const footer = m.footer !== undefined
162
+ ? `<div class="nav-menu__sep"></div><a class="nav-menu__more" href="${escapeHtml(m.footer.href)}">${escapeHtml(m.footer.label)}</a>`
163
+ : "";
164
+ return `<details class="nav-menu"><summary class="nav-menu__trigger">${escapeHtml(m.label)}<span class="nav-menu__chev">${svgIcon('<path d="m6 9 6 6 6-6"/>')}</span></summary><div class="nav-menu__panel">${itemsHtml}${footer}</div></details>`;
165
+ }
166
+ function renderNavEntry(entry) {
167
+ return entry.kind === "menu"
168
+ ? renderNavMenu(entry)
169
+ : `<a href="${escapeHtml(entry.href)}">${escapeHtml(entry.label)}</a>`;
170
+ }
171
+ /** Render just the apex header chrome (brand + nav + actions). Exported so a
172
+ * consumer that composes its own page shell (not a full apex page) can reuse
173
+ * the identical header — markup stays single-source. */
174
+ export function renderApexHeader(h) {
175
+ const logo = h.brand.logoSrc !== undefined ? `<img src="${escapeHtml(h.brand.logoSrc)}" alt="" /> ` : "";
176
+ const navLinksHtml = (h.navLinks ?? []).map(renderNavEntry).join("\n ");
177
+ const actionsHtml = (h.actions ?? []).map(renderCta).join("\n ");
178
+ return `<header>
179
+ <div class="container nav">
180
+ <div class="brand"><a href="${escapeHtml(h.brand.href)}">${logo}${escapeHtml(h.brand.label)}</a></div>
181
+ ${navLinksHtml !== "" ? `<nav class="nav-links">${navLinksHtml}</nav><details class="nav-toggle"><summary class="nav-toggle__trigger" aria-label="${escapeHtml(h.menuLabel ?? "Menu")}">${svgIcon('<path d="M4 6h16M4 12h16M4 18h16"/>')}</summary><nav class="nav-links">${navLinksHtml}</nav></details>` : ""}
182
+ ${actionsHtml !== "" ? `<div class="nav-actions">${actionsHtml}</div>` : ""}
183
+ </div>
184
+ </header>`;
185
+ }
186
+ function renderFooter(f) {
187
+ const cols = f.columns ?? [];
188
+ const logo = f.brand.logoSrc !== undefined ? `<img src="${escapeHtml(f.brand.logoSrc)}" alt="" /> ` : "";
189
+ const colHtml = cols
190
+ .map((c) => `<div class="footer-col">
191
+ <h4>${escapeHtml(c.heading)}</h4>
192
+ ${c.links.map((l) => `<a href="${escapeHtml(l.href)}">${escapeHtml(l.label)}</a>`).join("\n ")}
193
+ </div>`)
194
+ .join("\n ");
195
+ const bottom = f.bottomLeft !== undefined || f.bottomRight !== undefined
196
+ ? `<div class="footer-bottom">
197
+ ${f.bottomLeft !== undefined ? `<span>${escapeHtml(f.bottomLeft)}</span>` : ""}
198
+ ${f.bottomRight !== undefined ? `<span>${escapeHtml(f.bottomRight)}</span>` : ""}
199
+ </div>`
200
+ : "";
201
+ return `<footer>
202
+ <div class="container">
203
+ <div class="footer-grid" style="--footer-cols:${Math.max(1, cols.length)}">
204
+ <div>
205
+ <div class="footer-brand">${logo}${escapeHtml(f.brand.label)}</div>
206
+ ${f.tagline !== undefined ? `<p class="footer-tagline">${escapeHtml(f.tagline)}</p>` : ""}
207
+ </div>
208
+ ${colHtml}
209
+ </div>
210
+ ${bottom}
211
+ </div>
212
+ </footer>`;
213
+ }
214
+ // All <title>/meta/link/script tags for an ApexHead — the single source both
215
+ // renderApexPage and any other head (e.g. page-render's wrapInLayout) splice
216
+ // into their own <head>. Extracted verbatim from renderApexPage so existing
217
+ // output stays byte-identical (see render.test.ts regression coverage).
218
+ export function renderApexHeadTags(head) {
219
+ const ogUrl = head.canonicalUrl !== undefined
220
+ ? `\n <meta property="og:url" content="${escapeHtml(head.canonicalUrl)}" />`
221
+ : "";
222
+ const ogImage = head.ogImage !== undefined
223
+ ? `\n <meta property="og:image" content="${escapeHtml(head.ogImage)}" />`
224
+ : "";
225
+ const favicon = head.faviconHref !== undefined
226
+ ? `\n <link rel="icon" href="${escapeHtml(head.faviconHref)}" />`
227
+ : "";
228
+ const canonical = head.canonicalUrl !== undefined
229
+ ? `\n <link rel="canonical" href="${escapeHtml(head.canonicalUrl)}" />`
230
+ : "";
231
+ const alternates = (head.alternates ?? [])
232
+ .map((a) => `\n <link rel="alternate" hreflang="${escapeHtml(a.hreflang)}" href="${escapeHtml(a.href)}" />`)
233
+ .join("");
234
+ const robots = head.robots !== undefined
235
+ ? `\n <meta name="robots" content="${escapeHtml(head.robots)}" />`
236
+ : "";
237
+ const siteName = head.siteName !== undefined
238
+ ? `\n <meta property="og:site_name" content="${escapeHtml(head.siteName)}" />`
239
+ : "";
240
+ const locale = head.locale !== undefined
241
+ ? `\n <meta property="og:locale" content="${escapeHtml(head.locale)}" />`
242
+ : "";
243
+ const twitterCard = head.ogImage !== undefined
244
+ ? `\n <meta name="twitter:card" content="summary_large_image" />`
245
+ : "";
246
+ const twitterSite = head.twitterSite !== undefined
247
+ ? `\n <meta name="twitter:site" content="${escapeHtml(head.twitterSite)}" />`
248
+ : "";
249
+ const preconnects = (head.preconnects ?? [])
250
+ .map((url) => `\n <link rel="preconnect" href="${escapeHtml(url)}" />`)
251
+ .join("");
252
+ const schema = head.schemaJson !== undefined
253
+ ? `\n <script type="application/ld+json">${scriptSafeJsonHtml(head.schemaJson)}</script>`
254
+ : "";
255
+ const metaDescription = head.description
256
+ ? `\n <meta name="description" content="${escapeHtml(head.description)}" />`
257
+ : "";
258
+ const ogDescription = head.description
259
+ ? `\n <meta property="og:description" content="${escapeHtml(head.description)}" />`
260
+ : "";
261
+ return `<title>${escapeHtml(head.title)}</title>${metaDescription}
262
+ <meta property="og:title" content="${escapeHtml(head.title)}" />${ogDescription}
263
+ <meta property="og:type" content="website" />${ogUrl}${ogImage}${siteName}${locale}${twitterCard}${twitterSite}${favicon}${canonical}${alternates}${robots}${preconnects}${schema}`;
264
+ }
265
+ export function renderApexPage(page) {
266
+ const { head, brand } = page;
267
+ const theme = page.theme ?? "light";
268
+ // Brand-CSS ist app-authored (Trust-Boundary siehe Datei-Header), kein Tenant-Input.
269
+ const cssHtml = (brand.fontFaceCss ?? "") + brand.tokensCss + APEX_STRUCTURAL_CSS;
270
+ const sectionsHtml = page.sections.map(renderSection).join("\n\n ");
271
+ // interactive-widget is ignored by iOS Safari; apex pages have no fixed bottom bars, so
272
+ // the key only matters for Chromium/Android and needs no visualViewport fallback here.
273
+ return `<!doctype html>
274
+ <html lang="${escapeHtml(head.lang)}">
275
+ <head>
276
+ <meta charset="utf-8" />
277
+ <meta name="viewport" content="width=device-width,initial-scale=1,interactive-widget=resizes-content" />
278
+ ${renderApexHeadTags(head)}
279
+ <style>${cssHtml}</style>
280
+ </head>
281
+ <body${theme === "dark" ? ` class="apex-dark"` : ""}>
282
+ ${renderApexHeader(page.header)}
283
+
284
+ ${sectionsHtml}
285
+
286
+ ${renderFooter(page.footer)}
287
+
288
+ ${APEX_LIGHTBOX_HTML}
289
+ ${APEX_LIGHTBOX_SCRIPT}
290
+ </body>
291
+ </html>`;
292
+ }
293
+ const HEAD_TAGS_MARKER = "<!-- kumiko-page-head -->";
294
+ const TITLE_TAG_RE = /<title\b[^>]*>[\s\S]*?<\/title>/i;
295
+ // Idempotent by marker (repeated calls, e.g. hostDispatch + default path
296
+ // both hitting the same request, never double-inject) and safe on a
297
+ // head-less document (nothing to splice into). `tagsHtml` is pre-rendered
298
+ // HTML from a caller (renderApexHeadTags) — this function only owns
299
+ // placement + the original <title> removal, not escaping.
300
+ export function injectPageHead(html, tagsHtml) {
301
+ if (html.includes(HEAD_TAGS_MARKER))
302
+ return html;
303
+ if (!html.includes("</head>"))
304
+ return html;
305
+ const withoutTitle = html.replace(TITLE_TAG_RE, "");
306
+ return withoutTitle.replace("</head>", () => `${HEAD_TAGS_MARKER}\n${tagsHtml}\n</head>`);
307
+ }
308
+ // Resolver runs alongside the request, never gates it: a slow, throwing, or
309
+ // null-returning resolver must never turn a 200 shell into a 500 or a
310
+ // stall. One constant shared by runProdApp and runDevApp so both time out
311
+ // on the same value (kumiko-framework#3026).
312
+ const PAGE_HEAD_TIMEOUT_MS = 300;
313
+ async function resolvePageHeadWithTimeout(resolvePageHead, input) {
314
+ let timer;
315
+ // Winning the race alone would leave the resolver's queries running; the abort stops them.
316
+ const timeout = new AbortController();
317
+ const signal = input.requestSignal
318
+ ? AbortSignal.any([input.requestSignal, timeout.signal])
319
+ : timeout.signal;
320
+ const { systemQuery } = input;
321
+ try {
322
+ const timedOut = new Promise((resolve) => {
323
+ timer = setTimeout(() => {
324
+ timeout.abort();
325
+ resolve(null);
326
+ }, PAGE_HEAD_TIMEOUT_MS);
327
+ });
328
+ // .catch on the resolver's own promise (not just the outer try/catch)
329
+ // so a rejection arriving AFTER the timeout already won the race
330
+ // doesn't surface as an unhandled rejection.
331
+ const resolved = resolvePageHead({
332
+ path: input.path,
333
+ host: input.host,
334
+ preferredLocales: input.preferredLocales,
335
+ signal,
336
+ systemQuery: (type, payload, tenantId) => systemQuery(type, payload, tenantId, { signal }),
337
+ }).catch(() => null);
338
+ return await Promise.race([resolved, timedOut]);
339
+ }
340
+ catch {
341
+ return null;
342
+ }
343
+ finally {
344
+ if (timer !== undefined)
345
+ clearTimeout(timer);
346
+ }
347
+ }
348
+ // ApexHead.lang is required (html lang="..."); PageHeadMeta only carries
349
+ // og:locale-shaped strings ("de_DE", "en-US") since that's all og:locale
350
+ // needs. Take the language subtag before the region separator; default to
351
+ // "en" when there's no locale to derive one from.
352
+ function apexLangFromLocale(locale) {
353
+ return locale?.split(/[_-]/)[0]?.toLowerCase() || "en";
354
+ }
355
+ function toApexHead(meta) {
356
+ return {
357
+ lang: apexLangFromLocale(meta.locale),
358
+ title: meta.title,
359
+ description: meta.description ?? "",
360
+ ...(meta.canonicalUrl !== undefined ? { canonicalUrl: meta.canonicalUrl } : {}),
361
+ ...(meta.ogImage !== undefined ? { ogImage: meta.ogImage } : {}),
362
+ ...(meta.siteName !== undefined ? { siteName: meta.siteName } : {}),
363
+ ...(meta.locale !== undefined ? { locale: meta.locale } : {}),
364
+ };
365
+ }
366
+ /** Resolves per-request head metadata and splices it into `html`, capped at
367
+ * the shared timeout. Never throws and never changes `html` on a resolver
368
+ * error, a `null` resolve, or a timeout — the caller's shell always ships
369
+ * unchanged. runProdApp and runDevApp both call this single function, so a
370
+ * future change to timeout or fallback semantics has one place to land
371
+ * (kumiko-framework#3026). */
372
+ export async function resolveAndInjectPageHead(html, resolvePageHead, input) {
373
+ const meta = await resolvePageHeadWithTimeout(resolvePageHead, input);
374
+ if (!meta)
375
+ return html;
376
+ return injectPageHead(html, renderApexHeadTags(toApexHead(meta)));
377
+ }
@@ -0,0 +1,4 @@
1
+ export declare const APEX_LIGHTBOX_HTML = "<dialog id=\"apex-lightbox\" class=\"apex-lightbox\" aria-label=\"Screenshot preview\">\n <button type=\"button\" class=\"apex-lightbox__close\" aria-label=\"Close\">&times;</button>\n <button type=\"button\" class=\"apex-lightbox__prev\" aria-label=\"Previous screenshot\">&lsaquo;</button>\n <button type=\"button\" class=\"apex-lightbox__next\" aria-label=\"Next screenshot\">&rsaquo;</button>\n <img class=\"apex-lightbox__img\" alt=\"\" />\n</dialog>";
2
+ /** ponytail: one delegated listener; no-op when no .shot-frame on the page. */
3
+ export declare const APEX_LIGHTBOX_SCRIPT = "<script>\n(function () {\n var dlg = document.getElementById(\"apex-lightbox\");\n if (!dlg) return;\n var img = dlg.querySelector(\".apex-lightbox__img\");\n var closeBtn = dlg.querySelector(\".apex-lightbox__close\");\n var prevBtn = dlg.querySelector(\".apex-lightbox__prev\");\n var nextBtn = dlg.querySelector(\".apex-lightbox__next\");\n if (!img || !closeBtn || !prevBtn || !nextBtn) return;\n var shots = [];\n var current = 0;\n function show(i) {\n var shot = shots[i];\n current = i;\n img.src = shot.currentSrc || shot.src;\n img.alt = shot.alt || \"\";\n }\n function step(delta) {\n if (shots.length < 2) return;\n show((current + delta + shots.length) % shots.length);\n }\n function open(target) {\n shots = Array.prototype.slice.call(document.querySelectorAll(\".shot-frame img\"));\n var start = shots.indexOf(target);\n if (start < 0) {\n shots = [target];\n start = 0;\n }\n show(start);\n prevBtn.hidden = nextBtn.hidden = shots.length < 2;\n if (typeof dlg.showModal === \"function\") dlg.showModal();\n }\n function close() {\n if (dlg.open) dlg.close();\n }\n document.addEventListener(\"click\", function (e) {\n var t = e.target;\n if (!(t instanceof HTMLImageElement)) return;\n if (!t.closest(\".shot-frame\")) return;\n e.preventDefault();\n open(t);\n });\n closeBtn.addEventListener(\"click\", close);\n prevBtn.addEventListener(\"click\", function () { step(-1); });\n nextBtn.addEventListener(\"click\", function () { step(1); });\n document.addEventListener(\"keydown\", function (e) {\n if (!dlg.open) return;\n if (e.key === \"ArrowLeft\") {\n e.preventDefault();\n step(-1);\n } else if (e.key === \"ArrowRight\") {\n e.preventDefault();\n step(1);\n }\n });\n dlg.addEventListener(\"click\", function (e) {\n if (e.target === dlg) close();\n });\n dlg.addEventListener(\"cancel\", function (e) {\n e.preventDefault();\n close();\n });\n})();\n</script>";
4
+ export declare const APEX_LIGHTBOX_SCRIPT_CSP_HASH = "sha256-CLZlqZx0zShYKXq1Qg6+VYMTEC6tqiIlNf6JPA1nLck=";
@@ -0,0 +1,81 @@
1
+ // Vanilla lightbox for Apex marketing pages — click .shot-frame img to enlarge,
2
+ // prev/next (buttons or arrow keys) walks all .shot-frame images on the page.
3
+ // Injected by renderApexPage; no React, no per-app wiring.
4
+ export const APEX_LIGHTBOX_HTML = `<dialog id="apex-lightbox" class="apex-lightbox" aria-label="Screenshot preview">
5
+ <button type="button" class="apex-lightbox__close" aria-label="Close">&times;</button>
6
+ <button type="button" class="apex-lightbox__prev" aria-label="Previous screenshot">&lsaquo;</button>
7
+ <button type="button" class="apex-lightbox__next" aria-label="Next screenshot">&rsaquo;</button>
8
+ <img class="apex-lightbox__img" alt="" />
9
+ </dialog>`;
10
+ // Split from APEX_LIGHTBOX_SCRIPT so APEX_LIGHTBOX_SCRIPT_CSP_HASH hashes
11
+ // exactly the bytes the browser executes — CSP's script-src hash-source
12
+ // covers the content between <script> and </script>, nothing more/less.
13
+ const APEX_LIGHTBOX_SCRIPT_BODY = `
14
+ (function () {
15
+ var dlg = document.getElementById("apex-lightbox");
16
+ if (!dlg) return;
17
+ var img = dlg.querySelector(".apex-lightbox__img");
18
+ var closeBtn = dlg.querySelector(".apex-lightbox__close");
19
+ var prevBtn = dlg.querySelector(".apex-lightbox__prev");
20
+ var nextBtn = dlg.querySelector(".apex-lightbox__next");
21
+ if (!img || !closeBtn || !prevBtn || !nextBtn) return;
22
+ var shots = [];
23
+ var current = 0;
24
+ function show(i) {
25
+ var shot = shots[i];
26
+ current = i;
27
+ img.src = shot.currentSrc || shot.src;
28
+ img.alt = shot.alt || "";
29
+ }
30
+ function step(delta) {
31
+ if (shots.length < 2) return;
32
+ show((current + delta + shots.length) % shots.length);
33
+ }
34
+ function open(target) {
35
+ shots = Array.prototype.slice.call(document.querySelectorAll(".shot-frame img"));
36
+ var start = shots.indexOf(target);
37
+ if (start < 0) {
38
+ shots = [target];
39
+ start = 0;
40
+ }
41
+ show(start);
42
+ prevBtn.hidden = nextBtn.hidden = shots.length < 2;
43
+ if (typeof dlg.showModal === "function") dlg.showModal();
44
+ }
45
+ function close() {
46
+ if (dlg.open) dlg.close();
47
+ }
48
+ document.addEventListener("click", function (e) {
49
+ var t = e.target;
50
+ if (!(t instanceof HTMLImageElement)) return;
51
+ if (!t.closest(".shot-frame")) return;
52
+ e.preventDefault();
53
+ open(t);
54
+ });
55
+ closeBtn.addEventListener("click", close);
56
+ prevBtn.addEventListener("click", function () { step(-1); });
57
+ nextBtn.addEventListener("click", function () { step(1); });
58
+ document.addEventListener("keydown", function (e) {
59
+ if (!dlg.open) return;
60
+ if (e.key === "ArrowLeft") {
61
+ e.preventDefault();
62
+ step(-1);
63
+ } else if (e.key === "ArrowRight") {
64
+ e.preventDefault();
65
+ step(1);
66
+ }
67
+ });
68
+ dlg.addEventListener("click", function (e) {
69
+ if (e.target === dlg) close();
70
+ });
71
+ dlg.addEventListener("cancel", function (e) {
72
+ e.preventDefault();
73
+ close();
74
+ });
75
+ })();
76
+ `;
77
+ /** ponytail: one delegated listener; no-op when no .shot-frame on the page. */
78
+ export const APEX_LIGHTBOX_SCRIPT = `<script>${APEX_LIGHTBOX_SCRIPT_BODY}</script>`;
79
+ // CSP hash-source for the inline script above; apex output is often
80
+ // pre-rendered, so a per-request nonce can't work. Guarded by lightbox.test.ts.
81
+ export const APEX_LIGHTBOX_SCRIPT_CSP_HASH = "sha256-CLZlqZx0zShYKXq1Qg6+VYMTEC6tqiIlNf6JPA1nLck=";
@@ -0,0 +1,15 @@
1
+ export type AssetResolveContext = {
2
+ readonly tenantId?: string;
3
+ readonly theme?: "light" | "dark";
4
+ readonly platform?: "web" | "ios" | "android";
5
+ readonly locale?: string;
6
+ };
7
+ export type AssetResolution = {
8
+ readonly uri: string;
9
+ readonly width?: number;
10
+ readonly height?: number;
11
+ readonly alt?: string;
12
+ };
13
+ export type AssetResolver = {
14
+ resolve(qn: string, ctx?: AssetResolveContext): AssetResolution | null;
15
+ };
@@ -0,0 +1,17 @@
1
+ // Asset-Resolver — the layer between "qualified asset name" and "URL the
2
+ // renderer can point an <img>/<Image> at". An asset (logo, illustration,
3
+ // icon bundle) is declared by a feature with a qualified name
4
+ // ("admin:asset:hero-logo") and resolved at render-time against the
5
+ // current tenant / theme / platform.
6
+ //
7
+ // Why a resolver indirection:
8
+ // - Tenant-theming (different logo per tenant) without the feature
9
+ // knowing what tenant it's rendering for.
10
+ // - Dark-mode / light-mode variants picked up from the current theme
11
+ // context.
12
+ // - Web vs mobile different asset bundles (e.g. PNG vs SVG).
13
+ //
14
+ // The app registers a concrete resolver on startup and hands it to the
15
+ // renderer via context. Feature code calls `useAsset("admin:asset:logo")`
16
+ // (renderer-side hook) → internally `AssetResolver.resolve(qn)`.
17
+ export {};
@@ -0,0 +1,3 @@
1
+ export type { AssetResolution, AssetResolveContext, AssetResolver, } from "./asset.ts";
2
+ export type { LocaleResolver } from "./locale.ts";
3
+ export type { BadgeProps, ButtonProps, CardProps, DatePickerProps, IconProps, ModalProps, NumberInputProps, PrimitiveCommonProps, PrimitivesContract, SelectOption, SelectProps, TextInputProps, ToastIntent, ToastProps, ToggleProps, } from "./primitives.ts";
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ export type LocaleResolver = {
2
+ translate(key: string, params?: Readonly<Record<string, unknown>>): string;
3
+ locale(): string;
4
+ timeZone(): string;
5
+ subscribe(listener: () => void): () => void;
6
+ setLocale?(locale: string): void;
7
+ };
@@ -0,0 +1,11 @@
1
+ // Locale-Resolver — translation lookup + language/region info the
2
+ // renderer needs. Sits in front of i18next (or whatever i18n library
3
+ // the app wires up). ui-core calls it generically so form-controller,
4
+ // view-model, and nav-resolver all produce already-translated strings
5
+ // to hand to the renderer.
6
+ //
7
+ // The framework already has an i18n layer (@cosmicdrift/kumiko-framework/i18n) that
8
+ // features register translations against. This contract is what ui-core
9
+ // consumes — the app's entrypoint instantiates the resolver from a
10
+ // framework i18next instance and passes it to the renderer via context.
11
+ export {};
@@ -0,0 +1,93 @@
1
+ export type PrimitiveCommonProps = {
2
+ readonly id?: string;
3
+ readonly name?: string;
4
+ readonly disabled?: boolean;
5
+ readonly readOnly?: boolean;
6
+ readonly required?: boolean;
7
+ readonly label?: string;
8
+ readonly placeholder?: string;
9
+ readonly helperText?: string;
10
+ readonly errors?: readonly string[];
11
+ };
12
+ export type TextInputProps = PrimitiveCommonProps & {
13
+ readonly value: string;
14
+ readonly onChange: (next: string) => void;
15
+ readonly onBlur?: () => void;
16
+ readonly type?: "text" | "email" | "url" | "tel" | "password";
17
+ readonly maxLength?: number;
18
+ readonly autoComplete?: string;
19
+ };
20
+ export type NumberInputProps = PrimitiveCommonProps & {
21
+ readonly value: number | null;
22
+ readonly onChange: (next: number | null) => void;
23
+ readonly onBlur?: () => void;
24
+ readonly min?: number;
25
+ readonly max?: number;
26
+ readonly step?: number;
27
+ };
28
+ export type SelectOption<TValue extends string = string> = {
29
+ readonly value: TValue;
30
+ readonly label: string;
31
+ };
32
+ export type SelectProps<TValue extends string = string> = PrimitiveCommonProps & {
33
+ readonly value: TValue | null;
34
+ readonly onChange: (next: TValue | null) => void;
35
+ readonly options: readonly SelectOption<TValue>[];
36
+ };
37
+ export type ToggleProps = PrimitiveCommonProps & {
38
+ readonly value: boolean;
39
+ readonly onChange: (next: boolean) => void;
40
+ };
41
+ export type DatePickerProps = PrimitiveCommonProps & {
42
+ readonly value: string | null;
43
+ readonly onChange: (next: string | null) => void;
44
+ readonly minDate?: string;
45
+ readonly maxDate?: string;
46
+ };
47
+ export type ButtonProps = {
48
+ readonly onPress: () => void;
49
+ readonly label: string;
50
+ readonly variant?: "primary" | "secondary" | "destructive" | "ghost";
51
+ readonly disabled?: boolean;
52
+ readonly loading?: boolean;
53
+ readonly leftIcon?: string;
54
+ readonly rightIcon?: string;
55
+ };
56
+ export type ModalProps = {
57
+ readonly open: boolean;
58
+ readonly onClose: () => void;
59
+ readonly title?: string;
60
+ readonly description?: string;
61
+ };
62
+ export type ToastIntent = "info" | "success" | "warning" | "error";
63
+ export type ToastProps = {
64
+ readonly intent: ToastIntent;
65
+ readonly title: string;
66
+ readonly description?: string;
67
+ readonly onDismiss?: () => void;
68
+ };
69
+ export type BadgeProps = {
70
+ readonly label: string;
71
+ readonly intent?: ToastIntent;
72
+ };
73
+ export type CardProps = {
74
+ readonly title?: string;
75
+ readonly description?: string;
76
+ };
77
+ export type IconProps = {
78
+ readonly name: string;
79
+ readonly size?: number;
80
+ };
81
+ export type PrimitivesContract<TPrimitive = unknown> = {
82
+ readonly TextInput: TPrimitive;
83
+ readonly NumberInput: TPrimitive;
84
+ readonly Select: TPrimitive;
85
+ readonly Toggle: TPrimitive;
86
+ readonly DatePicker: TPrimitive;
87
+ readonly Button: TPrimitive;
88
+ readonly Modal: TPrimitive;
89
+ readonly Toast: TPrimitive;
90
+ readonly Badge: TPrimitive;
91
+ readonly Card: TPrimitive;
92
+ readonly Icon: TPrimitive;
93
+ };
@@ -0,0 +1,21 @@
1
+ // Primitives-Contract — the minimal set of UI building blocks every
2
+ // renderer must provide. A "primitive" is a unit the standard-renderers
3
+ // (entityList, entityEdit, etc.) call into without knowing which library
4
+ // implements it. On web that's shadcn; on mobile it's react-native-paper;
5
+ // both packages (primitives-shadcn, primitives-paper) implement this
6
+ // contract and the app wires one of them into the renderer via context.
7
+ //
8
+ // Why a contract here (in ui-core) instead of in each renderer:
9
+ // ui-core's view-model builder and form-controller produce metadata
10
+ // (field-type, validation-state, label, placeholder) that the renderer
11
+ // translates into primitive invocations. Having the contract shape in
12
+ // ui-core means the metadata can carry references to primitives by name
13
+ // ("text-input", "select") and the translation is a pure map-lookup on
14
+ // the renderer side, not a switch statement that re-derives UI intent
15
+ // from entity-schema.
16
+ //
17
+ // Runtime-free: every primitive is expressed as its input contract only
18
+ // (what props it takes). Concrete components live in each primitives-*
19
+ // package and depend on React / React Native / etc.; ui-core never
20
+ // imports them.
21
+ export {};
@@ -0,0 +1,2 @@
1
+ export type { BatchResult, Command, Dispatcher, DispatcherError, DispatcherStatus, FieldIssue, PendingFile, PendingWrite, QueryOpts, QueryResult, StreamOpts, WriteOpts, WriteResult, } from "./types.ts";
2
+ export { StreamFrame, type StreamFrameEvent } from "./types.ts";
@@ -0,0 +1 @@
1
+ export { StreamFrame } from "./types.js";