@object-ui/fields 15.0.0 → 16.1.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 +219 -0
- package/README.md +45 -7
- package/dist/index.cjs +5 -5
- package/dist/index.d.ts +21 -0
- package/dist/index.js +1798 -1721
- package/dist/widgets/CheckboxesField.cascade.test.d.ts +0 -0
- package/dist/widgets/CheckboxesField.d.ts +8 -1
- package/dist/widgets/FileField.d.ts +1 -1
- package/dist/widgets/ImageField.d.ts +1 -1
- package/dist/widgets/MultiSelectField.cascade.test.d.ts +0 -0
- package/dist/widgets/MultiSelectField.d.ts +10 -2
- package/dist/widgets/RadioField.cascade.test.d.ts +0 -0
- package/dist/widgets/RadioField.d.ts +8 -1
- package/dist/widgets/SelectField.d.ts +13 -9
- package/dist/widgets/deriveLookupColumns.d.ts +1 -0
- package/dist/widgets/types.d.ts +6 -0
- package/dist/widgets/useCascadingOptions.d.ts +18 -0
- package/dist/widgets/useUploadingSignal.d.ts +9 -0
- package/dist/widgets/useUploadingSignal.test.d.ts +1 -0
- package/package.json +9 -9
- package/src/field-type-coverage.test.ts +3 -1
- package/src/index.tsx +47 -6
- package/src/standard-widgets.test.tsx +44 -0
- package/src/widgets/CapabilityMultiSelectField.test.tsx +26 -1
- package/src/widgets/CapabilityMultiSelectField.tsx +35 -10
- package/src/widgets/CheckboxesField.cascade.test.tsx +143 -0
- package/src/widgets/CheckboxesField.tsx +70 -7
- package/src/widgets/FileField.tsx +9 -1
- package/src/widgets/ImageField.tsx +45 -42
- package/src/widgets/MultiSelectField.cascade.test.tsx +143 -0
- package/src/widgets/MultiSelectField.tsx +72 -8
- package/src/widgets/RadioField.cascade.test.tsx +141 -0
- package/src/widgets/RadioField.tsx +64 -7
- package/src/widgets/SelectField.tsx +33 -31
- package/src/widgets/TextAreaField.tsx +4 -2
- package/src/widgets/deriveLookupColumns.test.ts +13 -0
- package/src/widgets/deriveLookupColumns.ts +5 -15
- package/src/widgets/types.ts +6 -0
- package/src/widgets/useCascadingOptions.ts +46 -0
- package/src/widgets/useFieldTranslation.ts +13 -0
- package/src/widgets/useUploadingSignal.test.tsx +62 -0
- package/src/widgets/useUploadingSignal.ts +20 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,224 @@
|
|
|
1
1
|
# @object-ui/fields
|
|
2
2
|
|
|
3
|
+
## 16.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 1c8935a: feat(app-shell): render ActionParamDialog params through the shared form field-widget renderer (ADR-0059, #2700)
|
|
8
|
+
|
|
9
|
+
`ActionParamDialog` no longer hand-rolls a per-type ternary chain (select /
|
|
10
|
+
lookup / textarea / number / boolean, everything else → text input). Every
|
|
11
|
+
declared action param now renders through the same `fieldWidgetMap` the object
|
|
12
|
+
form uses, so a param of ANY form-supported field type — `file`, `image`,
|
|
13
|
+
`richtext`, `markdown`, `color`, `address`, `code`, `date`, … — gets its real
|
|
14
|
+
widget, lazily loaded behind `Suspense`. Subsumes the single `file` branch ask
|
|
15
|
+
in #2698: `type: 'file'` params render the real `FileField` upload control via
|
|
16
|
+
the ambient `UploadProvider`, honoring `multiple`/`accept`/`maxSize`.
|
|
17
|
+
|
|
18
|
+
- `@object-ui/fields`: new exports `resolveFormWidgetType(type)` (widget-key
|
|
19
|
+
resolution incl. spec aliases, text fallback) and `getLazyFieldWidget(type)`
|
|
20
|
+
(per-type-cached `React.lazy` over the form's own widget loaders).
|
|
21
|
+
- `@object-ui/core`: `ActionParamDef` gains `accept`/`maxSize`; `multiple` is
|
|
22
|
+
now general widget config (was lookup-only).
|
|
23
|
+
- `@object-ui/app-shell`: new pure `paramToField()` adapter (param → field
|
|
24
|
+
shape) with a drift test pinning param support ⊇ form support (`FORM_FIELD_TYPES`),
|
|
25
|
+
mirroring the FieldEditWidget parity guard; `resolveActionParams()` inherits
|
|
26
|
+
`multiple`/`accept`/`maxSize` from the referenced field for every type.
|
|
27
|
+
`required` validation, `visible` CEL gating, helpText, error styling, and
|
|
28
|
+
value shapes for previously-supported types are unchanged.
|
|
29
|
+
|
|
30
|
+
- ef14f69: feat(fields): CheckboxesField per-option `visibleWhen` cascading + `dependsOn` gating (completes the option-widget parity set)
|
|
31
|
+
|
|
32
|
+
`checkboxes` was the last static-option widget still rendering `config.options`
|
|
33
|
+
raw — with no per-option `visibleWhen` filtering, `dependsOn` gating, or cascade
|
|
34
|
+
clear. It now matches `MultiSelectField` (its multi-value sibling), completing
|
|
35
|
+
the ADR-0058 parity across `select` / `multiselect` / `radio` / `checkboxes`.
|
|
36
|
+
|
|
37
|
+
- **`@object-ui/fields`**: `CheckboxesField` routes through the shared
|
|
38
|
+
`useCascadingOptions` hook — offered boxes narrow against the live record +
|
|
39
|
+
`current_user`, the control gates behind a "select the parent first" hint
|
|
40
|
+
while a `dependsOn` field is empty, and selections no longer offered are
|
|
41
|
+
pruned per-element from the array. Adds `checkboxes-empty-*` /
|
|
42
|
+
`checkboxes-option-*` testids.
|
|
43
|
+
- **`@object-ui/components`**: adds `checkboxes` to the form renderer's option
|
|
44
|
+
field sets (`CASCADE_OPTION_FIELD_TYPES`, the cross-field cascade-clear
|
|
45
|
+
effect, and the option pre-filter) so a `checkboxes` field is threaded
|
|
46
|
+
`dependentValues` and gated identically to the other option widgets.
|
|
47
|
+
- Tests: `CheckboxesField.cascade.test.tsx` mirrors `MultiSelectField.cascade.test.tsx`.
|
|
48
|
+
|
|
49
|
+
- 14cb729: feat(fields): MultiSelectField per-option `visibleWhen` cascading + `dependsOn` gating (parity with single select, #2715)
|
|
50
|
+
|
|
51
|
+
The multi-value chip picker now implements the same ADR-0058 option
|
|
52
|
+
resolution as the single `SelectField`, closing the gap #2709 opened when a
|
|
53
|
+
`select` + `multiple` (and the `multiselect` type) started delegating to it.
|
|
54
|
+
|
|
55
|
+
- Extracted `useCascadingOptions` — the shared hook that resolves per-option
|
|
56
|
+
`visibleWhen` filtering, `dependsOn` gating, and the live `dependentValues` +
|
|
57
|
+
predicate-scope wiring — and routed both `SingleSelectField` and
|
|
58
|
+
`MultiSelectField` through it (no duplicated resolver).
|
|
59
|
+
- `MultiSelectField` narrows its offered chips against the live record +
|
|
60
|
+
`current_user`, gates behind a "select the parent first" hint while a
|
|
61
|
+
`dependsOn` field is empty, and surfaces a legible empty state instead of a
|
|
62
|
+
bare chip row.
|
|
63
|
+
- Cascade-clear: when the offered set changes (parent changed / predicate
|
|
64
|
+
flipped) the widget prunes only the now-invalid selections, keeping the
|
|
65
|
+
still-offered ones — the array analogue of the single select's clear.
|
|
66
|
+
- Tests: `MultiSelectField.cascade.test.tsx` mirrors `SelectField.cascade.test.tsx`
|
|
67
|
+
(gating, per-element cascade clear, role/context gating).
|
|
68
|
+
|
|
69
|
+
- 1629313: feat(fields): RadioField per-option `visibleWhen` cascading + `dependsOn` gating; single-source the option resolver
|
|
70
|
+
|
|
71
|
+
Brings `RadioField` to parity with `SelectField` / `MultiSelectField` for ADR-0058
|
|
72
|
+
cascading & role-gated options, and collapses the three copies of the
|
|
73
|
+
gate-then-filter logic onto one shared resolver.
|
|
74
|
+
|
|
75
|
+
- **`@object-ui/core`**: new pure `resolveCascadingOptions(rawOptions, record, dependsOn, scope)`
|
|
76
|
+
→ `{ options, gated, dependsOnFields }` — the single source of truth for
|
|
77
|
+
`dependsOn` gating + per-option `visibleWhen` filtering.
|
|
78
|
+
- **`@object-ui/fields`**: `RadioField` now narrows its offered radios against
|
|
79
|
+
the live record + `current_user`, gates behind a "select the parent first"
|
|
80
|
+
hint while a `dependsOn` field is empty, and clears a value no longer offered
|
|
81
|
+
(scalar cascade clear). The `useCascadingOptions` hook is refactored to a thin
|
|
82
|
+
React wrapper over `resolveCascadingOptions`.
|
|
83
|
+
- **`@object-ui/components`**: the form renderer's inline option pre-filter and
|
|
84
|
+
cross-field cascade-clear effect now call `resolveCascadingOptions` instead of
|
|
85
|
+
re-deriving gating/filtering, so they can't drift from the widgets (no
|
|
86
|
+
behavior change).
|
|
87
|
+
- Tests: `RadioField.cascade.test.tsx` mirrors the select cascade tests; core
|
|
88
|
+
gains `resolveCascadingOptions` unit coverage.
|
|
89
|
+
|
|
90
|
+
- eee4ded: feat(fields): render `select` + `multiple` through the multi-value chip picker; restore fields/core lint gates
|
|
91
|
+
|
|
92
|
+
- **Multi-value select** — a `select` field/param declared `multiple: true`
|
|
93
|
+
now renders the multi-value chip picker (the `multiselect` widget) and stores
|
|
94
|
+
a `string[]`, instead of collapsing to a single-value dropdown that could
|
|
95
|
+
hold only one value. The delegation lives inside `SelectField`, so the object
|
|
96
|
+
form, the inline grid editor, and the app-shell `ActionParamDialog` all
|
|
97
|
+
inherit it from the one `select` widget with no per-surface drift. Single
|
|
98
|
+
selects keep the cascading dropdown (multi + per-option `visibleWhen`
|
|
99
|
+
cascading is not a combination in use today).
|
|
100
|
+
- **`autonumber` mapping is unchanged** here; this change is orthogonal.
|
|
101
|
+
- **Lint gates restored** — fixed the pre-existing baseline lint errors that
|
|
102
|
+
had left the `@object-ui/fields` and `@object-ui/core` package lints red (so
|
|
103
|
+
the gate could not catch new violations): `react-hooks/rules-of-hooks` in
|
|
104
|
+
`ImageField` / `TextAreaField` / `index.tsx` (hooks hoisted above early
|
|
105
|
+
returns; the `useFieldTranslate` hook no longer wrapped in try/catch), plus
|
|
106
|
+
`no-useless-assignment` / `no-useless-escape` / `no-control-regex` /
|
|
107
|
+
`prefer-const` / `preserve-caught-error` in the core evaluator and utils. No
|
|
108
|
+
behavior change from the lint fixes.
|
|
109
|
+
|
|
110
|
+
### Patch Changes
|
|
111
|
+
|
|
112
|
+
- 0318118: fix(app-shell): block ActionParamDialog submit while a file/image param is uploading; map spec `autonumber` (ADR-0059 follow-ups)
|
|
113
|
+
|
|
114
|
+
Two follow-ups to the shared-field-widget param rendering (ADR-0059):
|
|
115
|
+
|
|
116
|
+
- **Upload-in-progress guard.** A `file`/`image` param's value only becomes its
|
|
117
|
+
fileId once the presigned upload settles, so confirming mid-upload sent an
|
|
118
|
+
empty/stale value. `FileField`/`ImageField` now surface their upload state via
|
|
119
|
+
an optional `onUploadingChange` prop (shared `useUploadingSignal` hook,
|
|
120
|
+
ignored by other widgets); `ActionParamDialog` wires it for `file`/`image`
|
|
121
|
+
params and disables Confirm (label → "Uploading…", new `actionDialog.uploading`
|
|
122
|
+
i18n key across all locales) plus blocks submit while any upload is in flight.
|
|
123
|
+
- **`autonumber` spelling.** `mapFieldTypeToFormType` now maps the spec
|
|
124
|
+
`FieldType` spelling `autonumber` (in addition to the widget-map key
|
|
125
|
+
`auto_number`) to the AutoNumber widget, so a spec-typed `autonumber`
|
|
126
|
+
field/param no longer falls through to the plain text input — fixes the object
|
|
127
|
+
form path as well as action params.
|
|
128
|
+
|
|
129
|
+
- aefcf39: feat(action-params): serialize file/image action params to storage id(s); retire the approvals composer
|
|
130
|
+
|
|
131
|
+
Declared action params of `type: 'file'`/`'image'` now POST the portable API
|
|
132
|
+
contract — the storage id(s) — instead of the upload widget's rich object:
|
|
133
|
+
|
|
134
|
+
- `FileField` surfaces the id it already receives from the upload adapter
|
|
135
|
+
(`meta.fileId`) as `file_id` on each emitted file object (additive; the
|
|
136
|
+
record file-field value shape is unchanged).
|
|
137
|
+
- `ActionParamDialog` maps upload-param values to their `file_id`(s) at submit
|
|
138
|
+
(`serializeParamValues`, pure + exported): single → string, `multiple` →
|
|
139
|
+
`string[]`. The api handler already forwards param values untouched, so an
|
|
140
|
+
action with a `file` param POSTs `attachments: string[]`.
|
|
141
|
+
|
|
142
|
+
This lets the approvals inbox retire its last hand-wired UI — the approve/reject
|
|
143
|
+
composer with its bespoke attachment upload — so the drawer renders every
|
|
144
|
+
decision through `DeclaredActionsBar` with the declared `attachments` file param
|
|
145
|
+
(framework side declares it; see the paired framework change). `DeclaredActionsBar`'s
|
|
146
|
+
`exclude` prop stays as a general capability.
|
|
147
|
+
|
|
148
|
+
- 3b2e4d9: fix(list): route remaining system-field groupings through the shared classifier
|
|
149
|
+
|
|
150
|
+
Follow-up to the `owner_id` default-column fix: consolidate the display-oriented
|
|
151
|
+
system-field exclusions onto the shared `isSystemManagedField` /
|
|
152
|
+
`SYSTEM_MANAGED_FIELD_NAMES` (from `@object-ui/types`) so the framework-injected
|
|
153
|
+
`owner_id` is treated consistently across the grid, record picker, and detail
|
|
154
|
+
drawer.
|
|
155
|
+
|
|
156
|
+
- `ObjectGrid` record-detail drawer: the business-fields vs. muted meta-section
|
|
157
|
+
split now uses the shared classifier, so `owner_id` (and other injected system
|
|
158
|
+
fields) land in the meta section instead of the business body.
|
|
159
|
+
- `deriveLookupColumns` (record picker): drops its local name set for the shared
|
|
160
|
+
classifier — now flag-aware (`field.system`), not just name-based.
|
|
161
|
+
- `RecordDetailDrawer`: its default `systemFields` set is derived from the shared
|
|
162
|
+
`SYSTEM_MANAGED_FIELD_NAMES`; the `systemFields` prop override is preserved.
|
|
163
|
+
|
|
164
|
+
`deriveRelatedLists`' narrow "audit FK on every object" set and plugin-detail's
|
|
165
|
+
inline-edit "never editable" set are intentionally left distinct — different
|
|
166
|
+
semantics (the latter deliberately keeps `owner_id` editable).
|
|
167
|
+
|
|
168
|
+
- Updated dependencies [0318118]
|
|
169
|
+
- Updated dependencies [1c8935a]
|
|
170
|
+
- Updated dependencies [af1b0db]
|
|
171
|
+
- Updated dependencies [8b8b744]
|
|
172
|
+
- Updated dependencies [7cf4051]
|
|
173
|
+
- Updated dependencies [803558e]
|
|
174
|
+
- Updated dependencies [2e7d7f0]
|
|
175
|
+
- Updated dependencies [ef14f69]
|
|
176
|
+
- Updated dependencies [94d4876]
|
|
177
|
+
- Updated dependencies [1100a8b]
|
|
178
|
+
- Updated dependencies [7abe4cd]
|
|
179
|
+
- Updated dependencies [69fa5d1]
|
|
180
|
+
- Updated dependencies [549c67d]
|
|
181
|
+
- Updated dependencies [ebe6494]
|
|
182
|
+
- Updated dependencies [2b17339]
|
|
183
|
+
- Updated dependencies [31b77d4]
|
|
184
|
+
- Updated dependencies [6d4fbe6]
|
|
185
|
+
- Updated dependencies [0a3710b]
|
|
186
|
+
- Updated dependencies [f80aaf2]
|
|
187
|
+
- Updated dependencies [62b9ab5]
|
|
188
|
+
- Updated dependencies [1629313]
|
|
189
|
+
- Updated dependencies [29c6040]
|
|
190
|
+
- Updated dependencies [faebac3]
|
|
191
|
+
- Updated dependencies [2331ac9]
|
|
192
|
+
- Updated dependencies [199fa83]
|
|
193
|
+
- Updated dependencies [eee4ded]
|
|
194
|
+
- @object-ui/i18n@16.1.0
|
|
195
|
+
- @object-ui/core@16.1.0
|
|
196
|
+
- @object-ui/types@16.1.0
|
|
197
|
+
- @object-ui/react@16.1.0
|
|
198
|
+
- @object-ui/components@16.1.0
|
|
199
|
+
- @object-ui/providers@16.1.0
|
|
200
|
+
|
|
201
|
+
## 16.0.0
|
|
202
|
+
|
|
203
|
+
### Patch Changes
|
|
204
|
+
|
|
205
|
+
- Updated dependencies [d3e19ed]
|
|
206
|
+
- Updated dependencies [59d4fa9]
|
|
207
|
+
- Updated dependencies [4c7c47f]
|
|
208
|
+
- Updated dependencies [210806a]
|
|
209
|
+
- Updated dependencies [b4ef588]
|
|
210
|
+
- Updated dependencies [ca0f5f0]
|
|
211
|
+
- Updated dependencies [5534535]
|
|
212
|
+
- Updated dependencies [9b8f978]
|
|
213
|
+
- Updated dependencies [195a651]
|
|
214
|
+
- Updated dependencies [33b4995]
|
|
215
|
+
- @object-ui/react@16.0.0
|
|
216
|
+
- @object-ui/components@16.0.0
|
|
217
|
+
- @object-ui/types@16.0.0
|
|
218
|
+
- @object-ui/i18n@16.0.0
|
|
219
|
+
- @object-ui/core@16.0.0
|
|
220
|
+
- @object-ui/providers@16.0.0
|
|
221
|
+
|
|
3
222
|
## 15.0.0
|
|
4
223
|
|
|
5
224
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -55,6 +55,23 @@ Supported types out of the box:
|
|
|
55
55
|
- **Media**: `file`, `image`
|
|
56
56
|
- **System**: `formula`, `summary`, `auto_number`
|
|
57
57
|
|
|
58
|
+
### Rendering form field widgets outside the form
|
|
59
|
+
|
|
60
|
+
The full widget surface is exported for consumers that render field widgets
|
|
61
|
+
outside a record form (ADR-0059):
|
|
62
|
+
|
|
63
|
+
- `FORM_FIELD_TYPES` — the frozen list of every type the form can render.
|
|
64
|
+
- `resolveFormWidgetType(type)` — resolves any field-type spelling to its
|
|
65
|
+
widget key (spec aliases like `toggle`/`json`/`secret` included; unknown
|
|
66
|
+
types fall back to `text`, mirroring the form).
|
|
67
|
+
- `getLazyFieldWidget(type)` — the widget wrapped in `React.lazy` (cached per
|
|
68
|
+
type; render inside `<Suspense>`), sharing the same loaders `registerField`
|
|
69
|
+
uses so nothing is bundled eagerly.
|
|
70
|
+
|
|
71
|
+
The app-shell `ActionParamDialog` uses these to render declared action params
|
|
72
|
+
through the exact same widgets as the object form — with a drift test pinning
|
|
73
|
+
param support ⊇ form support.
|
|
74
|
+
|
|
58
75
|
### File uploads in line-item grids
|
|
59
76
|
|
|
60
77
|
`GridField` (the master-detail line-items grid) supports `type: 'file'` columns:
|
|
@@ -66,15 +83,36 @@ or photo per row without opening the row form (objectui#2360). Columns accept
|
|
|
66
83
|
exported as `FileCell`). Auto-derived subform columns map `file`/`image`/
|
|
67
84
|
`avatar` fields to file columns instead of dropping them.
|
|
68
85
|
|
|
86
|
+
### Multi-value selects
|
|
87
|
+
|
|
88
|
+
A `select` field declared `multiple: true` selects zero-or-more values (spec
|
|
89
|
+
allows `multiple` on `select`). `SelectField` delegates to the multi-value chip
|
|
90
|
+
picker (the same widget the `multiselect` type uses) and stores a `string[]`.
|
|
91
|
+
Delegating inside `SelectField` — rather than at a type-resolution layer — means
|
|
92
|
+
every surface that renders the `select` widget (the object form, the inline grid
|
|
93
|
+
editor, and the app-shell `ActionParamDialog`) gets multi-select identically,
|
|
94
|
+
with no per-surface drift. Both single- and multi-value selects resolve
|
|
95
|
+
per-option `visibleWhen` cascading and `dependsOn` gating through the same
|
|
96
|
+
[`useCascadingOptions`](./src/widgets/useCascadingOptions.ts) hook, so the
|
|
97
|
+
offered chips narrow (and now-invalid selections are pruned) exactly as the
|
|
98
|
+
single dropdown does.
|
|
99
|
+
|
|
69
100
|
### Cascading & role-gated select options
|
|
70
101
|
|
|
71
|
-
`select` options support a per-option
|
|
72
|
-
when TRUE, evaluated against the live
|
|
73
|
-
`dependsOn`. Together they drive
|
|
74
|
-
and role-gated options with no
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
102
|
+
`select`, `multiselect`, `radio`, and `checkboxes` options support a per-option
|
|
103
|
+
`visibleWhen` CEL predicate (offered only when TRUE, evaluated against the live
|
|
104
|
+
record + `current_user`) and a field-level `dependsOn`. Together they drive
|
|
105
|
+
dependent selects (country → province → city) and role-gated options with no
|
|
106
|
+
bespoke matrix — the same primitives dependent lookups use. All four widgets
|
|
107
|
+
resolve this through the shared [`useCascadingOptions`](./src/widgets/useCascadingOptions.ts)
|
|
108
|
+
hook, which wraps the pure `resolveCascadingOptions` helper in `@object-ui/core`
|
|
109
|
+
(also used by the form renderer's inline pre-filter, so gating and filtering
|
|
110
|
+
never drift). While a `dependsOn` parent is empty the control is gated; a parent
|
|
111
|
+
change re-filters the list and clears a now-invalid value (scalar `select` /
|
|
112
|
+
`radio` drop the value; multi-value `multiselect` / `checkboxes` prune just the
|
|
113
|
+
offered-out entries).
|
|
114
|
+
Client-side hiding is UX only — gate authorization-sensitive values on the
|
|
115
|
+
server too. See
|
|
78
116
|
[`content/docs/fields/select.mdx`](../../content/docs/fields/select.mdx).
|
|
79
117
|
|
|
80
118
|
<!-- release-metadata:v3.3.0 -->
|