@object-ui/plugin-form 17.6.0 → 18.0.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.
- package/CHANGELOG.md +4991 -0
- package/README.md +522 -80
- package/dist/DrawerForm.d.ts +42 -3
- package/dist/DrawerForm.d.ts.map +1 -1
- package/dist/EmbeddableForm.d.ts.map +1 -1
- package/dist/FormAnalytics.d.ts.map +1 -1
- package/dist/LineItemsPanel.d.ts +6 -3
- package/dist/LineItemsPanel.d.ts.map +1 -1
- package/dist/MasterDetailForm.d.ts +79 -38
- package/dist/MasterDetailForm.d.ts.map +1 -1
- package/dist/ModalForm.d.ts +60 -5
- package/dist/ModalForm.d.ts.map +1 -1
- package/dist/ObjectForm.d.ts.map +1 -1
- package/dist/SplitForm.d.ts +49 -3
- package/dist/SplitForm.d.ts.map +1 -1
- package/dist/TabbedForm.d.ts +75 -5
- package/dist/TabbedForm.d.ts.map +1 -1
- package/dist/WizardForm.d.ts +145 -38
- package/dist/WizardForm.d.ts.map +1 -1
- package/dist/autoLayout.d.ts +113 -8
- package/dist/autoLayout.d.ts.map +1 -1
- package/dist/closedAffordanceNotice.d.ts +14 -0
- package/dist/closedAffordanceNotice.d.ts.map +1 -0
- package/dist/customFieldsMerge.d.ts +29 -0
- package/dist/customFieldsMerge.d.ts.map +1 -0
- package/dist/deriveMasterDetail.d.ts +82 -29
- package/dist/deriveMasterDetail.d.ts.map +1 -1
- package/dist/fieldGroups.d.ts +189 -0
- package/dist/fieldGroups.d.ts.map +1 -1
- package/dist/fieldWriteGate.d.ts +136 -0
- package/dist/fieldWriteGate.d.ts.map +1 -0
- package/dist/flatFields.d.ts +11 -2
- package/dist/flatFields.d.ts.map +1 -1
- package/dist/formChrome.d.ts +55 -0
- package/dist/formChrome.d.ts.map +1 -0
- package/dist/index.d.ts +149 -26
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3984 -2332
- package/dist/index.umd.cjs +1 -1
- package/dist/initialFieldFocus.d.ts +23 -0
- package/dist/initialFieldFocus.d.ts.map +1 -0
- package/dist/initialRecord.d.ts +72 -0
- package/dist/initialRecord.d.ts.map +1 -0
- package/dist/loadFailure.d.ts +28 -0
- package/dist/loadFailure.d.ts.map +1 -0
- package/dist/masterDetailTx.d.ts.map +1 -1
- package/dist/occSave.d.ts +6 -1
- package/dist/occSave.d.ts.map +1 -1
- package/dist/recordInvalidation.d.ts +33 -0
- package/dist/recordInvalidation.d.ts.map +1 -0
- package/dist/recordReadGate.d.ts +34 -0
- package/dist/recordReadGate.d.ts.map +1 -0
- package/dist/sanitize.d.ts +272 -5
- package/dist/sanitize.d.ts.map +1 -1
- package/dist/schemaDefaults.d.ts +104 -9
- package/dist/schemaDefaults.d.ts.map +1 -1
- package/dist/sectionFields.d.ts +67 -2
- package/dist/sectionFields.d.ts.map +1 -1
- package/dist/sectionGroups.d.ts +62 -0
- package/dist/sectionGroups.d.ts.map +1 -0
- package/dist/sectionPredicateDiagnostic.d.ts +38 -0
- package/dist/sectionPredicateDiagnostic.d.ts.map +1 -0
- package/dist/submitTarget.d.ts +136 -0
- package/dist/submitTarget.d.ts.map +1 -0
- package/dist/successBehavior.d.ts +44 -25
- package/dist/successBehavior.d.ts.map +1 -1
- package/dist/thankYouRedirectCountdown.d.ts +1 -1
- package/dist/uploadGate.d.ts +35 -0
- package/dist/uploadGate.d.ts.map +1 -0
- package/dist/writePayload.d.ts +87 -0
- package/dist/writePayload.d.ts.map +1 -0
- package/package.json +13 -12
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deriveMasterDetail.d.ts","sourceRoot":"","sources":["../src/deriveMasterDetail.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"deriveMasterDetail.d.ts","sourceRoot":"","sources":["../src/deriveMasterDetail.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAgBH,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEvE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC9B;AAQD,kEAAkE;AAClE,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC,CAqClF;AA+CD;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,qBAAqB,GAAG,SAAS,EAC9C,gBAAgB,EAAE,MAAM,GACvB,MAAM,GAAG,SAAS,CAWpB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,CAC3B,WAAW,EAAE,qBAAqB,GAAG,SAAS,EAC9C,IAAI,EAAE;IAAE,YAAY,EAAE,iBAAiB,CAAC;IAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7G,UAAU,EAAE,CAYd;AA2GD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,UAAU,EAAE,GAAG,SAAS,EACjC,WAAW,EAAE,qBAAqB,GAAG,SAAS,EAC9C,IAAI,EAAE;IAAE,YAAY,EAAE,iBAAiB,CAAA;CAAE,GACxC,UAAU,EAAE,CAqCd;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,qBAAqB,GAAG,SAAS,EAC9C,IAAI,GAAE;IAAE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CAAO,GAC5D,MAAM,EAAE,CAKV;AAED,+BAA+B;AAC/B,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;AAiBzC,gFAAgF;AAChF,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAE5C;;iFAEiF;AACjF,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAE3C;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,qBAAqB,GAAG,SAAS,EAC9C,UAAU,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,EAC5C,IAAI,GAAE;IAAE,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAAO,GACxC,UAAU,CAaZ;AAwBD,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,wEAAwE;IACxE,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,mFAAmF;IACnF,IAAI,EAAE,UAAU,CAAC;IACjB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;+EAC2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,qBAAqB,GAAG,SAAS,EAC9C,gBAAgB,EAAE,MAAM,EACxB,QAAQ,EAAE;IACR,YAAY,EAAE,iBAAiB,CAAC;IAChC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;CACnC,GACA,aAAa,CAoBf"}
|
package/dist/fieldGroups.d.ts
CHANGED
|
@@ -19,4 +19,193 @@ import { FormField, ObjectFormSection } from '@object-ui/types';
|
|
|
19
19
|
* into ObjectForm's existing section-render path.
|
|
20
20
|
*/
|
|
21
21
|
export declare function deriveFieldGroupSections(fields: FormField[], fieldGroups: unknown): ObjectFormSection[] | null;
|
|
22
|
+
/**
|
|
23
|
+
* THE ONE ROW RULE (objectui#9849 step two — director ruling letter E,
|
|
24
|
+
* item 2): 「The divider row exists iff `title || description`; with
|
|
25
|
+
* `description` only it is the blurb-only row (objectui#9835's shape), on
|
|
26
|
+
* every arm — one rule」.
|
|
27
|
+
*
|
|
28
|
+
* Every arm asks this one function, both to decide whether a row is drawn and
|
|
29
|
+
* — because 「the collapse control lives on the row」 (item 3) — whether a
|
|
30
|
+
* collapse control has anywhere to live. It replaced a four-way gate union
|
|
31
|
+
* (one answer per arm) that the ruling deleted.
|
|
32
|
+
*
|
|
33
|
+
* ⚠️ The row is PRESENTATION only. Whether the group is gated by its ADR-0089
|
|
34
|
+
* `visibleWhen` predicate and objectui#6236 membership claim does NOT depend
|
|
35
|
+
* on it (item 1) — see `projectSectionDivider`.
|
|
36
|
+
*/
|
|
37
|
+
export declare function sectionDrawsDividerRow(title?: string, description?: string): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* The section configuration a divider row is projected FROM, already resolved
|
|
40
|
+
* by the arm that owns each resolution.
|
|
41
|
+
*
|
|
42
|
+
* ⚠️ `collapse` arrives RESOLVED — by `resolveSectionCollapse` below, the one
|
|
43
|
+
* `collapsed` / `collapsible` resolution every arm calls. It is resolved before
|
|
44
|
+
* this projection rather than inside it because the arm needs the same answer
|
|
45
|
+
* a second time: whether to take the section's fields out of the DOM.
|
|
46
|
+
*/
|
|
47
|
+
export interface SectionDividerSource {
|
|
48
|
+
/** Section identity; spells the row's `name`. */
|
|
49
|
+
key: string | number;
|
|
50
|
+
/** The heading, already resolved through `sectionLabel` where the arm does that. */
|
|
51
|
+
title?: string;
|
|
52
|
+
/** The authored blurb (spec `FormSection.description`). */
|
|
53
|
+
description?: string;
|
|
54
|
+
/** ADR-0089 `FormSection.visibleWhen` (#6111), unevaluated. */
|
|
55
|
+
visibleWhen?: unknown;
|
|
56
|
+
/**
|
|
57
|
+
* The fault direction of {@link visibleWhen}, copied onto the row unchanged
|
|
58
|
+
* (`ObjectFormSection.visibleWhenFault`, objectui#13055).
|
|
59
|
+
*/
|
|
60
|
+
visibleWhenFault?: ObjectFormSection['visibleWhenFault'];
|
|
61
|
+
/** The objectui#6236 membership claim: RESOLVED (post-FLS) member names. */
|
|
62
|
+
members: string[];
|
|
63
|
+
/** Read by one arm only — see `projectSectionDivider`. */
|
|
64
|
+
className?: string;
|
|
65
|
+
/** Resolved by `resolveSectionCollapse`, ⛔ never here. */
|
|
66
|
+
collapse?: {
|
|
67
|
+
collapsible?: boolean;
|
|
68
|
+
collapsed?: boolean;
|
|
69
|
+
onToggle?: () => void;
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* The loud diagnostic director ruling letter E, item 3 orders for a group that
|
|
74
|
+
* declares `collapsible` (or `collapsed`) but yields neither a heading nor a
|
|
75
|
+
* blurb: 「The collapse control lives on the row. A group that … yields neither
|
|
76
|
+
* title nor description has nowhere to host the control ⇒ a loud diagnostic at
|
|
77
|
+
* validation or render …, ⛔ never fields removed from the DOM with no control」.
|
|
78
|
+
*
|
|
79
|
+
* Emitted at RENDER, through the channel this package already uses for
|
|
80
|
+
* renderer-side author mistakes — a once-per-occurrence `console.warn`, the
|
|
81
|
+
* voice of `warnSectionMemberExcludedByFields` in `sectionFields.ts`. ⛔ It
|
|
82
|
+
* only warns: the resolution below keeps such a group OPEN, so its fields stay
|
|
83
|
+
* reachable whatever the warning's reader does.
|
|
84
|
+
*
|
|
85
|
+
* The first sentence is the ruling's own wording, verbatim; the pin that holds
|
|
86
|
+
* it reads it from this function, so the two cannot drift.
|
|
87
|
+
*/
|
|
88
|
+
export declare function headinglessCollapseWarning(where: string): string;
|
|
89
|
+
/**
|
|
90
|
+
* Forget which sections were already reported — for pins only, so each row
|
|
91
|
+
* observes its own first report. The dedupe is per module instance, and this
|
|
92
|
+
* module is internal (the package barrel does not re-export it).
|
|
93
|
+
*/
|
|
94
|
+
export declare function resetHeadinglessCollapseWarnings(): void;
|
|
95
|
+
/**
|
|
96
|
+
* Resolve a section's authored `collapsed` / `collapsible` pair into what the
|
|
97
|
+
* page draws: whether its row is a disclosure control, whether its fields are
|
|
98
|
+
* out of the DOM right now, and what toggles them.
|
|
99
|
+
*
|
|
100
|
+
* ⭐ THE ONE RESOLUTION (objectui#9849 — director ruling letter E, item 4:
|
|
101
|
+
* 「the three `collapsed` / `collapsible` resolutions converge to the
|
|
102
|
+
* declaration-based one objectui#9780 established」). Every arm calls it: the
|
|
103
|
+
* default arm, both `DrawerForm` pushes and — since step two, per item 1's
|
|
104
|
+
* 「on every arm」 — both stacked `ModalForm` pushes.
|
|
105
|
+
*
|
|
106
|
+
* The rules, each objectui#9780's (maintainer ruling 2026-09-18, letter A):
|
|
107
|
+
*
|
|
108
|
+
* - `collapsed` IMPLIES `collapsible`. "Collapsed by default" is an everyday
|
|
109
|
+
* intent and `collapsed: true` its most natural spelling, so that spelling
|
|
110
|
+
* installs the control.
|
|
111
|
+
* - `collapsible: false` WITH `collapsed: true` is the same contradiction and
|
|
112
|
+
* resolves the same way — collapsed wins, the control is present.
|
|
113
|
+
* - The control is read off the DECLARATION, ⛔ never off the live state:
|
|
114
|
+
* deriving it from the live state would delete the control the moment the
|
|
115
|
+
* user opened the section.
|
|
116
|
+
* - A section declaring neither member is untouched.
|
|
117
|
+
* - ⭐ A section is only ever collapsed when it is collapsible, and it is only
|
|
118
|
+
* collapsible when it has a divider row to carry the control — which, by
|
|
119
|
+
* the one row rule (`sectionDrawsDividerRow`), is exactly when it yields a
|
|
120
|
+
* heading or a blurb. So fields leave the DOM only while a control that
|
|
121
|
+
* brings them back is on the page.
|
|
122
|
+
* - ⭐ A section that declares the pair and yields NEITHER is rendered open
|
|
123
|
+
* and reported (`headinglessCollapseWarning`) — letter E item 3.
|
|
124
|
+
*/
|
|
125
|
+
export declare function resolveSectionCollapse(declared: {
|
|
126
|
+
collapsible?: boolean;
|
|
127
|
+
collapsed?: boolean;
|
|
128
|
+
}, host: {
|
|
129
|
+
/** The live state the user has toggled this section to, if any. */
|
|
130
|
+
live: boolean | undefined;
|
|
131
|
+
/** The row the section yields — the one row rule decides from these two. */
|
|
132
|
+
title: string | undefined;
|
|
133
|
+
description: string | undefined;
|
|
134
|
+
/**
|
|
135
|
+
* Who is asking and about which section, for the diagnostic only — e.g.
|
|
136
|
+
* `ObjectForm section 2 of object 'invoice'`. Also its dedupe key.
|
|
137
|
+
*/
|
|
138
|
+
where: string;
|
|
139
|
+
/** Record the next live state for this section. */
|
|
140
|
+
setCollapsed: (next: boolean) => void;
|
|
141
|
+
}): {
|
|
142
|
+
collapsible: boolean;
|
|
143
|
+
collapsed: boolean;
|
|
144
|
+
onToggle?: () => void;
|
|
145
|
+
};
|
|
146
|
+
/**
|
|
147
|
+
* Project one section configuration onto the `section-divider` row it draws.
|
|
148
|
+
*
|
|
149
|
+
* ⭐ THIS IS THE ONE PATH (objectui#9849, triage ruling 2026-09-18:
|
|
150
|
+
* 「让 section 配置到 divider 的投影只有一条路径」). Before it, six sites across
|
|
151
|
+
* `ObjectForm.tsx`, `ModalForm.tsx` and `DrawerForm.tsx` each rebuilt the row
|
|
152
|
+
* key by key, and a key one of them forgot was invisible to the author. A key
|
|
153
|
+
* added here is added for every arm at once, and a key dropped here is dropped
|
|
154
|
+
* for every arm at once, which is what makes the loss visible instead of
|
|
155
|
+
* silent.
|
|
156
|
+
*
|
|
157
|
+
* ⭐ AND ONE RULE FOR WHICH ROW (director ruling letter E, maintainer 「同意」).
|
|
158
|
+
* There is no per-arm gate any more — the enumerated four-way union this
|
|
159
|
+
* function used to take as a parameter was deleted by that ruling:
|
|
160
|
+
*
|
|
161
|
+
* 1. 「Group-level semantics are independent of the heading」 — the ADR-0089
|
|
162
|
+
* `visibleWhen` predicate and the objectui#6236 membership claim ride
|
|
163
|
+
* EVERY row this function returns, so a headingless group is never
|
|
164
|
+
* un-gated, and the claim names only the group's own resolved members, so
|
|
165
|
+
* its predicate never hides more than the group it names.
|
|
166
|
+
* 2. The VISIBLE row exists iff `title || description`
|
|
167
|
+
* (`sectionDrawsDividerRow`); with `description` only, it is the blurb-only
|
|
168
|
+
* row — no heading span, just the blurb (objectui#9835's shape).
|
|
169
|
+
* 3. A group with neither, that authored a predicate, still needs a carrier
|
|
170
|
+
* for item 1: it gets a CHROME-LESS gate row — no `label`, no
|
|
171
|
+
* `description`, so `SectionDivider` renders nothing — which exists only
|
|
172
|
+
* to carry the predicate and the claim. It is the same shape `TabbedForm`
|
|
173
|
+
* already emits for a degraded single-section form, spelled
|
|
174
|
+
* `__section_gate_` like that one. A group with neither and no predicate
|
|
175
|
+
* returns no row at all: nothing to draw, nothing to gate.
|
|
176
|
+
*
|
|
177
|
+
* The key set, and who owns each member:
|
|
178
|
+
*
|
|
179
|
+
* - `label` — the heading. The arm resolves i18n before handing it over.
|
|
180
|
+
* - `description` — the authored blurb (objectui#9779 / #9834 / #9849).
|
|
181
|
+
* - `visibleWhen` — ADR-0089's section predicate (#6111). The renderer
|
|
182
|
+
* evaluates it on this pseudo-field with the host predicate scope bound
|
|
183
|
+
* (#6010), so copying it here is what makes the authored predicate reach an
|
|
184
|
+
* evaluator at all.
|
|
185
|
+
* - `visibleWhenFault` — the fault direction of that predicate, emitted only
|
|
186
|
+
* when the section carries one (a field group's: `'hidden'`,
|
|
187
|
+
* objectui#13055). The renderer reads it for the divider's fault fallback.
|
|
188
|
+
* - `fields` — the objectui#6236 membership claim: RESOLVED member names, so
|
|
189
|
+
* the predicate gates the whole group and not just the heading. The form
|
|
190
|
+
* renderer also ends the group's field grid where the claim ends
|
|
191
|
+
* (`splitAtUntitledRuns`, `@object-ui/components`, objectui#11777), which is
|
|
192
|
+
* how an untitled section after it — the trailing ungrouped bucket, which
|
|
193
|
+
* gets no row here — is drawn as its own block instead of under this
|
|
194
|
+
* heading. A row that dropped the claim would put those fields back under it.
|
|
195
|
+
* - `colSpan` — see `DIVIDER_COL_SPAN`.
|
|
196
|
+
* - `collapsible` / `collapsed` / `onToggle` — on the visible row only (the
|
|
197
|
+
* control lives on the row), and only when the arm hands over a resolved
|
|
198
|
+
* `collapse`; see `SectionDividerSource`.
|
|
199
|
+
* - `className` — emitted only when the arm hands one over. objectstack#13626
|
|
200
|
+
* ("retire the reads", maintainer ruling 2026-09-01) took this read off
|
|
201
|
+
* every arm but `ModalForm`'s explicit-sections push, whose residue is
|
|
202
|
+
* preserved here rather than retired in passing: retiring it is a second
|
|
203
|
+
* ruling's job, and `sectionStyleKeysRetired-13626` pins the arms that
|
|
204
|
+
* already dropped it.
|
|
205
|
+
*
|
|
206
|
+
* ⛔ Not read, on any arm: `gridClassName` — a per-section grid needs a
|
|
207
|
+
* per-section form, which the single-form structure these arms share does not
|
|
208
|
+
* have.
|
|
209
|
+
*/
|
|
210
|
+
export declare function projectSectionDivider(source: SectionDividerSource): FormField[];
|
|
22
211
|
//# sourceMappingURL=fieldGroups.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fieldGroups.d.ts","sourceRoot":"","sources":["../src/fieldGroups.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAeH,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,SAAS,EAAE,EACnB,WAAW,EAAE,OAAO,GACnB,iBAAiB,EAAE,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"fieldGroups.d.ts","sourceRoot":"","sources":["../src/fieldGroups.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAeH,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,SAAS,EAAE,EACnB,WAAW,EAAE,OAAO,GACnB,iBAAiB,EAAE,GAAG,IAAI,CAsD5B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAEpF;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,oBAAoB;IACnC,iDAAiD;IACjD,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,oFAAoF;IACpF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;IACzD,4EAA4E;IAC5E,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC;CAClF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQhE;AAGD;;;;GAIG;AACH,wBAAgB,gCAAgC,IAAI,IAAI,CAEvD;AAOD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,EACxD,IAAI,EAAE;IACJ,mEAAmE;IACnE,IAAI,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1B,4EAA4E;IAC5E,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACvC,GACA;IAAE,WAAW,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE,CAWrE;AAWD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+DG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,oBAAoB,GAAG,SAAS,EAAE,CAkC/E"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { SchemaLike } from '@object-ui/core';
|
|
2
|
+
/**
|
|
3
|
+
* The permission surface this module consumes — structurally the subset of
|
|
4
|
+
* `usePermissions()` that answers the write question. Declared structurally so
|
|
5
|
+
* `@object-ui/plugin-form` binds to the two members it actually reads rather
|
|
6
|
+
* than to the whole context type.
|
|
7
|
+
*/
|
|
8
|
+
export interface FieldWritePrincipal {
|
|
9
|
+
isLoaded: boolean;
|
|
10
|
+
checkField(object: string, field: string, action: 'read' | 'write' | 'create'): boolean;
|
|
11
|
+
}
|
|
12
|
+
/** A field-name predicate: `true` when the caller may write that field. */
|
|
13
|
+
export type FieldWriteGate = (fieldName: string) => boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Build the outbound write gate for one object, or `undefined` when there is
|
|
16
|
+
* no resolved principal to ask.
|
|
17
|
+
*
|
|
18
|
+
* `undefined` rather than an always-true function on purpose: the callers hand
|
|
19
|
+
* this straight to `sanitizeFormData`, whose option is absent-or-predicate, so
|
|
20
|
+
* an unresolved principal produces the byte-identical payload it produced
|
|
21
|
+
* before this gate existed.
|
|
22
|
+
*
|
|
23
|
+
* `mode` is required, not optional: it picks the question (objectui#12082),
|
|
24
|
+
* and a container that forgot it would silently strip a create-only caller's
|
|
25
|
+
* whole body again. A mode that writes nothing (`view`) gets the edit
|
|
26
|
+
* question, the stricter of the two.
|
|
27
|
+
*/
|
|
28
|
+
export declare function fieldWriteGate(perms: FieldWritePrincipal | null | undefined, objectName: string, mode: string | undefined): FieldWriteGate | undefined;
|
|
29
|
+
export interface ApplyFieldPermissionsOptions {
|
|
30
|
+
perms: FieldWritePrincipal | null | undefined;
|
|
31
|
+
objectName: string;
|
|
32
|
+
/**
|
|
33
|
+
* The form's mode, which picks the field question (objectui#12082): `create`
|
|
34
|
+
* asks the insert rule, any other mode but `view` the update rule. A
|
|
35
|
+
* `view`-mode form renders everything read-only already.
|
|
36
|
+
*/
|
|
37
|
+
mode?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Optional hint placed on a field the caller may read but not edit, used
|
|
40
|
+
* only when the field declares no description of its own. `ObjectForm`'s
|
|
41
|
+
* simple variant is the one container that shows it.
|
|
42
|
+
*/
|
|
43
|
+
deniedDescription?: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The render half for a FORM: drop what the caller may not READ, and mark what
|
|
47
|
+
* they may read but not WRITE as non-editable.
|
|
48
|
+
*/
|
|
49
|
+
export declare function applyFieldPermissions<T extends Record<string, any>>(fields: T[] | undefined, { perms, objectName, mode, deniedDescription }: ApplyFieldPermissionsOptions): T[] | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* The principal surface {@link gateFormFields} reads: the field-level resolver,
|
|
52
|
+
* the server's effective API operation set for an object (`/me/permissions`
|
|
53
|
+
* `apiOperations`, objectstack#3391; `undefined` means "no effective set",
|
|
54
|
+
* which leaves the object's own affordance standing), and the caller's object
|
|
55
|
+
* grant (`usePermissions().can`, objectui#12082).
|
|
56
|
+
*/
|
|
57
|
+
export interface FormFieldPrincipal extends FieldWritePrincipal {
|
|
58
|
+
can(object: string, action: 'create' | 'update' | 'delete'): boolean;
|
|
59
|
+
getObjectApiOperations?: (object: string) => readonly string[] | undefined;
|
|
60
|
+
}
|
|
61
|
+
export interface GateFormFieldsOptions extends ApplyFieldPermissionsOptions {
|
|
62
|
+
perms: FormFieldPrincipal | null | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* The object schema the form resolved (its `managedBy` bucket and
|
|
65
|
+
* `userActions` opt-ins). `null` while it has not loaded, or when the form
|
|
66
|
+
* has no metadata source, reads as the default bucket.
|
|
67
|
+
*/
|
|
68
|
+
objectSchema: SchemaLike | null | undefined;
|
|
69
|
+
}
|
|
70
|
+
/** The form-level affordance {@link closedFormAffordance} can report closed. */
|
|
71
|
+
export type ClosedFormAffordance = 'create' | 'edit';
|
|
72
|
+
/**
|
|
73
|
+
* Which affordance the form-wide lock found CLOSED for this form, or
|
|
74
|
+
* `undefined` when the lock does not engage (objectui#11000) — closed by the
|
|
75
|
+
* managed-object policy, the effective API operation set or, since
|
|
76
|
+
* objectui#12082, the caller's object grant.
|
|
77
|
+
*
|
|
78
|
+
* It is {@link managedModeLocked}, the very predicate {@link gateFormFields}
|
|
79
|
+
* disables every drawn field on, read for its reason: `create` for a create
|
|
80
|
+
* form, `edit` for an edit form. The locked form's notice
|
|
81
|
+
* (`ClosedAffordanceNotice`) and the wizard's navigation gate read THIS, not a
|
|
82
|
+
* verdict of their own, so a form cannot explain a lock it did not draw, nor
|
|
83
|
+
* draw one it does not explain.
|
|
84
|
+
*
|
|
85
|
+
* A per-field lock never answers here: a field the caller may read but not
|
|
86
|
+
* edit ({@link applyFieldPermissions}) or a field declared `readonly` locks
|
|
87
|
+
* that one field while the form's affordance stays open.
|
|
88
|
+
*/
|
|
89
|
+
export declare function closedFormAffordance({ perms, objectName, mode, objectSchema, }: Pick<GateFormFieldsOptions, 'perms' | 'objectName' | 'mode' | 'objectSchema'>): ClosedFormAffordance | undefined;
|
|
90
|
+
/**
|
|
91
|
+
* The ONE field-gate step every `ObjectForm` layout draws its RESOLVED fields
|
|
92
|
+
* through (objectui#10612): the default arm (flat and sectioned), `DrawerForm`
|
|
93
|
+
* and `ModalForm` (sections, derived field groups and flat), and `TabbedForm`,
|
|
94
|
+
* `SplitForm` and `WizardForm` (sections).
|
|
95
|
+
*
|
|
96
|
+
* Two gates, in one pass, so no layout can apply one and skip the other:
|
|
97
|
+
*
|
|
98
|
+
* 1. field-level security — {@link applyFieldPermissions}: drop what the
|
|
99
|
+
* caller may not READ, lock what they may read but not WRITE;
|
|
100
|
+
* 2. the form-wide lock — every drawn field is `disabled` when
|
|
101
|
+
* {@link managedModeLocked} says the mode's affordance is closed. Only
|
|
102
|
+
* `disabled`, not `readOnly`: the default arm's lock always drew a
|
|
103
|
+
* disabled input, and the submit button is left as it is.
|
|
104
|
+
*
|
|
105
|
+
* Before this step the lock was stamped by the default arm's field generator
|
|
106
|
+
* alone, so the drawer, modal, tabbed, split and wizard layouts drew live
|
|
107
|
+
* inputs on a managed object whose write the server refuses (objectui#10613,
|
|
108
|
+
* folded into objectui#10612). It runs on the resolved list rather than in a
|
|
109
|
+
* generator, so every drawn field is locked — an inline `customFields` member
|
|
110
|
+
* and an already-built section entry as much as a field generated from the
|
|
111
|
+
* object — which is what "blanket" says.
|
|
112
|
+
*
|
|
113
|
+
* Entries with no `name` pass through untouched, as in the render pass.
|
|
114
|
+
*/
|
|
115
|
+
export declare function gateFormFields<T extends Record<string, any>>(fields: T[] | undefined, { objectSchema, ...options }: GateFormFieldsOptions): T[] | undefined;
|
|
116
|
+
/**
|
|
117
|
+
* The render half for a line-items GRID: the same pass over its columns — drop
|
|
118
|
+
* what the caller may not READ, and lock the cells of what they may read but
|
|
119
|
+
* not WRITE (objectui#10163).
|
|
120
|
+
*
|
|
121
|
+
* ⛔ Not a second gate: the verdict is {@link gateByPermission}'s, the same one
|
|
122
|
+
* the three form containers render through, so the grid and the form above it
|
|
123
|
+
* cannot disagree about which field is refused. A column that is refused
|
|
124
|
+
* replaces any `readonlyWhen` it declared — a lock on every row already covers
|
|
125
|
+
* every row a narrower lock would. Rows are untouched: whether a line may be
|
|
126
|
+
* added or removed stays the container's own answer.
|
|
127
|
+
*
|
|
128
|
+
* `mode` is the form the grid sits in, and picks the question the cells ask
|
|
129
|
+
* the same way it does for a form's fields (objectui#12082): a CREATE form's
|
|
130
|
+
* lines are all new child records, so their cells ask the create question. A
|
|
131
|
+
* grid anywhere else — an edit form, a record page's line-items block — may
|
|
132
|
+
* hold existing lines beside new ones, and one lock per column cannot split
|
|
133
|
+
* per row, so it asks the edit question, as it always did.
|
|
134
|
+
*/
|
|
135
|
+
export declare function applyColumnPermissions<T extends Record<string, any>>(columns: T[] | undefined, { perms, objectName, mode }: Pick<ApplyFieldPermissionsOptions, 'perms' | 'objectName' | 'mode'>): T[] | undefined;
|
|
136
|
+
//# sourceMappingURL=fieldWriteGate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fieldWriteGate.d.ts","sourceRoot":"","sources":["../src/fieldWriteGate.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AAEH,OAAO,EAIL,KAAK,UAAU,EAChB,MAAM,iBAAiB,CAAC;AAEzB;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;CACzF;AAED,2EAA2E;AAC3E,MAAM,MAAM,cAAc,GAAG,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;AAE5D;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,EAC7C,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,GAAG,SAAS,GACvB,cAAc,GAAG,SAAS,CAI5B;AAED,MAAM,WAAW,4BAA4B;IAC3C,KAAK,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,CAAC;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAwCD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACjE,MAAM,EAAE,CAAC,EAAE,GAAG,SAAS,EACvB,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,iBAAiB,EAAE,EAAE,4BAA4B,GAC3E,CAAC,EAAE,GAAG,SAAS,CAMjB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,kBAAmB,SAAQ,mBAAmB;IAC7D,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;IACrE,sBAAsB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CAC5E;AAED,MAAM,WAAW,qBAAsB,SAAQ,4BAA4B;IACzE,KAAK,EAAE,kBAAkB,GAAG,IAAI,GAAG,SAAS,CAAC;IAC7C;;;;OAIG;IACH,YAAY,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,CAAC;CAC7C;AAyCD,gFAAgF;AAChF,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,MAAM,CAAC;AAErD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,KAAK,EACL,UAAU,EACV,IAAI,EACJ,YAAY,GACb,EAAE,IAAI,CAAC,qBAAqB,EAAE,OAAO,GAAG,YAAY,GAAG,MAAM,GAAG,cAAc,CAAC,GAC5E,oBAAoB,GACpB,SAAS,CAGZ;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1D,MAAM,EAAE,CAAC,EAAE,GAAG,SAAS,EACvB,EAAE,YAAY,EAAE,GAAG,OAAO,EAAE,EAAE,qBAAqB,GAClD,CAAC,EAAE,GAAG,SAAS,CAOjB;AAcD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAClE,OAAO,EAAE,CAAC,EAAE,GAAG,SAAS,EACxB,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,IAAI,CAAC,4BAA4B,EAAE,OAAO,GAAG,YAAY,GAAG,MAAM,CAAC,GAC/F,CAAC,EAAE,GAAG,SAAS,CAKjB"}
|
package/dist/flatFields.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FormField } from '@object-ui/types';
|
|
2
|
-
import { SectionFieldsContext } from './sectionFields';
|
|
2
|
+
import { SectionFieldsContext } from './sectionFields.js';
|
|
3
3
|
export interface FlatFieldsContext extends SectionFieldsContext {
|
|
4
4
|
/**
|
|
5
5
|
* The caller's explicit field whitelist, in render order. Entries are field
|
|
@@ -7,6 +7,13 @@ export interface FlatFieldsContext extends SectionFieldsContext {
|
|
|
7
7
|
* object schema declares, in schema order.
|
|
8
8
|
*/
|
|
9
9
|
fields?: Array<string | Record<string, any>>;
|
|
10
|
+
/**
|
|
11
|
+
* The authored inline members (`schema.customFields`), MERGED over the
|
|
12
|
+
* generated set exactly as `ObjectForm` merges them — override by name in
|
|
13
|
+
* place, keep the rest, append the unmatched in authored order
|
|
14
|
+
* (objectui#10073; the rule lives in `customFieldsMerge.ts`).
|
|
15
|
+
*/
|
|
16
|
+
customFields?: FormField[];
|
|
10
17
|
}
|
|
11
18
|
/**
|
|
12
19
|
* Build the runtime `FormField` list for a container rendering an object's
|
|
@@ -15,7 +22,9 @@ export interface FlatFieldsContext extends SectionFieldsContext {
|
|
|
15
22
|
* Fields the object schema does not declare are SKIPPED — the flat containers
|
|
16
23
|
* have always dropped them rather than rendering `fromObjectSchema`'s bare
|
|
17
24
|
* `input` stub, and a whitelist naming a field the object does not have is an
|
|
18
|
-
* authoring error the form should not paper over with an untyped control.
|
|
25
|
+
* authoring error the form should not paper over with an untyped control. A
|
|
26
|
+
* `customFields` member naming such a field is drawn in its place: the member
|
|
27
|
+
* is a whole definition, not an untyped stub.
|
|
19
28
|
*/
|
|
20
29
|
export declare function buildFlatFields(ctx: FlatFieldsContext): FormField[];
|
|
21
30
|
//# sourceMappingURL=flatFields.d.ts.map
|
package/dist/flatFields.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flatFields.d.ts","sourceRoot":"","sources":["../src/flatFields.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,
|
|
1
|
+
{"version":3,"file":"flatFields.d.ts","sourceRoot":"","sources":["../src/flatFields.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAiD,KAAK,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAG3G,MAAM,WAAW,iBAAkB,SAAQ,oBAAoB;IAC7D;;;;OAIG;IACH,MAAM,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;IAC7C;;;;;OAKG;IACH,YAAY,CAAC,EAAE,SAAS,EAAE,CAAC;CAC5B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,iBAAiB,GAAG,SAAS,EAAE,CA8BnE"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI
|
|
3
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* What the submitter is told when a DECLARED `navigateOnSuccess` produced no
|
|
10
|
+
* destination — objectui#5034 point 2.
|
|
11
|
+
*
|
|
12
|
+
* The write succeeded, so this rides on the success toast as a note rather than
|
|
13
|
+
* becoming an error or a blocking panel: turning a successful write into an
|
|
14
|
+
* error state would be a worse lie than the silence it replaces. What was
|
|
15
|
+
* missing is one fact, and only one: the navigation the author declared did not
|
|
16
|
+
* happen. Before this, the toast was byte-identical to the toast a form with no
|
|
17
|
+
* `navigateOnSuccess` at all produces, so an author who mistyped the destination
|
|
18
|
+
* — or whose record carried no usable id — saw a form that looked entirely
|
|
19
|
+
* healthy and had silently stopped honouring a key they wrote.
|
|
20
|
+
*
|
|
21
|
+
* Maintainer ruling, 2026-08-17: "A refused declared navigation is surfaced: the
|
|
22
|
+
* success toast carries a note that the declared navigation was not performed —
|
|
23
|
+
* never indistinguishable from the no-key case."
|
|
24
|
+
*
|
|
25
|
+
* The note names no REASON on purpose. `resolveSuccessNavigate` answers null for
|
|
26
|
+
* two different causes (no usable id on the written record; a destination the
|
|
27
|
+
* same-origin guard refused) and returns no discriminant, so a reason in this
|
|
28
|
+
* copy could only be re-derived by reimplementing that helper's internals at the
|
|
29
|
+
* call site — where it would drift from the helper, and would additionally bake
|
|
30
|
+
* an acceptance rule into user-visible prose, which objectui#5034 has since
|
|
31
|
+
* narrowed once already. The diagnosable detail — the template the author
|
|
32
|
+
* actually wrote — goes to `console.warn` at each call site instead.
|
|
33
|
+
*
|
|
34
|
+
* The submitter sees it (it is the toast's description), so it is pack key
|
|
35
|
+
* `form.navigateRefused` and each form renders `t('form.navigateRefused')`
|
|
36
|
+
* (objectui#11039). This constant is that key's English default, read from the
|
|
37
|
+
* table above so there is one spelling of it; `WizardForm` re-exports it,
|
|
38
|
+
* because that is where it used to live and where its tests import it from.
|
|
39
|
+
* Single-sourced so a wizard and a flat form cannot tell a submitter two
|
|
40
|
+
* different things about one refusal; a test pins that they do not.
|
|
41
|
+
*/
|
|
42
|
+
export declare const NAVIGATE_ON_SUCCESS_REFUSED_NOTE: string;
|
|
43
|
+
/**
|
|
44
|
+
* The form family's feedback chrome. Falls back to the English table above
|
|
45
|
+
* when no i18n provider is mounted, or when the mounted catalogue predates
|
|
46
|
+
* these keys (`form.errorLoading` is the probe).
|
|
47
|
+
*/
|
|
48
|
+
export declare const useFormChromeTranslation: () => {
|
|
49
|
+
t: (key: string, options?: Record<string, unknown>) => string;
|
|
50
|
+
language: string;
|
|
51
|
+
} | {
|
|
52
|
+
t: import('i18next').TFunction<string, undefined>;
|
|
53
|
+
language: string;
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=formChrome.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formChrome.d.ts","sourceRoot":"","sources":["../src/formChrome.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA6EH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,gCAAgC,QAA+C,CAAC;AAE7F;;;;GAIG;AACH,eAAO,MAAM,wBAAwB;4BAvHpC,CAAC;;;;;CA0HD,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ObjectForm } from './ObjectForm';
|
|
1
|
+
import { ObjectForm } from './ObjectForm.js';
|
|
2
2
|
export { ObjectForm };
|
|
3
|
-
export type { ObjectFormComponentProps } from './ObjectForm';
|
|
3
|
+
export type { ObjectFormComponentProps } from './ObjectForm.js';
|
|
4
4
|
/**
|
|
5
5
|
* @deprecated Use `ObjectFormComponentProps`. Renamed in objectui#4650 because
|
|
6
6
|
* `@objectstack/spec/ui` owns `ObjectFormProps` from 17.0.0, where it means the
|
|
@@ -8,28 +8,151 @@ export type { ObjectFormComponentProps } from './ObjectForm';
|
|
|
8
8
|
* props. The alias denotes the SAME type and is kept only so existing importers
|
|
9
9
|
* keep compiling.
|
|
10
10
|
*/
|
|
11
|
-
export type { ObjectFormComponentProps as ObjectFormProps } from './ObjectForm';
|
|
12
|
-
export { FormSectionContainer } from './FormSection';
|
|
13
|
-
export type { FormSectionContainerProps } from './FormSection';
|
|
14
|
-
export { applyAutoLayout, inferColumns, inferModalSize, isWideFieldType, isAutoGeneratedFieldType, applyAutoColSpan, containerGridColsFor, filterCreateModeFields, filterSystemFields, filterAutoGeneratedFields, } from './autoLayout';
|
|
15
|
-
export { TabbedForm } from './TabbedForm';
|
|
16
|
-
export type { TabbedFormProps, TabbedFormSchema, FormSectionConfig } from './TabbedForm';
|
|
17
|
-
export { WizardForm } from './WizardForm';
|
|
18
|
-
export type { WizardFormProps, WizardFormSchema } from './WizardForm';
|
|
19
|
-
export { SplitForm } from './SplitForm';
|
|
20
|
-
export type { SplitFormProps, SplitFormSchema } from './SplitForm';
|
|
21
|
-
export { DrawerForm } from './DrawerForm';
|
|
22
|
-
export type { DrawerFormProps, DrawerFormSchema } from './DrawerForm';
|
|
23
|
-
export { ModalForm } from './ModalForm';
|
|
24
|
-
export type { ModalFormProps, ModalFormSchema } from './ModalForm';
|
|
25
|
-
export { EmbeddableForm } from './EmbeddableForm';
|
|
26
|
-
export type { EmbeddableFormProps, EmbeddableFormConfig, EmbeddableFormTexts } from './EmbeddableForm';
|
|
27
|
-
export { FormAnalytics } from './FormAnalytics';
|
|
28
|
-
export type { FormAnalyticsProps, FormSubmissionMetric } from './FormAnalytics';
|
|
29
|
-
export { MasterDetailForm } from './MasterDetailForm';
|
|
30
|
-
export type { MasterDetailFormProps, MasterDetailFormSchema, MasterDetailDetailConfig, } from './MasterDetailForm';
|
|
31
|
-
export { LineItemsPanel } from './LineItemsPanel';
|
|
32
|
-
export type { LineItemsPanelSchema } from './LineItemsPanel';
|
|
33
|
-
export { deriveDetail, deriveColumns, deriveFormFields, findRelationshipField, resolveInlineMode } from './deriveMasterDetail';
|
|
34
|
-
export type { DerivedDetail, InlineMode } from './deriveMasterDetail';
|
|
11
|
+
export type { ObjectFormComponentProps as ObjectFormProps } from './ObjectForm.js';
|
|
12
|
+
export { FormSectionContainer } from './FormSection.js';
|
|
13
|
+
export type { FormSectionContainerProps } from './FormSection.js';
|
|
14
|
+
export { applyAutoLayout, inferColumns, inferModalSize, isWideFieldType, isAutoGeneratedFieldType, applyAutoColSpan, containerGridColsFor, filterCreateModeFields, filterSystemFields, filterAutoGeneratedFields, } from './autoLayout.js';
|
|
15
|
+
export { TabbedForm } from './TabbedForm.js';
|
|
16
|
+
export type { TabbedFormProps, TabbedFormSchema, FormSectionConfig } from './TabbedForm.js';
|
|
17
|
+
export { WizardForm } from './WizardForm.js';
|
|
18
|
+
export type { WizardFormProps, WizardFormSchema, WizardStepConfig } from './WizardForm.js';
|
|
19
|
+
export { SplitForm } from './SplitForm.js';
|
|
20
|
+
export type { SplitFormProps, SplitFormSchema } from './SplitForm.js';
|
|
21
|
+
export { DrawerForm } from './DrawerForm.js';
|
|
22
|
+
export type { DrawerFormProps, DrawerFormSchema } from './DrawerForm.js';
|
|
23
|
+
export { ModalForm } from './ModalForm.js';
|
|
24
|
+
export type { ModalFormProps, ModalFormSchema } from './ModalForm.js';
|
|
25
|
+
export { EmbeddableForm } from './EmbeddableForm.js';
|
|
26
|
+
export type { EmbeddableFormProps, EmbeddableFormConfig, EmbeddableFormTexts } from './EmbeddableForm.js';
|
|
27
|
+
export { FormAnalytics } from './FormAnalytics.js';
|
|
28
|
+
export type { FormAnalyticsProps, FormSubmissionMetric } from './FormAnalytics.js';
|
|
29
|
+
export { MasterDetailForm } from './MasterDetailForm.js';
|
|
30
|
+
export type { MasterDetailFormProps, MasterDetailFormSchema, MasterDetailDetailConfig, } from './MasterDetailForm.js';
|
|
31
|
+
export { LineItemsPanel } from './LineItemsPanel.js';
|
|
32
|
+
export type { LineItemsPanelSchema } from './LineItemsPanel.js';
|
|
33
|
+
export { deriveDetail, deriveColumns, deriveFormFields, findRelationshipField, resolveInlineMode } from './deriveMasterDetail.js';
|
|
34
|
+
export type { DerivedDetail, InlineMode, ChildObjectSchemaLike } from './deriveMasterDetail.js';
|
|
35
|
+
/**
|
|
36
|
+
* The CREATE-payload rule this package owns, published for the OTHER form
|
|
37
|
+
* renderer (objectui#6059).
|
|
38
|
+
*
|
|
39
|
+
* `omitServerResolvedDefaults` is a pure function over a values object and an
|
|
40
|
+
* object schema — no React, no registry, no container — and it is the
|
|
41
|
+
* COMPOSITION of two `@object-ui/core` predicates (`isRuntimeDefault` AND
|
|
42
|
+
* `isMissingForRequired`, on create only) rather than a third opinion about
|
|
43
|
+
* either. It stayed module-private through the whole #4047 / #4068 / #4069 /
|
|
44
|
+
* #4085 / #5683 / #5727 / #5883 chain, so the console's `FormPage` — the SECOND
|
|
45
|
+
* form renderer in this repo — had to spell that composition out by hand for
|
|
46
|
+
* #5883, and the next renderer would have had to as well. Neither PREDICATE was
|
|
47
|
+
* ever copied (both live in `@object-ui/core` precisely so they cannot fork),
|
|
48
|
+
* but two hand-written copies of the composition are still free to disagree
|
|
49
|
+
* about a case neither author had in mind. One importable function is not.
|
|
50
|
+
*
|
|
51
|
+
* `isRequiredInForm` travels with it because each one's docblock names the
|
|
52
|
+
* other as its half: excusing a server-owned field from `required` and then
|
|
53
|
+
* submitting the key anyway is not half a fix, it is no fix. A consumer able to
|
|
54
|
+
* reach one and not the other can build exactly that state, which is the defect
|
|
55
|
+
* #4069 and #5883 closed on the two chains separately.
|
|
56
|
+
*
|
|
57
|
+
* `optionListDefault` joined them for a named consumer (objectui#13049): the
|
|
58
|
+
* console's public form page (`/f/:slug`) seeds its own create values and had
|
|
59
|
+
* no reading of an option's `default: true`, so a required select the server
|
|
60
|
+
* would default opened empty and the client refused the submit. That page now
|
|
61
|
+
* calls the very function `schemaDefaultValues` calls (objectui#11914), so the
|
|
62
|
+
* two renderers cannot disagree about which option is the default. It travels
|
|
63
|
+
* with its parameter type, `OptionListFieldLike` (objectui#7324).
|
|
64
|
+
*
|
|
65
|
+
* Deliberately NOT the rest of `schemaDefaults.ts`. `seedCreateValues`,
|
|
66
|
+
* `schemaDefaultValues`, `isSeedableDefault`, `isCreateFormMode` and
|
|
67
|
+
* `SeedContext` are adjacent, not asked for — no consumer outside this package
|
|
68
|
+
* has needed them, and every added name is published surface somebody then has
|
|
69
|
+
* to keep. The public form page needed the option-list reading alone: its
|
|
70
|
+
* literal-default and runtime-default rules were already its own (#5727), and
|
|
71
|
+
* the precedence gate (`defaultValue == null`) is the caller's. `isRuntimeDefault`
|
|
72
|
+
* stays out for a stronger reason: it is `@object-ui/core`'s to publish, this
|
|
73
|
+
* module only re-exports it for its own call sites, and a second published
|
|
74
|
+
* spelling of one classifier is the very thing #4085 collapsed.
|
|
75
|
+
*/
|
|
76
|
+
export { omitServerResolvedDefaults, isRequiredInForm, optionListDefault } from './schemaDefaults.js';
|
|
77
|
+
/**
|
|
78
|
+
* The `form.sections[].group` RESOLVER, published for the third form-section
|
|
79
|
+
* consumer (objectui#8641).
|
|
80
|
+
*
|
|
81
|
+
* `resolveSectionGroupReferences` replaces every `{ group: 'x' }` section with
|
|
82
|
+
* the section that group declares, and returns its input UNCHANGED — the same
|
|
83
|
+
* array reference — when no section uses the reference form. It is a pure
|
|
84
|
+
* function over plain data: no React, no registry, no container.
|
|
85
|
+
*
|
|
86
|
+
* ## Why it is published rather than copied
|
|
87
|
+
*
|
|
88
|
+
* `apps/console`'s `FormPage` has its OWN section builder (`buildSections`),
|
|
89
|
+
* on none of this package's code path, and it read `sec.fields ?? []` — so a
|
|
90
|
+
* spec-legal `{ group }` section produced a section with no label and no
|
|
91
|
+
* fields, measured in the DOM as an empty bordered card with zero inputs on
|
|
92
|
+
* both the internal `/forms/:name` and public `/f/:slug` routes. That is the
|
|
93
|
+
* silent-drop class objectui#7051 closed HERE, arriving at a renderer #7051's
|
|
94
|
+
* fix could not reach.
|
|
95
|
+
*
|
|
96
|
+
* The standing constraint of objectui#7051 / objectstack#13855 is that no
|
|
97
|
+
* assembly rule may be re-implemented on the objectui side — not declared
|
|
98
|
+
* order, not the empty-group drop, not the ungrouped trailing bucket, not the
|
|
99
|
+
* collapse / `visibleWhen` passthrough. Every one of those comes from
|
|
100
|
+
* `deriveFieldGroupLayout` (ADR-0085 §5) through this package's ONE adapter,
|
|
101
|
+
* `deriveFieldGroupSections`, which this resolver calls. A consumer that
|
|
102
|
+
* reached for `deriveFieldGroupLayout` directly would have to re-spell the
|
|
103
|
+
* `collapse` enum -> `{ collapsible, collapsed }` mapping and the `visibleWhen`
|
|
104
|
+
* passthrough to land on a section shape, which is that constraint's exact
|
|
105
|
+
* prohibition. So the importable resolver is the only arm that keeps one
|
|
106
|
+
* assembler and one behaviour for all three consumers.
|
|
107
|
+
*
|
|
108
|
+
* This is the same surface decision as objectui#6059's create-payload pair,
|
|
109
|
+
* for the same file, and it is deliberately as small: the resolver and the
|
|
110
|
+
* options type its signature requires (objectui#7324's rule — a consumer must
|
|
111
|
+
* be able to NAME what it passes; a type adds no runtime surface).
|
|
112
|
+
* `hasSectionGroupReference` stays module-private because the resolver already
|
|
113
|
+
* answers it by returning its input unchanged, and `resetSectionGroupReports`
|
|
114
|
+
* stays private because it is this package's own test seam.
|
|
115
|
+
*/
|
|
116
|
+
export { resolveSectionGroupReferences } from './sectionGroups.js';
|
|
117
|
+
export type { ResolveSectionGroupsOptions } from './sectionGroups.js';
|
|
118
|
+
/**
|
|
119
|
+
* The field name a section entry resolves to — the identity rule of the three
|
|
120
|
+
* entry shapes `ObjectFormSection.fields` declares, spelled once
|
|
121
|
+
* (objectui#11615): a bare string is the name, the form view's `{ field }`
|
|
122
|
+
* entry names its field by `field`, an inline `FormField` by `name`;
|
|
123
|
+
* `undefined` when the entry names nothing.
|
|
124
|
+
*
|
|
125
|
+
* Published beside the resolver because the resolver RETURNS that union, and
|
|
126
|
+
* objectui#7324's rule applies to reading what a published function hands
|
|
127
|
+
* back as much as to naming what it takes: a consumer narrowing an entry by
|
|
128
|
+
* hand reads `.name` off a `{ field }` entry — the second dialect this one
|
|
129
|
+
* spelling exists to prevent. A pure function over plain data.
|
|
130
|
+
*/
|
|
131
|
+
export { sectionEntryName } from './sectionFields.js';
|
|
132
|
+
/**
|
|
133
|
+
* The parameter types those published signatures require, so a consumer can
|
|
134
|
+
* NAME what it must pass (objectui#7324).
|
|
135
|
+
*
|
|
136
|
+
* Both were unnameable: `ChildObjectSchemaLike` is the `childSchema` of the
|
|
137
|
+
* five derive functions exported above, and `FieldDefaultsSchemaLike` is the
|
|
138
|
+
* `objectSchema` of `omitServerResolvedDefaults`. Neither reached this barrel,
|
|
139
|
+
* so a host held them in a variable it could not annotate and wrote the shape
|
|
140
|
+
* out by hand instead — a producer-owned shape copied into every consumer,
|
|
141
|
+
* which is what `declared = enforced` exists to prevent.
|
|
142
|
+
*
|
|
143
|
+
* Two names, not one. They arrived carrying the SAME name (`ObjectSchemaLike`)
|
|
144
|
+
* in two files, and they are not the same type: measured with `tsc`, the
|
|
145
|
+
* defaults one is a strict subtype of the child one, and the compiler calls
|
|
146
|
+
* them mutually assignable ONLY because the child one's field values are
|
|
147
|
+
* `any` — swap that single `any` for `unknown` and the child -> defaults
|
|
148
|
+
* direction fails (TS2322). Lifting either under the shared name would have
|
|
149
|
+
* put a name on this package's public surface that already meant something
|
|
150
|
+
* else two files over, with nothing in the name to say which.
|
|
151
|
+
*
|
|
152
|
+
* These are types, not values: they add no runtime surface, and each is the
|
|
153
|
+
* type a signature already published requires — not an adjacent name lifted
|
|
154
|
+
* because it was nearby. `OptionListFieldLike` is the `field` of
|
|
155
|
+
* `optionListDefault` (objectui#13049), on the same rule.
|
|
156
|
+
*/
|
|
157
|
+
export type { FieldDefaultsSchemaLike, OptionListFieldLike } from './schemaDefaults.js';
|
|
35
158
|
//# sourceMappingURL=index.d.ts.map
|