@object-ui/fields 16.0.0 → 17.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.
Files changed (71) hide show
  1. package/CHANGELOG.md +630 -0
  2. package/README.md +45 -7
  3. package/dist/FieldEditWidget.d.ts +7 -0
  4. package/dist/field-type-alias.d.ts +16 -0
  5. package/dist/index.cjs +5 -5
  6. package/dist/index.d.ts +35 -11
  7. package/dist/index.js +2241 -1853
  8. package/dist/widgets/CheckboxesField.cascade.test.d.ts +0 -0
  9. package/dist/widgets/CheckboxesField.d.ts +8 -1
  10. package/dist/widgets/FileField.d.ts +1 -1
  11. package/dist/widgets/FilterConditionField.d.ts +32 -0
  12. package/dist/widgets/ImageField.d.ts +1 -1
  13. package/dist/widgets/ImageLightbox.d.ts +30 -0
  14. package/dist/widgets/ImageLightbox.test.d.ts +1 -0
  15. package/dist/widgets/LookupField.hydration.test.d.ts +1 -0
  16. package/dist/widgets/LookupField.idField.test.d.ts +1 -0
  17. package/dist/widgets/MultiSelectField.cascade.test.d.ts +0 -0
  18. package/dist/widgets/MultiSelectField.d.ts +10 -2
  19. package/dist/widgets/RadioField.cascade.test.d.ts +0 -0
  20. package/dist/widgets/RadioField.d.ts +8 -1
  21. package/dist/widgets/RecipientPickerField.test.d.ts +0 -0
  22. package/dist/widgets/SelectField.d.ts +13 -9
  23. package/dist/widgets/__tests__/FilterConditionField.matchAll.test.d.ts +8 -0
  24. package/dist/widgets/__tests__/FilterConditionField.operators.test.d.ts +8 -0
  25. package/dist/widgets/deriveLookupColumns.d.ts +1 -0
  26. package/dist/widgets/file-value.d.ts +112 -0
  27. package/dist/widgets/file-value.test.d.ts +1 -0
  28. package/dist/widgets/types.d.ts +6 -0
  29. package/dist/widgets/useCascadingOptions.d.ts +18 -0
  30. package/dist/widgets/useFieldTranslation.d.ts +2 -0
  31. package/dist/widgets/useUploadingSignal.d.ts +9 -0
  32. package/dist/widgets/useUploadingSignal.test.d.ts +1 -0
  33. package/package.json +11 -10
  34. package/src/FieldEditWidget.test.ts +74 -2
  35. package/src/FieldEditWidget.tsx +44 -4
  36. package/src/field-type-alias.ts +100 -0
  37. package/src/field-type-coverage.test.ts +3 -1
  38. package/src/index.tsx +137 -135
  39. package/src/standard-widgets.test.tsx +44 -0
  40. package/src/widgets/CheckboxesField.cascade.test.tsx +143 -0
  41. package/src/widgets/CheckboxesField.tsx +77 -11
  42. package/src/widgets/FileField.tsx +91 -52
  43. package/src/widgets/FilterConditionField.tsx +109 -9
  44. package/src/widgets/ImageField.tsx +106 -65
  45. package/src/widgets/ImageLightbox.test.tsx +52 -0
  46. package/src/widgets/ImageLightbox.tsx +108 -0
  47. package/src/widgets/LookupField.hydration.test.tsx +136 -0
  48. package/src/widgets/LookupField.idField.test.tsx +61 -0
  49. package/src/widgets/LookupField.tsx +106 -9
  50. package/src/widgets/MultiSelectField.cascade.test.tsx +143 -0
  51. package/src/widgets/MultiSelectField.tsx +78 -11
  52. package/src/widgets/ObjectRefField.tsx +9 -4
  53. package/src/widgets/PeoplePicker.test.tsx +20 -0
  54. package/src/widgets/PeoplePicker.tsx +15 -3
  55. package/src/widgets/RadioField.cascade.test.tsx +141 -0
  56. package/src/widgets/RadioField.tsx +69 -9
  57. package/src/widgets/RecipientPickerField.test.tsx +157 -0
  58. package/src/widgets/RecipientPickerField.tsx +36 -16
  59. package/src/widgets/SelectField.tsx +33 -31
  60. package/src/widgets/TextAreaField.tsx +8 -3
  61. package/src/widgets/__tests__/FilterConditionField.matchAll.test.ts +66 -0
  62. package/src/widgets/__tests__/FilterConditionField.operators.test.ts +142 -0
  63. package/src/widgets/deriveLookupColumns.test.ts +13 -0
  64. package/src/widgets/deriveLookupColumns.ts +5 -15
  65. package/src/widgets/file-value.test.ts +230 -0
  66. package/src/widgets/file-value.ts +230 -0
  67. package/src/widgets/types.ts +6 -0
  68. package/src/widgets/useCascadingOptions.ts +46 -0
  69. package/src/widgets/useFieldTranslation.ts +30 -0
  70. package/src/widgets/useUploadingSignal.test.tsx +62 -0
  71. package/src/widgets/useUploadingSignal.ts +20 -0
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 `visibleWhen` CEL predicate (offered only
72
- when TRUE, evaluated against the live record + `current_user`) and a field-level
73
- `dependsOn`. Together they drive dependent selects (country → province → city)
74
- and role-gated options with no bespoke matrix — the same primitives dependent
75
- lookups use. While a `dependsOn` parent is empty the control is gated; a parent
76
- change re-filters the list and clears a now-invalid value. Client-side hiding is
77
- UX only — gate authorization-sensitive values on the server too. See
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 -->
@@ -12,6 +12,13 @@ export declare const INLINE_EXCLUDED_FIELD_TYPES: Set<string>;
12
12
  export declare const DISCRETE_EDIT_TYPES: Set<string>;
13
13
  /** True when a field type has a dedicated in-place edit widget. */
14
14
  export declare function hasFieldEditWidget(type: string | undefined): boolean;
15
+ /**
16
+ * True when a field type is deliberately NOT inline-editable (alias-aware:
17
+ * `composite` resolves to the excluded `object`, `video` to `file`, …).
18
+ * Grid hosts must treat these as read-only cells — falling back to a plain
19
+ * text editor is exactly the corruption path the exclusion exists to close.
20
+ */
21
+ export declare function isInlineExcludedFieldType(type: string | undefined): boolean;
15
22
  /**
16
23
  * Render the dedicated edit widget for a field's type — the SAME control the
17
24
  * form uses — as a controlled `{ value, onChange, field }` input. Returns
@@ -0,0 +1,16 @@
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
+ * Map field type to form component type
10
+ *
11
+ * @param fieldType - The ObjectQL field type identifier to convert
12
+ * (for example: `"text"`, `"number"`, `"date"`, `"lookup"`).
13
+ * @returns The normalized form field type string used in the form schema
14
+ * (for example: `"input"`, `"textarea"`, `"date-picker"`, `"select"`).
15
+ */
16
+ export declare function mapFieldTypeToFormType(fieldType: string): string;