@cosmicdrift/kumiko-renderer 0.328.0 → 0.328.1

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 (259) hide show
  1. package/dist/app/action-form-shim.d.ts +14 -0
  2. package/{src/app/action-form-shim.ts → dist/app/action-form-shim.js} +26 -46
  3. package/dist/app/app-features-context.d.ts +8 -0
  4. package/dist/app/app-features-context.js +16 -0
  5. package/dist/app/column-renderers.d.ts +30 -0
  6. package/dist/app/column-renderers.js +34 -0
  7. package/dist/app/config-edit-shim.d.ts +11 -0
  8. package/{src/app/config-edit-shim.ts → dist/app/config-edit-shim.js} +12 -25
  9. package/dist/app/content-editors.d.ts +38 -0
  10. package/dist/app/content-editors.js +26 -0
  11. package/dist/app/content-preview.d.ts +11 -0
  12. package/dist/app/content-preview.js +30 -0
  13. package/dist/app/custom-screens.d.ts +11 -0
  14. package/dist/app/custom-screens.js +20 -0
  15. package/dist/app/dashboard-body.d.ts +16 -0
  16. package/dist/app/dashboard-body.js +11 -0
  17. package/dist/app/extension-form-submit.d.ts +32 -0
  18. package/dist/app/extension-form-submit.js +73 -0
  19. package/dist/app/extension-sections.d.ts +72 -0
  20. package/dist/app/extension-sections.js +34 -0
  21. package/dist/app/feature-schema.d.ts +4 -0
  22. package/{src/app/feature-schema.ts → dist/app/feature-schema.js} +12 -22
  23. package/dist/app/form-schema.d.ts +4 -0
  24. package/dist/app/form-schema.js +85 -0
  25. package/dist/app/kumiko-screen.d.ts +43 -0
  26. package/dist/app/kumiko-screen.js +2206 -0
  27. package/dist/app/layout-fields.d.ts +3 -0
  28. package/dist/app/layout-fields.js +20 -0
  29. package/dist/app/list-facets.d.ts +48 -0
  30. package/dist/app/list-facets.js +185 -0
  31. package/dist/app/nav.d.ts +61 -0
  32. package/dist/app/nav.js +139 -0
  33. package/dist/app/projection-detail-shim.d.ts +8 -0
  34. package/dist/app/projection-detail-shim.js +71 -0
  35. package/dist/app/projection-list-shim.d.ts +13 -0
  36. package/{src/app/projection-list-shim.ts → dist/app/projection-list-shim.js} +26 -41
  37. package/dist/app/qn.d.ts +7 -0
  38. package/{src/app/qn.ts → dist/app/qn.js} +9 -11
  39. package/dist/app/qualify-screen-id.d.ts +2 -0
  40. package/{src/app/qualify-screen-id.ts → dist/app/qualify-screen-id.js} +5 -6
  41. package/dist/app/reference-facet-bridge.d.ts +10 -0
  42. package/dist/app/reference-facet-bridge.js +22 -0
  43. package/dist/app/return-to.d.ts +31 -0
  44. package/dist/app/return-to.js +188 -0
  45. package/dist/app/row-actions.d.ts +77 -0
  46. package/dist/app/row-actions.js +416 -0
  47. package/dist/app/screen-access.d.ts +8 -0
  48. package/dist/app/screen-access.js +48 -0
  49. package/dist/app/secret-mint-body.d.ts +10 -0
  50. package/dist/app/secret-mint-body.js +140 -0
  51. package/dist/app/secrets-edit-body.d.ts +8 -0
  52. package/dist/app/secrets-edit-body.js +76 -0
  53. package/dist/app/use-embedded-screen.d.ts +6 -0
  54. package/dist/app/use-embedded-screen.js +19 -0
  55. package/dist/app/variable-chips.d.ts +7 -0
  56. package/dist/app/variable-chips.js +16 -0
  57. package/dist/app/write-failed-error.d.ts +6 -0
  58. package/dist/app/write-failed-error.js +21 -0
  59. package/dist/components/embedded-list-field.d.ts +10 -0
  60. package/dist/components/embedded-list-field.js +259 -0
  61. package/dist/components/grid-cell-for-field.d.ts +25 -0
  62. package/dist/components/grid-cell-for-field.js +31 -0
  63. package/dist/components/multi-select-checkboxes.d.ts +14 -0
  64. package/dist/components/multi-select-checkboxes.js +36 -0
  65. package/dist/components/reference-create-dialog.d.ts +13 -0
  66. package/dist/components/reference-create-dialog.js +46 -0
  67. package/dist/components/related-list-section.d.ts +25 -0
  68. package/dist/components/related-list-section.js +273 -0
  69. package/dist/components/render-edit-action-button.d.ts +22 -0
  70. package/dist/components/render-edit-action-button.js +43 -0
  71. package/dist/components/render-edit-logic.d.ts +6 -0
  72. package/dist/components/render-edit-logic.js +63 -0
  73. package/dist/components/render-edit-types.d.ts +209 -0
  74. package/dist/components/render-edit-types.js +1 -0
  75. package/dist/components/render-edit.d.ts +6 -0
  76. package/dist/components/render-edit.js +1169 -0
  77. package/dist/components/render-field.d.ts +38 -0
  78. package/dist/components/render-field.js +544 -0
  79. package/dist/components/render-list.d.ts +117 -0
  80. package/dist/components/render-list.js +232 -0
  81. package/dist/components/write-form-section.d.ts +17 -0
  82. package/dist/components/write-form-section.js +104 -0
  83. package/dist/context/dispatcher-context.d.ts +10 -0
  84. package/{src/context/dispatcher-context.tsx → dist/context/dispatcher-context.js} +16 -29
  85. package/dist/context/draft-storage-context.d.ts +12 -0
  86. package/dist/context/draft-storage-context.js +18 -0
  87. package/dist/context/user-roles-context.d.ts +7 -0
  88. package/{src/context/user-roles-context.tsx → dist/context/user-roles-context.js} +7 -15
  89. package/dist/format-when.d.ts +1 -0
  90. package/{src/format-when.ts → dist/format-when.js} +7 -7
  91. package/dist/hooks/reference-limits.d.ts +3 -0
  92. package/{src/hooks/reference-limits.ts → dist/hooks/reference-limits.js} +0 -1
  93. package/dist/hooks/use-ai-text.d.ts +52 -0
  94. package/dist/hooks/use-ai-text.js +90 -0
  95. package/dist/hooks/use-disclosure.d.ts +7 -0
  96. package/dist/hooks/use-disclosure.js +8 -0
  97. package/dist/hooks/use-form.d.ts +7 -0
  98. package/dist/hooks/use-form.js +36 -0
  99. package/dist/hooks/use-list-url-state.d.ts +43 -0
  100. package/dist/hooks/use-list-url-state.js +131 -0
  101. package/dist/hooks/use-mutation.d.ts +9 -0
  102. package/dist/hooks/use-mutation.js +37 -0
  103. package/dist/hooks/use-query.d.ts +14 -0
  104. package/dist/hooks/use-query.js +118 -0
  105. package/dist/hooks/use-reference-lookup.d.ts +14 -0
  106. package/dist/hooks/use-reference-lookup.js +63 -0
  107. package/dist/hooks/use-store.d.ts +3 -0
  108. package/dist/hooks/use-store.js +38 -0
  109. package/dist/hooks/use-stream-handler.d.ts +14 -0
  110. package/dist/hooks/use-stream-handler.js +93 -0
  111. package/dist/i18n-defaults.d.ts +2 -0
  112. package/dist/i18n-defaults.js +201 -0
  113. package/dist/i18n.d.ts +64 -0
  114. package/dist/i18n.js +166 -0
  115. package/dist/index.d.ts +77 -0
  116. package/dist/index.js +55 -0
  117. package/dist/inside-drawer.d.ts +2 -0
  118. package/{src/inside-drawer.ts → dist/inside-drawer.js} +2 -5
  119. package/dist/page-header-slot.d.ts +2 -0
  120. package/{src/page-header-slot.ts → dist/page-header-slot.js} +2 -5
  121. package/dist/primitives.d.ts +1351 -0
  122. package/dist/primitives.js +73 -0
  123. package/dist/screen-fills-height.d.ts +3 -0
  124. package/dist/screen-fills-height.js +3 -0
  125. package/dist/share-links.d.ts +4 -0
  126. package/dist/share-links.js +11 -0
  127. package/dist/sort-by-accessor.d.ts +5 -0
  128. package/dist/sort-by-accessor.js +16 -0
  129. package/dist/sse/live-events.d.ts +23 -0
  130. package/dist/sse/live-events.js +28 -0
  131. package/dist/tokens.d.ts +83 -0
  132. package/dist/tokens.js +80 -0
  133. package/package.json +16 -9
  134. package/src/__tests__/error-i18n-defaults.test.ts +0 -82
  135. package/src/__tests__/format-when.test.ts +0 -12
  136. package/src/__tests__/i18n.test.tsx +0 -283
  137. package/src/__tests__/merge-search-params-into-initial.test.ts +0 -525
  138. package/src/__tests__/qn.test.ts +0 -83
  139. package/src/__tests__/share-links.test.ts +0 -26
  140. package/src/__tests__/sort-by-accessor.test.ts +0 -48
  141. package/src/__tests__/stringify-nav-params.test.ts +0 -33
  142. package/src/__tests__/use-list-url-state.test.tsx +0 -250
  143. package/src/app/__tests__/action-form-field-labels.test.tsx +0 -92
  144. package/src/app/__tests__/action-form-shim.test.ts +0 -137
  145. package/src/app/__tests__/build-list-query-payload.test.ts +0 -107
  146. package/src/app/__tests__/config-edit-shim.test.ts +0 -57
  147. package/src/app/__tests__/content-editors.test.tsx +0 -128
  148. package/src/app/__tests__/content-preview.test.tsx +0 -184
  149. package/src/app/__tests__/entity-edit-create-search-params.test.tsx +0 -236
  150. package/src/app/__tests__/entity-edit-fill-height.test.tsx +0 -118
  151. package/src/app/__tests__/entity-edit-jsonb-embedded-submit.test.tsx +0 -239
  152. package/src/app/__tests__/entity-list-create-singleton.test.tsx +0 -128
  153. package/src/app/__tests__/entity-list-row-action-entity-target.test.tsx +0 -424
  154. package/src/app/__tests__/entity-list-row-action-icon.test.tsx +0 -248
  155. package/src/app/__tests__/entity-list-row-action-kumiko-actions-view.test.tsx +0 -162
  156. package/src/app/__tests__/entity-list-row-action-refetch.test.tsx +0 -401
  157. package/src/app/__tests__/entity-list-screen-padding.test.tsx +0 -128
  158. package/src/app/__tests__/feature-schema.test.ts +0 -40
  159. package/src/app/__tests__/form-schema.test.ts +0 -247
  160. package/src/app/__tests__/list-daterange-facet.test.ts +0 -165
  161. package/src/app/__tests__/list-filter-facets.test.tsx +0 -521
  162. package/src/app/__tests__/nav.test.ts +0 -198
  163. package/src/app/__tests__/projection-detail-actions.test.tsx +0 -719
  164. package/src/app/__tests__/projection-detail-reference-field.test.tsx +0 -165
  165. package/src/app/__tests__/projection-detail-shim.test.ts +0 -188
  166. package/src/app/__tests__/projection-detail-singleton.test.tsx +0 -191
  167. package/src/app/__tests__/projection-list-bad-shape.test.tsx +0 -152
  168. package/src/app/__tests__/projection-list-reference-column.test.tsx +0 -219
  169. package/src/app/__tests__/projection-list-search-sort.test.tsx +0 -212
  170. package/src/app/__tests__/qualified-names.test.ts +0 -37
  171. package/src/app/__tests__/return-to.test.ts +0 -396
  172. package/src/app/__tests__/row-actions-navigate-tab.test.ts +0 -223
  173. package/src/app/__tests__/row-default-edit-action.test.tsx +0 -324
  174. package/src/app/__tests__/screen-access-allows.test.ts +0 -34
  175. package/src/app/__tests__/secret-mint-body.test.tsx +0 -404
  176. package/src/app/__tests__/variable-chips.test.tsx +0 -70
  177. package/src/app/app-features-context.tsx +0 -25
  178. package/src/app/column-renderers.tsx +0 -68
  179. package/src/app/content-editors.tsx +0 -85
  180. package/src/app/content-preview.tsx +0 -67
  181. package/src/app/custom-screens.tsx +0 -29
  182. package/src/app/dashboard-body.tsx +0 -33
  183. package/src/app/extension-form-submit.tsx +0 -123
  184. package/src/app/extension-sections.tsx +0 -111
  185. package/src/app/form-schema.ts +0 -91
  186. package/src/app/kumiko-screen.tsx +0 -3801
  187. package/src/app/layout-fields.ts +0 -31
  188. package/src/app/list-facets.ts +0 -259
  189. package/src/app/nav.tsx +0 -258
  190. package/src/app/projection-detail-shim.ts +0 -86
  191. package/src/app/reference-facet-bridge.tsx +0 -58
  192. package/src/app/return-to.tsx +0 -234
  193. package/src/app/row-actions.ts +0 -640
  194. package/src/app/screen-access.ts +0 -63
  195. package/src/app/secret-mint-body.tsx +0 -259
  196. package/src/app/secrets-edit-body.tsx +0 -194
  197. package/src/app/use-embedded-screen.ts +0 -27
  198. package/src/app/variable-chips.tsx +0 -39
  199. package/src/app/write-failed-error.ts +0 -27
  200. package/src/components/__tests__/embedded-list-field.test.tsx +0 -531
  201. package/src/components/__tests__/multi-select-checkboxes.test.tsx +0 -162
  202. package/src/components/__tests__/related-list-section-empty-state.test.tsx +0 -143
  203. package/src/components/__tests__/related-list-section.test.tsx +0 -1733
  204. package/src/components/__tests__/render-edit-action-button.test.tsx +0 -205
  205. package/src/components/__tests__/render-edit-hidden-section.test.tsx +0 -128
  206. package/src/components/__tests__/render-edit-logic.test.ts +0 -314
  207. package/src/components/__tests__/render-edit-screen-description.test.tsx +0 -152
  208. package/src/components/__tests__/render-edit-submit-actions.test.tsx +0 -460
  209. package/src/components/__tests__/render-field-app-locale.test.tsx +0 -142
  210. package/src/components/__tests__/render-field-enum-option.test.tsx +0 -99
  211. package/src/components/__tests__/render-field-icon-derivation.test.tsx +0 -119
  212. package/src/components/__tests__/render-field-json-format.test.tsx +0 -164
  213. package/src/components/__tests__/render-field-money-embedded-list-consistency.test.tsx +0 -212
  214. package/src/components/__tests__/render-field-money-roundtrip.test.tsx +0 -217
  215. package/src/components/__tests__/render-field-number-grouping.test.tsx +0 -76
  216. package/src/components/__tests__/render-field-number-unit.test.tsx +0 -227
  217. package/src/components/__tests__/render-field-password-format.test.tsx +0 -101
  218. package/src/components/__tests__/render-field-select-display.test.tsx +0 -134
  219. package/src/components/__tests__/render-field-unit-format.test.tsx +0 -107
  220. package/src/components/__tests__/render-field-unsupported-types.test.tsx +0 -195
  221. package/src/components/__tests__/render-list-toolbar-icon-only.test.tsx +0 -146
  222. package/src/components/__tests__/write-form-section.test.tsx +0 -375
  223. package/src/components/embedded-list-field.tsx +0 -354
  224. package/src/components/grid-cell-for-field.tsx +0 -88
  225. package/src/components/multi-select-checkboxes.tsx +0 -93
  226. package/src/components/reference-create-dialog.tsx +0 -91
  227. package/src/components/related-list-section.tsx +0 -491
  228. package/src/components/render-edit-action-button.tsx +0 -109
  229. package/src/components/render-edit-logic.ts +0 -85
  230. package/src/components/render-edit-types.ts +0 -226
  231. package/src/components/render-edit.tsx +0 -1871
  232. package/src/components/render-field.tsx +0 -951
  233. package/src/components/render-list.tsx +0 -593
  234. package/src/components/write-form-section.tsx +0 -198
  235. package/src/context/draft-storage-context.tsx +0 -39
  236. package/src/hooks/__tests__/use-ai-text.test.tsx +0 -177
  237. package/src/hooks/__tests__/use-disclosure.test.tsx +0 -25
  238. package/src/hooks/__tests__/use-form.test.tsx +0 -65
  239. package/src/hooks/__tests__/use-mutation.test.tsx +0 -77
  240. package/src/hooks/__tests__/use-query.test.tsx +0 -149
  241. package/src/hooks/__tests__/use-stream-handler.test.tsx +0 -107
  242. package/src/hooks/use-ai-text.ts +0 -172
  243. package/src/hooks/use-disclosure.ts +0 -20
  244. package/src/hooks/use-form.ts +0 -78
  245. package/src/hooks/use-list-url-state.ts +0 -207
  246. package/src/hooks/use-mutation.ts +0 -61
  247. package/src/hooks/use-query.ts +0 -166
  248. package/src/hooks/use-reference-lookup.ts +0 -76
  249. package/src/hooks/use-store.ts +0 -48
  250. package/src/hooks/use-stream-handler.ts +0 -134
  251. package/src/i18n-defaults.ts +0 -240
  252. package/src/i18n.tsx +0 -286
  253. package/src/index.ts +0 -279
  254. package/src/primitives.tsx +0 -1567
  255. package/src/screen-fills-height.ts +0 -3
  256. package/src/share-links.ts +0 -12
  257. package/src/sort-by-accessor.ts +0 -20
  258. package/src/sse/live-events.tsx +0 -56
  259. package/src/tokens.tsx +0 -170
@@ -1,226 +0,0 @@
1
- import type {
2
- EntityDefinition,
3
- EntityEditScreenDefinition,
4
- IconKey,
5
- RowAction,
6
- RowActionDrawer,
7
- } from "@cosmicdrift/kumiko-framework/ui-types";
8
- import type {
9
- FormSnapshot,
10
- FormValues,
11
- SubmitResult,
12
- Translate,
13
- } from "@cosmicdrift/kumiko-headless";
14
- import type { ReactNode } from "react";
15
- import type * as z from "zod";
16
-
17
- export type RenderEditProps<TValues extends FormValues, TCtx = unknown> = {
18
- readonly screen: EntityEditScreenDefinition;
19
- readonly entity: EntityDefinition;
20
- readonly featureName: string;
21
- readonly initial: TValues;
22
- /** Real entity id for extension-section mounts (set-value UI). Mount AND
23
- * persistExtensions resolve it via `resolveExtensionEntityId(entityIdProp,
24
- * vm.id)` — the same value, so the section doesn't mount editable against
25
- * one id while persist writes against another (or none at all).
26
- * Omitting (undefined) = fallback to `vm.id` (= values["id"]), which the
27
- * update form carries for the existing row. Explicit `null` = "no entity"
28
- * (create mode / no extension persistence). */
29
- readonly entityId?: string | null;
30
- /** Already-persisted extension values (e.g. `record.customFields`) for
31
- * extension-section mounts. Lets the section display its current stock
32
- * during edit. Only the update body provides this. */
33
- readonly extensionInitialValues?: Readonly<Record<string, unknown>>;
34
- /** Standard single-write submit path. Ignored when `customSubmit` is set
35
- * (configEdit screens dispatch multiple writes per submit, where a single
36
- * writeCommand makes no sense). */
37
- readonly writeCommand?: string;
38
- /** Override for the submit pipeline. When set, runs controller.validate()
39
- * and then customSubmit(snapshot) instead of controller.submit(). On
40
- * success the form state rebases so that isUnchanged/isDirty become false
41
- * again — without that, save button and banner stay stale. */
42
- readonly customSubmit?: (snapshot: FormSnapshot<TValues>) => Promise<SubmitResult<unknown>>;
43
- readonly translate?: Translate;
44
- readonly ctx?: TCtx;
45
- readonly schema?: z.ZodType;
46
- readonly onSubmit?: (result: SubmitResult<unknown>) => void;
47
- readonly payloadMode?: "values" | "changes";
48
- readonly buildPayload?: (snapshot: FormSnapshot<TValues>) => unknown;
49
- /** Prefix to strip from server validation issue paths before mapping them
50
- * onto form fields — see SubmitConfig.serverFieldPathPrefix. Only needed
51
- * when buildPayload nests the form values under a key. */
52
- readonly serverFieldPathPrefix?: string;
53
- readonly onDelete?: () => Promise<void> | void;
54
- readonly onCancel?: () => void;
55
- readonly onReload?: () => void;
56
- /** Fires when the form gains or loses unsaved input (field changes or a
57
- * dirty extension section). Lets a host such as a drawer guard closing. */
58
- readonly onDirtyChange?: (dirty: boolean) => void;
59
- /** Copy-link action (issue #912) — only set in update mode (create mode
60
- * has no entity id yet, hence no permalink). The callback is already fully
61
- * bound (URL building + clipboard happen outside, in
62
- * `@cosmicdrift/kumiko-renderer-web`'s RoutedScreen — this platform-neutral
63
- * package must not touch `navigator`/`window`, see
64
- * guard-renderer-boundaries). undefined = no button. */
65
- readonly onCopyLink?: () => Promise<void> | void;
66
- /** Header action buttons, rendered before the built-in copy-link/
67
- * delete/cancel/save controls. Each callback is already fully
68
- * bound (screen-type/nav/dispatcher resolution happens in the caller,
69
- * same split as `onCopyLink`) — RenderEdit only wires the button, its
70
- * busy state and its confirm dialog. */
71
- readonly actions?: readonly RenderEditAction[];
72
- /** Opens a relatedList section row's drawer-kind action (fw#2710).
73
- * RenderEdit has no `schema` to resolve the target actionForm itself —
74
- * the caller (ProjectionDetailBody, which does have schema) supplies the
75
- * opener and owns the actual Drawer state/rendering. Only projectionDetail
76
- * passes this — the boot validator rejects relatedList sections on every
77
- * other screen type that shares this layout. */
78
- readonly onRelatedListDrawerAction?: (
79
- action: RowActionDrawer,
80
- initialValues: Readonly<Record<string, unknown>> | undefined,
81
- ) => void;
82
- /** i18n key for the submit button. Default: "kumiko.actions.save".
83
- * Action forms (tier 2.7d) pass their screen.submitLabel here so that
84
- * "Save" can be replaced by domain-specific strings ("Approve" /
85
- * "Dispatch" / etc.). */
86
- readonly submitLabel?: string;
87
- /** Visual style of the submit button (actionForm `submitStyle`). Default "primary". */
88
- readonly submitVariant?: "primary" | "danger";
89
- /** Context box above the drawer form (title + optional subtitle, already resolved). */
90
- readonly summary?: { readonly title: string; readonly subtitle?: string };
91
- /** Per-field extra content inline after the label (e.g.
92
- * ConfigSourceBadge). Called with the field name, returns a ReactNode or
93
- * undefined. */
94
- readonly labelAppendix?: (fieldName: string) => ReactNode | undefined;
95
- /** Per-field extra content below the input (e.g. ConfigCascadeView).
96
- * Called with the field name, returns a ReactNode or undefined. */
97
- readonly fieldAppendix?: (fieldName: string) => ReactNode | undefined;
98
- /** Controlled mode (issue #1887): fires on every values-snapshot change
99
- * (typing, `patch(...)` from outside) with the current values. `changes`
100
- * is the delta against the initial values — same semantics as
101
- * `payloadMode: "changes"` — so a caller never overwrites unseen fields.
102
- * `valid` is a pure dry-run parse against `schema` (not a
103
- * `controller.validate()` call), so it does not paint field errors into
104
- * the UI and can diverge from the currently rendered `snapshot.errors` —
105
- * always `true` without `schema`. A caller that patches a fresh object
106
- * reference on every call must not do so unconditionally: `setValues` is
107
- * a no-op when the merged value is reference-equal to the current one,
108
- * so only a converging patch settles instead of looping. Without this
109
- * prop, existing behavior is unchanged. `onControlsReady` is guaranteed
110
- * to have already fired by the time the mount-time `onChange` call
111
- * happens, so a caller patching dependent fields from inside `onChange`
112
- * never has to guard against `controls` being undefined. */
113
- readonly onChange?: (state: RenderEditChangeState<TValues>) => void;
114
- /** Controlled mode (issue #1887): called once after mount, hands the
115
- * caller `patch`/`validate`/`getValues` bound to this RenderEdit
116
- * instance — addressable from outside without a remount. `patch` merges
117
- * only the given keys (existing `controller.setValues` semantics),
118
- * values on unmentioned fields stay untouched. `validate` runs without a
119
- * write and reports field issues via `snapshot.errors` on the field
120
- * itself rather than as a summary banner. Without this prop, existing
121
- * behavior is unchanged. */
122
- readonly onControlsReady?: (controls: RenderEditControls<TValues>) => void;
123
- /** Renders only these fields (by `field` name from the layout) — section
124
- * order, title, and visibility still come from the layout, so the caller
125
- * doesn't duplicate its shape. A section with no fields left after
126
- * filtering is dropped entirely (not rendered empty). Submit validation
127
- * is scoped to the actually-rendered fields the same way — a required
128
- * field outside this list doesn't block submit. Omitting this prop keeps
129
- * unchanged behavior. Read once at mount for `controller.submit()`'s
130
- * validation scope (the underlying `useForm` controller is mount-lived);
131
- * rendering and `controls.validate()` do stay reactive to later changes. */
132
- readonly fields?: readonly string[];
133
- /** Locked state (issue #1896): every rendered field and the submit button
134
- * go visibly inactive, no write possible. For cases where input becomes
135
- * moot — e.g. Solon's editor pointing at an existing record instead of
136
- * creating a new one. Extension sections are out of scope: RenderEdit has
137
- * no way to force-disable an arbitrary registered component. Omitting
138
- * this prop keeps unchanged behavior.
139
- *
140
- * ponytail: direct-consumer only — kumiko-screen.tsx's RenderEdit call
141
- * sites pass explicit prop lists without a spread and never forward
142
- * `disabled`, so a screen-driven app can't set the locked state today.
143
- * Upgrade path if that's needed: thread a screen-spec flag through to
144
- * `EntityEditCreateBody`/`EntityEditEditBody`. */
145
- readonly disabled?: boolean;
146
- /** Renders the fields without RenderEdit's own action bar (save, cancel,
147
- * delete, copy-link). For hosts that put those controls into their own
148
- * chrome — a drawer footer, a wizard shell — and drive the write through
149
- * `onControlsReady`'s `submit`. Omitting this prop keeps unchanged
150
- * behavior. */
151
- readonly hideActions?: boolean;
152
- /** "form" (default) — every field renders as its Input widget, disabled
153
- * when `field.readOnly`, unchanged behavior. "text" renders a
154
- * `field.readOnly` field as plain text instead of a disabled Input
155
- * (ProjectionDetailBody's read view, fw#2245) — editable fields are
156
- * unaffected either way, so this only changes forms that already have
157
- * readOnly fields. */
158
- readonly valueDisplay?: "form" | "text";
159
- /** Suppresses every section's own title (fields-section header, relatedList
160
- * Section title) AND the form's own top-level title/subtitle — for a host
161
- * that already renders that label itself elsewhere (e.g. a tab strip
162
- * whose label duplicates it, or a page-level header above RenderEdit).
163
- * Without this, the form's title (`screen:<id>.title` / `screen.id`)
164
- * renders unconditionally regardless of section-level suppression — a
165
- * host relying on this prop to fully own the heading otherwise sees a
166
- * redundant title above its content. Omitting this prop keeps unchanged
167
- * behavior. */
168
- readonly hideSectionTitles?: boolean;
169
- /** Screen body fills the shell height: the form gets `fillHeight` and
170
- * `stickyActions` (sections scroll, footer pinned). Set by KumikoScreen for
171
- * screens with `fillHeight !== false`; dialogs and other embedded hosts
172
- * omit it and keep document-flow height. */
173
- readonly fillScreenHeight?: boolean;
174
- /** Extra content rendered above the card, sharing its left padding and
175
- * width — for a host with its own header region (title/metrics/tabs)
176
- * that would otherwise render as unpadded siblings before RenderEdit.
177
- * Omitting this prop keeps unchanged behavior. */
178
- readonly headerRegion?: ReactNode | ((headerSlot: ReactNode | undefined) => ReactNode);
179
- /** resolves an `EditFieldsSection`/`EditExtensionSection`/
180
- * `EditRelatedListSection`/`EditWriteFormSection`'s own `actions` into
181
- * already-bound buttons, rendered in that section's title row — same
182
- * split as `onCopyLink`/header `actions`: RenderEdit has no dispatcher/nav
183
- * context of its own, so the caller (which does) resolves each RowAction
184
- * against the record being edited. Returns `undefined`/`[]` to render no
185
- * actions for that section. */
186
- readonly buildSectionActions?: (
187
- actions: readonly RowAction[],
188
- ) => readonly RenderEditAction[] | undefined;
189
- };
190
-
191
- export type RenderEditAction = {
192
- readonly id: string;
193
- readonly label: string;
194
- readonly onPress: () => void | Promise<void>;
195
- readonly style?: "primary" | "secondary" | "danger";
196
- readonly confirm?: string;
197
- readonly confirmLabel?: string;
198
- /** Overrides the default "danger implies a confirm dialog" rule. Schema-driven
199
- * navigate/drawer actions set it to false: the colour marks the action as
200
- * destructive, but the target form is the confirmation. */
201
- readonly confirmRequired?: boolean;
202
- /** Resolved icon (author `RowAction.icon` or the id-derived default) —
203
- * drives both the icon-left-of-text render and the icon-only collapse
204
- * rule (see `shouldRenderActionsIconOnly`). */
205
- readonly icon?: IconKey;
206
- };
207
-
208
- export type RenderEditChangeState<TValues extends FormValues> = {
209
- readonly values: TValues;
210
- readonly changes: Partial<TValues>;
211
- readonly dirty: boolean;
212
- readonly valid: boolean;
213
- readonly submitting: boolean;
214
- };
215
-
216
- export type RenderEditControls<TValues extends FormValues> = {
217
- readonly patch: (partial: Partial<TValues>) => void;
218
- readonly validate: () => boolean;
219
- readonly getValues: () => TValues;
220
- /** Runs the same pipeline the built-in save button runs: validation,
221
- * `customSubmit`/`writeCommand`, extension-section persistence, draft
222
- * discard, state rebase. Unlike the button it carries no unchanged-form
223
- * guard — a host showing a pre-filled proposal must be able to accept it
224
- * untouched. */
225
- readonly submit: () => Promise<void>;
226
- };