@object-ui/fields 17.5.0 → 17.6.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 (229) hide show
  1. package/CHANGELOG.md +714 -0
  2. package/dist/FieldEditWidget.d.ts +16 -2
  3. package/dist/field-type-alias.d.ts +16 -0
  4. package/dist/index.cjs +4 -4
  5. package/dist/index.css +27 -9
  6. package/dist/index.d.ts +425 -72
  7. package/dist/index.js +2530 -2228
  8. package/dist/widgets/AddressField.d.ts +3 -3
  9. package/dist/widgets/AutoNumberField.d.ts +1 -1
  10. package/dist/widgets/AvatarField.d.ts +1 -1
  11. package/dist/widgets/BooleanField.d.ts +1 -1
  12. package/dist/widgets/CapabilityMultiSelectField.d.ts +1 -1
  13. package/dist/widgets/CheckboxesField.d.ts +1 -1
  14. package/dist/widgets/CodeField.d.ts +1 -1
  15. package/dist/widgets/ColorField.d.ts +1 -1
  16. package/dist/widgets/CurrencyField.d.ts +1 -1
  17. package/dist/widgets/DateField.d.ts +1 -1
  18. package/dist/widgets/DateTimeField.d.ts +1 -1
  19. package/dist/widgets/EmailField.d.ts +1 -1
  20. package/dist/widgets/FileField.d.ts +18 -2
  21. package/dist/widgets/FilterConditionField.d.ts +28 -1
  22. package/dist/widgets/FormulaField.d.ts +1 -1
  23. package/dist/widgets/FullscreenFieldEditor.d.ts +9 -2
  24. package/dist/widgets/GeolocationField.d.ts +1 -1
  25. package/dist/widgets/GridField.d.ts +56 -4
  26. package/dist/widgets/ImageField.d.ts +1 -1
  27. package/dist/widgets/LocationField.d.ts +1 -1
  28. package/dist/widgets/LookupField.d.ts +1 -1
  29. package/dist/widgets/MasterDetailField.d.ts +1 -1
  30. package/dist/widgets/MultiSelectField.d.ts +1 -1
  31. package/dist/widgets/NumberField.d.ts +1 -1
  32. package/dist/widgets/ObjectField.d.ts +1 -1
  33. package/dist/widgets/ObjectRefField.d.ts +1 -1
  34. package/dist/widgets/OptionsEmptyState.d.ts +13 -7
  35. package/dist/widgets/PasswordField.d.ts +1 -1
  36. package/dist/widgets/PercentField.d.ts +1 -1
  37. package/dist/widgets/PhoneField.d.ts +1 -1
  38. package/dist/widgets/QRCodeField.d.ts +1 -1
  39. package/dist/widgets/RadioField.d.ts +1 -1
  40. package/dist/widgets/RatingField.d.ts +1 -1
  41. package/dist/widgets/RecipientPickerField.d.ts +1 -1
  42. package/dist/widgets/RecordPickerDialog.d.ts +2 -4
  43. package/dist/widgets/RichTextField.d.ts +37 -1
  44. package/dist/widgets/SelectField.d.ts +1 -1
  45. package/dist/widgets/SignatureField.d.ts +32 -2
  46. package/dist/widgets/SliderField.d.ts +37 -2
  47. package/dist/widgets/SummaryField.d.ts +1 -1
  48. package/dist/widgets/TagsField.d.ts +1 -1
  49. package/dist/widgets/TextAreaField.d.ts +6 -2
  50. package/dist/widgets/TextField.d.ts +1 -1
  51. package/dist/widgets/TimeField.d.ts +1 -1
  52. package/dist/widgets/UrlField.d.ts +1 -1
  53. package/dist/widgets/UserField.d.ts +1 -1
  54. package/dist/widgets/VectorField.d.ts +1 -1
  55. package/dist/widgets/_cell-renderer-bridge.d.ts +1 -1
  56. package/dist/widgets/address-format.d.ts +27 -7
  57. package/dist/widgets/lookupColumnDisplay.d.ts +93 -0
  58. package/dist/widgets/richTextDisplay.d.ts +80 -0
  59. package/dist/widgets/toHostGroupProps.d.ts +119 -21
  60. package/dist/widgets/types.d.ts +8 -3
  61. package/package.json +9 -10
  62. package/dist/widgets/CharacterCount.d.ts +0 -56
  63. package/src/FieldEditWidget.test.ts +0 -133
  64. package/src/FieldEditWidget.tsx +0 -207
  65. package/src/__tests__/AddressCellRenderer.test.tsx +0 -166
  66. package/src/__tests__/CurrencyField.minorUnits.test.tsx +0 -191
  67. package/src/__tests__/CurrencyField.symbol.test.tsx +0 -198
  68. package/src/__tests__/DateCellRenderer.test.tsx +0 -82
  69. package/src/__tests__/NumberCellRenderer.grouping.test.tsx +0 -146
  70. package/src/__tests__/NumberCellRenderer.test.tsx +0 -60
  71. package/src/__tests__/PercentCellRenderer.locale.test.tsx +0 -152
  72. package/src/__tests__/PercentCellRenderer.test.tsx +0 -115
  73. package/src/__tests__/boolean-label-association-e2e.test.tsx +0 -298
  74. package/src/__tests__/capability-multiselect-retired.test.ts +0 -109
  75. package/src/__tests__/cell-truncation.test.tsx +0 -96
  76. package/src/__tests__/composite-group-label-e2e.test.tsx +0 -436
  77. package/src/__tests__/composite-group-label-readonly-e2e.test.tsx +0 -403
  78. package/src/__tests__/date-formatter-residue-4272.test.ts +0 -120
  79. package/src/__tests__/date-locale-channel.test.tsx +0 -305
  80. package/src/__tests__/field-carrier-sdui.test.tsx +0 -169
  81. package/src/__tests__/formatCurrency.centsDigit.test.tsx +0 -158
  82. package/src/__tests__/formatCurrency.minorUnits.test.tsx +0 -221
  83. package/src/__tests__/group-labelling-declaration.test.ts +0 -148
  84. package/src/__tests__/lookupCellDisplayField.test.tsx +0 -107
  85. package/src/__tests__/lookupCellDisplayName.test.tsx +0 -119
  86. package/src/__tests__/lookupCellRecordLink.test.tsx +0 -171
  87. package/src/__tests__/lookupCellReferenceKey.test.tsx +0 -57
  88. package/src/__tests__/percent-cell-vs-measure-4576.test.ts +0 -115
  89. package/src/__tests__/percent-formatter-locale-4553.test.ts +0 -147
  90. package/src/__tests__/percent-tie-halfup-4590.test.ts +0 -224
  91. package/src/__tests__/registry-collision.test.ts +0 -91
  92. package/src/__tests__/resolveFieldCurrency.test.ts +0 -20
  93. package/src/__tests__/select-label-association-e2e.test.tsx +0 -199
  94. package/src/__tests__/spec-symbol-batch7.test.ts +0 -126
  95. package/src/__tests__/validation-feedback.test.tsx +0 -361
  96. package/src/__tests__/widget-aria-invalid-e2e.test.tsx +0 -265
  97. package/src/__tests__/widget-aria-invalid-registry-e2e.test.tsx +0 -338
  98. package/src/__tests__/widget-dom-leak-e2e.test.tsx +0 -357
  99. package/src/__tests__/widget-props-contract.test.tsx +0 -142
  100. package/src/coerce-safe-value.test.ts +0 -34
  101. package/src/complex-widgets.test.tsx +0 -924
  102. package/src/currency.ts +0 -144
  103. package/src/datetime-widgets.test.tsx +0 -185
  104. package/src/field-type-alias.multiple.test.ts +0 -81
  105. package/src/field-type-alias.ts +0 -156
  106. package/src/field-type-coverage.test.ts +0 -67
  107. package/src/index.css +0 -44
  108. package/src/index.tsx +0 -2745
  109. package/src/standard-widgets.test.tsx +0 -364
  110. package/src/widgets/AddressField.postalCode.test.tsx +0 -257
  111. package/src/widgets/AddressField.tsx +0 -182
  112. package/src/widgets/AddressField.uniqueIds.test.tsx +0 -93
  113. package/src/widgets/AutoNumberField.tsx +0 -18
  114. package/src/widgets/AvatarField.tsx +0 -117
  115. package/src/widgets/BooleanField.tsx +0 -86
  116. package/src/widgets/CapabilityMultiSelectField.test.tsx +0 -168
  117. package/src/widgets/CapabilityMultiSelectField.tsx +0 -241
  118. package/src/widgets/CharacterCount.tsx +0 -263
  119. package/src/widgets/CheckboxesField.cascade.test.tsx +0 -143
  120. package/src/widgets/CheckboxesField.tsx +0 -169
  121. package/src/widgets/CodeField.tsx +0 -41
  122. package/src/widgets/ColorField.tsx +0 -53
  123. package/src/widgets/CurrencyField.tsx +0 -135
  124. package/src/widgets/DateField.tsx +0 -40
  125. package/src/widgets/DateTimeField.tsx +0 -46
  126. package/src/widgets/EmailField.tsx +0 -37
  127. package/src/widgets/FileField.tsx +0 -512
  128. package/src/widgets/FilterConditionField.tsx +0 -454
  129. package/src/widgets/FormulaField.tsx +0 -38
  130. package/src/widgets/FullscreenFieldEditor.tsx +0 -60
  131. package/src/widgets/GeolocationField.tsx +0 -193
  132. package/src/widgets/GeolocationField.uniqueIds.test.tsx +0 -88
  133. package/src/widgets/GridField.test.tsx +0 -632
  134. package/src/widgets/GridField.tsx +0 -1070
  135. package/src/widgets/ImageCropperDialog.tsx +0 -245
  136. package/src/widgets/ImageField.maxSize.test.tsx +0 -154
  137. package/src/widgets/ImageField.tsx +0 -305
  138. package/src/widgets/ImageLightbox.test.tsx +0 -52
  139. package/src/widgets/ImageLightbox.tsx +0 -108
  140. package/src/widgets/LocationField.tsx +0 -57
  141. package/src/widgets/LookupField.dependsOn.test.tsx +0 -233
  142. package/src/widgets/LookupField.gateHintLabel.test.tsx +0 -135
  143. package/src/widgets/LookupField.hydration.test.tsx +0 -136
  144. package/src/widgets/LookupField.idField.test.tsx +0 -61
  145. package/src/widgets/LookupField.tsx +0 -1295
  146. package/src/widgets/MarkdownContent.tsx +0 -19
  147. package/src/widgets/MasterDetailField.tsx +0 -131
  148. package/src/widgets/MultiSelectField.cascade.test.tsx +0 -143
  149. package/src/widgets/MultiSelectField.tsx +0 -196
  150. package/src/widgets/NumberField.tsx +0 -49
  151. package/src/widgets/ObjectField.tsx +0 -94
  152. package/src/widgets/ObjectRefField.tsx +0 -121
  153. package/src/widgets/OptionsEmptyState.no-provider.test.tsx +0 -88
  154. package/src/widgets/OptionsEmptyState.test.tsx +0 -169
  155. package/src/widgets/OptionsEmptyState.tsx +0 -99
  156. package/src/widgets/PasswordField.tsx +0 -49
  157. package/src/widgets/PeoplePicker.test.tsx +0 -360
  158. package/src/widgets/PeoplePicker.tsx +0 -579
  159. package/src/widgets/PeoplePickerComponents.test.tsx +0 -104
  160. package/src/widgets/PercentField.tsx +0 -95
  161. package/src/widgets/PersonRow.tsx +0 -117
  162. package/src/widgets/PhoneField.tsx +0 -37
  163. package/src/widgets/QRCodeField.tsx +0 -103
  164. package/src/widgets/RadioField.cascade.test.tsx +0 -141
  165. package/src/widgets/RadioField.tsx +0 -143
  166. package/src/widgets/RatingField.tsx +0 -94
  167. package/src/widgets/RecipientPickerField.test.tsx +0 -157
  168. package/src/widgets/RecipientPickerField.tsx +0 -188
  169. package/src/widgets/RecordPickerDialog.baseFilterShapes.test.tsx +0 -191
  170. package/src/widgets/RecordPickerDialog.dateLocale.test.tsx +0 -124
  171. package/src/widgets/RecordPickerDialog.filterOptions.test.tsx +0 -611
  172. package/src/widgets/RecordPickerDialog.selectLabel.test.tsx +0 -112
  173. package/src/widgets/RecordPickerDialog.tsx +0 -1365
  174. package/src/widgets/RichTextField.tsx +0 -176
  175. package/src/widgets/SelectField.cascade.test.tsx +0 -138
  176. package/src/widgets/SelectField.tsx +0 -193
  177. package/src/widgets/SelectionTray.tsx +0 -110
  178. package/src/widgets/SignatureField.tsx +0 -140
  179. package/src/widgets/SliderField.tsx +0 -39
  180. package/src/widgets/SummaryField.tsx +0 -31
  181. package/src/widgets/TagsField.placeholder.no-provider.test.tsx +0 -68
  182. package/src/widgets/TagsField.placeholder.test.tsx +0 -95
  183. package/src/widgets/TagsField.tsx +0 -88
  184. package/src/widgets/TextAreaField.tsx +0 -213
  185. package/src/widgets/TextField.tsx +0 -45
  186. package/src/widgets/TimeField.tsx +0 -31
  187. package/src/widgets/UrlField.tsx +0 -46
  188. package/src/widgets/UserField.tsx +0 -59
  189. package/src/widgets/UserFieldPicker.test.tsx +0 -78
  190. package/src/widgets/VectorField.tsx +0 -29
  191. package/src/widgets/__tests__/FilterConditionField.matchAll.test.ts +0 -66
  192. package/src/widgets/__tests__/FilterConditionField.operators.test.ts +0 -166
  193. package/src/widgets/__tests__/FullscreenFieldEditor.i18n.test.tsx +0 -248
  194. package/src/widgets/__tests__/FullscreenFieldEditor.no-provider.test.tsx +0 -116
  195. package/src/widgets/__tests__/RichTextField.fullscreenDisabled.test.tsx +0 -244
  196. package/src/widgets/__tests__/RichTextField.mobileFullscreen.test.tsx +0 -195
  197. package/src/widgets/__tests__/TextAreaField.characterCount.announcements.test.tsx +0 -417
  198. package/src/widgets/__tests__/TextAreaField.characterCount.i18n.test.tsx +0 -287
  199. package/src/widgets/__tests__/TextAreaField.characterCount.no-provider.test.tsx +0 -160
  200. package/src/widgets/__tests__/TextAreaField.fullscreenCharacterCount.i18n.test.tsx +0 -161
  201. package/src/widgets/__tests__/TextAreaField.fullscreenCharacterCount.test.tsx +0 -346
  202. package/src/widgets/__tests__/TextAreaField.fullscreenDisabled.test.tsx +0 -246
  203. package/src/widgets/__tests__/TextAreaField.mobileFullscreen.test.tsx +0 -175
  204. package/src/widgets/_cell-renderer-bridge.ts +0 -19
  205. package/src/widgets/address-format.ts +0 -120
  206. package/src/widgets/deriveLookupColumns.test.ts +0 -112
  207. package/src/widgets/deriveLookupColumns.ts +0 -108
  208. package/src/widgets/file-size-guard.ts +0 -55
  209. package/src/widgets/file-value.test.ts +0 -230
  210. package/src/widgets/file-value.ts +0 -246
  211. package/src/widgets/nativeDateValue.test.ts +0 -115
  212. package/src/widgets/nativeDateValue.ts +0 -112
  213. package/src/widgets/openNativePicker.ts +0 -18
  214. package/src/widgets/optionWidgets.gatedOptions.test.tsx +0 -267
  215. package/src/widgets/optionWidgets.unconfiguredOptions.test.tsx +0 -150
  216. package/src/widgets/personDisplay.test.ts +0 -113
  217. package/src/widgets/personDisplay.ts +0 -92
  218. package/src/widgets/recentLookups.test.ts +0 -45
  219. package/src/widgets/recentLookups.ts +0 -47
  220. package/src/widgets/toDomProps.ts +0 -204
  221. package/src/widgets/toHostGroupProps.ts +0 -102
  222. package/src/widgets/types.ts +0 -242
  223. package/src/widgets/useCascadingOptions.ts +0 -46
  224. package/src/widgets/useFieldTranslation.ts +0 -132
  225. package/src/widgets/useRecordQuery.test.ts +0 -174
  226. package/src/widgets/useRecordQuery.ts +0 -291
  227. package/src/widgets/useUploadingSignal.test.tsx +0 -62
  228. package/src/widgets/useUploadingSignal.ts +0 -20
  229. package/src/withFieldCarrier.tsx +0 -75
package/dist/index.css CHANGED
@@ -23,9 +23,6 @@
23
23
  .right-2\.5 {
24
24
  right: calc(var(--spacing, 0.25rem) * 2.5);
25
25
  }
26
- .bottom-2 {
27
- bottom: calc(var(--spacing, 0.25rem) * 2);
28
- }
29
26
  .left-3 {
30
27
  left: calc(var(--spacing, 0.25rem) * 3);
31
28
  }
@@ -130,6 +127,9 @@
130
127
  .gap-y-1 {
131
128
  row-gap: var(--spacing, 0.25rem);
132
129
  }
130
+ .border-\[color\:var\(--os-badge-border\)\] {
131
+ border-color: var(--os-badge-border);
132
+ }
133
133
  .border-background {
134
134
  border-color: var(--color-background, hsl(var(--background)));
135
135
  }
@@ -187,6 +187,15 @@
187
187
  .border-yellow-200 {
188
188
  border-color: var(--color-yellow-200, oklch(94.5% 0.129 101.54));
189
189
  }
190
+ .bg-\[\#1e8449\] {
191
+ background-color: #1e8449;
192
+ }
193
+ .bg-\[color\:var\(--os-badge-bg\)\] {
194
+ background-color: var(--os-badge-bg);
195
+ }
196
+ .bg-\[color\:var\(--os-dot-bg\)\] {
197
+ background-color: var(--os-dot-bg);
198
+ }
190
199
  .bg-background\/60 {
191
200
  background-color: color-mix(in srgb, hsl(var(--background)) 60%, transparent);
192
201
  @supports (color: color-mix(in lab, red, red)) {
@@ -268,9 +277,6 @@
268
277
  .bg-yellow-500 {
269
278
  background-color: var(--color-yellow-500, oklch(79.5% 0.184 86.047));
270
279
  }
271
- .p-1\.5 {
272
- padding: calc(var(--spacing, 0.25rem) * 1.5);
273
- }
274
280
  .px-px {
275
281
  padding-inline: 1px;
276
282
  }
@@ -286,15 +292,15 @@
286
292
  .pl-9 {
287
293
  padding-left: calc(var(--spacing, 0.25rem) * 9);
288
294
  }
295
+ .text-\[color\:var\(--os-badge-fg\)\] {
296
+ color: var(--os-badge-fg);
297
+ }
289
298
  .text-blue-600 {
290
299
  color: var(--color-blue-600, oklch(54.6% 0.245 262.881));
291
300
  }
292
301
  .text-blue-700 {
293
302
  color: var(--color-blue-700, oklch(48.8% 0.243 264.376));
294
303
  }
295
- .text-gray-400 {
296
- color: var(--color-gray-400, oklch(70.7% 0.022 261.325));
297
- }
298
304
  .text-gray-500 {
299
305
  color: var(--color-gray-500, oklch(55.1% 0.027 264.364));
300
306
  }
@@ -491,6 +497,9 @@
491
497
  max-width: var(--container-5xl, 64rem);
492
498
  }
493
499
  }
500
+ .dark\:border-\[color\:var\(--os-badge-border-dark\)\]:where(.dark, .dark *) {
501
+ border-color: var(--os-badge-border-dark);
502
+ }
494
503
  .dark\:border-blue-900\/60:where(.dark, .dark *) {
495
504
  border-color: color-mix(in srgb, oklch(37.9% 0.146 265.522) 60%, transparent);
496
505
  @supports (color: color-mix(in lab, red, red)) {
@@ -545,6 +554,12 @@
545
554
  border-color: color-mix(in oklab, var(--color-yellow-900, oklch(42.1% 0.095 57.708)) 60%, transparent);
546
555
  }
547
556
  }
557
+ .dark\:bg-\[color\:var\(--os-badge-bg-dark\)\]:where(.dark, .dark *) {
558
+ background-color: var(--os-badge-bg-dark);
559
+ }
560
+ .dark\:bg-\[color\:var\(--os-dot-bg-dark\)\]:where(.dark, .dark *) {
561
+ background-color: var(--os-dot-bg-dark);
562
+ }
548
563
  .dark\:bg-blue-950\/40:where(.dark, .dark *) {
549
564
  background-color: color-mix(in srgb, oklch(28.2% 0.091 267.935) 40%, transparent);
550
565
  @supports (color: color-mix(in lab, red, red)) {
@@ -602,6 +617,9 @@
602
617
  background-color: color-mix(in oklab, var(--color-yellow-950, oklch(28.6% 0.066 53.813)) 40%, transparent);
603
618
  }
604
619
  }
620
+ .dark\:text-\[color\:var\(--os-badge-fg-dark\)\]:where(.dark, .dark *) {
621
+ color: var(--os-badge-fg-dark);
622
+ }
605
623
  .dark\:text-blue-300:where(.dark, .dark *) {
606
624
  color: var(--color-blue-300, oklch(80.9% 0.105 251.813));
607
625
  }
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { default as React } from 'react';
2
2
  import { FieldMetadata } from '@object-ui/types';
3
- import { resolveFieldCurrency } from './currency';
3
+ import { humanizeLabel, ComponentMeta } from '@object-ui/core';
4
+ import { resolveFieldCurrency } from './currency.js';
4
5
  /**
5
6
  * Pick the most reasonable display name from an arbitrary record object.
6
7
  * Tries common name-like keys in priority order, then falls back to undefined.
@@ -60,15 +61,21 @@ export declare function formatNumber(value: number, decimals?: number, locale?:
60
61
  */
61
62
  export declare function formatPercent(value: number, precision?: number, locale?: string): string;
62
63
  /**
63
- * Humanize a snake_case or kebab-case string into Title Case.
64
- * Used as fallback label when no explicit option.label exists.
64
+ * Humanize a snake_case or kebab-case string into Title Case — the fallback
65
+ * label when no explicit `option.label` exists.
65
66
  *
66
- * Examples:
67
- * "in_progress" → "In Progress"
68
- * "high-priority" → "High Priority"
69
- * "active" → "Active"
70
- */
71
- export declare function humanizeLabel(value: string): string;
67
+ * Defined in `@object-ui/core` (`utils/humanize-label.ts`) and re-exported here
68
+ * because this package is one of its two doorways: `plugin-grid`,
69
+ * `plugin-gantt` and `plugin-detail` read it from `@object-ui/fields`, while
70
+ * `plugin-charts` reads the same function straight from core. Until
71
+ * objectui#5444 this file and `plugin-charts`' `ObjectChart.tsx` each held a
72
+ * byte-identical private copy; core is the shared ancestor both packages
73
+ * already depend on, so the convention has one home and no new dependency edge
74
+ * (objectui#4389: core-canonical logic, plugins consume). The core docstring
75
+ * carries the convention itself, and the reason it stays distinct from
76
+ * `humanizeFieldKey`'s camelCase-splitting KEY convention.
77
+ */
78
+ export { humanizeLabel };
72
79
  /** Options shared by {@link formatDate} / {@link formatRelativeDate}. */
73
80
  export interface DateDisplayOptions {
74
81
  dueLike?: boolean;
@@ -134,6 +141,43 @@ export declare function DateCellRenderer({ value, field }: CellRendererProps): R
134
141
  * DateTime field cell renderer (Airtable-style with date and time visually separated)
135
142
  */
136
143
  export declare function DateTimeCellRenderer({ value }: CellRendererProps): React.ReactElement;
144
+ /** The six pill colors plus the two dot colors derived from one declared hex. */
145
+ export interface HexBadgePalette {
146
+ bg: string;
147
+ fg: string;
148
+ border: string;
149
+ bgDark: string;
150
+ fgDark: string;
151
+ borderDark: string;
152
+ dot: string;
153
+ dotDark: string;
154
+ }
155
+ /**
156
+ * Derive a full soft-pill palette from an author-declared hex.
157
+ *
158
+ * The declared LIGHTNESS is what separates two same-hue tiers (`#2ecc71` is
159
+ * l=0.49, `#1e8449` is l=0.32 — their hues differ by 0.1°), so it has to
160
+ * survive into the *surface*. A fixed pale tint — the obvious reading of
161
+ * "compute a soft pill from the hex" — does not carry it: measured, that
162
+ * leaves the reported pair ΔE 2.3 apart in Lab, at the ~2.3 just-noticeable
163
+ * threshold, which would close this issue on paper while the user still cannot
164
+ * tell the two badges apart. Letting the tint depth track the declared
165
+ * lightness puts them ΔE 8.0 apart instead.
166
+ */
167
+ export declare function deriveHexBadgePalette(color: string): HexBadgePalette | undefined;
168
+ /** A className plus the custom properties it reads. */
169
+ export interface HexColorAppearance {
170
+ className: string;
171
+ style: React.CSSProperties;
172
+ }
173
+ /**
174
+ * Soft-pill appearance for an explicitly declared hex, or `undefined` for
175
+ * every other kind of declaration (family name, no colour at all) so the
176
+ * caller falls back to `getBadgeColorClasses`.
177
+ */
178
+ export declare function getBadgeHexAppearance(color?: string): HexColorAppearance | undefined;
179
+ /** Dot appearance for an explicitly declared hex (see `getBadgeHexAppearance`). */
180
+ export declare function getDotHexAppearance(color?: string): HexColorAppearance | undefined;
137
181
  export declare function getBadgeColorClasses(color?: string, val?: unknown): string;
138
182
  /**
139
183
  * Resolve a semantic color name (e.g. "red", "green") for a value, suitable
@@ -246,14 +290,15 @@ export declare function JsonCellRenderer({ value }: CellRendererProps): React.Re
246
290
  */
247
291
  export declare function ColorSwatchCellRenderer({ value }: CellRendererProps): React.ReactElement;
248
292
  /**
249
- * Renders `markdown` / `richtext` values as formatted GFM markdown (lazy-loaded,
250
- * sanitized) instead of the raw markup string.
251
- */
252
- export declare function MarkdownCellRenderer({ value }: CellRendererProps): React.ReactElement;
253
- /**
254
- * Renders an `html` value as sanitized, formatted HTML instead of raw markup.
293
+ * The rich-content display pipelines — `markdown` through the GFM renderer,
294
+ * `html`/`richtext` through the sanitizing HTML renderer — live in
295
+ * `./widgets/richTextDisplay.js` rather than here, so `RichTextField` can
296
+ * import them without importing this barrel back (objectui#5498). Re-exported
297
+ * unchanged: they are part of this package's published surface, and
298
+ * `RICH_TEXT_CELL_RENDERERS` below is the one table both the cell resolver and
299
+ * the widget's readonly branch read.
255
300
  */
256
- export declare function HtmlCellRenderer({ value }: CellRendererProps): React.ReactElement;
301
+ export { MarkdownCellRenderer, HtmlCellRenderer } from './widgets/richTextDisplay.js';
257
302
  /**
258
303
  * Renders a `location`/`geolocation` value as readable coordinates with a pin.
259
304
  * Accepts `{ lat, lng }` / `{ latitude, longitude }`, a `"lat,lng"` string,
@@ -284,7 +329,8 @@ export declare function AddressCellRenderer({ value }: CellRendererProps): React
284
329
  * Get the appropriate cell renderer for a field type
285
330
  */
286
331
  export declare function getCellRenderer(fieldType: string): React.FC<CellRendererProps>;
287
- export { mapFieldTypeToFormType } from './field-type-alias';
332
+ export { mapFieldTypeToFormType } from './field-type-alias.js';
333
+ export { RETIRED_FIELD_TYPES, isRetiredFieldType, reportRetiredFieldType, resetRetiredFieldTypeReports, } from './field-type-alias.js';
288
334
  /**
289
335
  * Formats file size in bytes to human-readable string
290
336
  * @param bytes - File size in bytes (must be non-negative)
@@ -304,6 +350,235 @@ export declare function buildValidationRules(field: any): any;
304
350
  * @returns Whether the condition is met
305
351
  */
306
352
  export declare function evaluateCondition(condition: any, formData: any): boolean;
353
+ declare const fieldWidgetMap: {
354
+ text: () => Promise<{
355
+ default: React.ComponentType<any>;
356
+ } | {
357
+ default: typeof import('./widgets/TextField.js').TextField;
358
+ }>;
359
+ textarea: () => Promise<{
360
+ default: React.ComponentType<any>;
361
+ } | {
362
+ default: typeof import('./widgets/TextAreaField.js').TextAreaField;
363
+ }>;
364
+ number: () => Promise<{
365
+ default: React.ComponentType<any>;
366
+ } | {
367
+ default: typeof import('./widgets/NumberField.js').NumberField;
368
+ }>;
369
+ boolean: () => Promise<{
370
+ default: React.ComponentType<any>;
371
+ } | {
372
+ default: typeof import('./widgets/BooleanField.js').BooleanField;
373
+ }>;
374
+ select: () => Promise<{
375
+ default: React.ComponentType<any>;
376
+ } | {
377
+ default: typeof import('./widgets/SelectField.js').SelectField;
378
+ }>;
379
+ date: () => Promise<{
380
+ default: React.ComponentType<any>;
381
+ } | {
382
+ default: typeof import('./widgets/DateField.js').DateField;
383
+ }>;
384
+ datetime: () => Promise<{
385
+ default: React.ComponentType<any>;
386
+ } | {
387
+ default: typeof import('./widgets/DateTimeField.js').DateTimeField;
388
+ }>;
389
+ time: () => Promise<{
390
+ default: React.ComponentType<any>;
391
+ } | {
392
+ default: typeof import('./widgets/TimeField.js').TimeField;
393
+ }>;
394
+ email: () => Promise<{
395
+ default: React.ComponentType<any>;
396
+ } | {
397
+ default: typeof import('./widgets/EmailField.js').EmailField;
398
+ }>;
399
+ phone: () => Promise<{
400
+ default: React.ComponentType<any>;
401
+ } | {
402
+ default: typeof import('./widgets/PhoneField.js').PhoneField;
403
+ }>;
404
+ url: () => Promise<{
405
+ default: React.ComponentType<any>;
406
+ } | {
407
+ default: typeof import('./widgets/UrlField.js').UrlField;
408
+ }>;
409
+ multiselect: () => Promise<{
410
+ default: React.ComponentType<any>;
411
+ } | {
412
+ default: typeof import('./widgets/MultiSelectField.js').MultiSelectField;
413
+ }>;
414
+ radio: () => Promise<{
415
+ default: React.ComponentType<any>;
416
+ } | {
417
+ default: typeof import('./widgets/RadioField.js').RadioField;
418
+ }>;
419
+ checkboxes: () => Promise<{
420
+ default: React.ComponentType<any>;
421
+ } | {
422
+ default: typeof import('./widgets/CheckboxesField.js').CheckboxesField;
423
+ }>;
424
+ tags: () => Promise<{
425
+ default: React.ComponentType<any>;
426
+ } | {
427
+ default: typeof import('./widgets/TagsField.js').TagsField;
428
+ }>;
429
+ currency: () => Promise<{
430
+ default: React.ComponentType<any>;
431
+ } | {
432
+ default: typeof import('./widgets/CurrencyField.js').CurrencyField;
433
+ }>;
434
+ percent: () => Promise<{
435
+ default: React.ComponentType<any>;
436
+ } | {
437
+ default: typeof import('./widgets/PercentField.js').PercentField;
438
+ }>;
439
+ password: () => Promise<{
440
+ default: React.ComponentType<any>;
441
+ } | {
442
+ default: typeof import('./widgets/PasswordField.js').PasswordField;
443
+ }>;
444
+ markdown: () => Promise<{
445
+ default: React.ComponentType<any>;
446
+ } | {
447
+ default: typeof import('./widgets/RichTextField.js').RichTextField;
448
+ }>;
449
+ html: () => Promise<{
450
+ default: React.ComponentType<any>;
451
+ } | {
452
+ default: typeof import('./widgets/RichTextField.js').RichTextField;
453
+ }>;
454
+ richtext: () => Promise<{
455
+ default: React.ComponentType<any>;
456
+ } | {
457
+ default: typeof import('./widgets/RichTextField.js').RichTextField;
458
+ }>;
459
+ lookup: () => Promise<{
460
+ default: React.ComponentType<any>;
461
+ } | {
462
+ default: typeof import('./widgets/LookupField.js').LookupField;
463
+ }>;
464
+ master_detail: () => Promise<{
465
+ default: React.ComponentType<any>;
466
+ } | {
467
+ default: typeof import('./widgets/LookupField.js').LookupField;
468
+ }>;
469
+ file: () => Promise<{
470
+ default: React.ComponentType<any>;
471
+ } | {
472
+ default: typeof import('./widgets/FileField.js').FileField;
473
+ }>;
474
+ image: () => Promise<{
475
+ default: React.ComponentType<any>;
476
+ } | {
477
+ default: typeof import('./widgets/ImageField.js').ImageField;
478
+ }>;
479
+ location: () => Promise<{
480
+ default: React.ComponentType<any>;
481
+ } | {
482
+ default: typeof import('./widgets/LocationField.js').LocationField;
483
+ }>;
484
+ formula: () => Promise<{
485
+ default: React.ComponentType<any>;
486
+ } | {
487
+ default: typeof import('./widgets/FormulaField.js').FormulaField;
488
+ }>;
489
+ summary: () => Promise<{
490
+ default: React.ComponentType<any>;
491
+ } | {
492
+ default: typeof import('./widgets/SummaryField.js').SummaryField;
493
+ }>;
494
+ auto_number: () => Promise<{
495
+ default: React.ComponentType<any>;
496
+ } | {
497
+ default: typeof import('./widgets/AutoNumberField.js').AutoNumberField;
498
+ }>;
499
+ user: () => Promise<{
500
+ default: React.ComponentType<any>;
501
+ } | {
502
+ default: typeof import('./widgets/UserField.js').UserField;
503
+ }>;
504
+ object: () => Promise<{
505
+ default: React.ComponentType<any>;
506
+ } | {
507
+ default: typeof import('./widgets/ObjectField.js').ObjectField;
508
+ }>;
509
+ vector: () => Promise<{
510
+ default: React.ComponentType<any>;
511
+ } | {
512
+ default: typeof import('./widgets/VectorField.js').VectorField;
513
+ }>;
514
+ grid: () => Promise<{
515
+ default: React.ComponentType<any>;
516
+ } | {
517
+ default: typeof import('./widgets/GridField.js').GridField;
518
+ }>;
519
+ color: () => Promise<{
520
+ default: React.ComponentType<any>;
521
+ } | {
522
+ default: typeof import('./widgets/ColorField.js').ColorField;
523
+ }>;
524
+ slider: () => Promise<{
525
+ default: React.ComponentType<any>;
526
+ } | {
527
+ default: typeof import('./widgets/SliderField.js').SliderField;
528
+ }>;
529
+ rating: () => Promise<{
530
+ default: React.ComponentType<any>;
531
+ } | {
532
+ default: typeof import('./widgets/RatingField.js').RatingField;
533
+ }>;
534
+ code: () => Promise<{
535
+ default: React.ComponentType<any>;
536
+ } | {
537
+ default: typeof import('./widgets/CodeField.js').CodeField;
538
+ }>;
539
+ avatar: () => Promise<{
540
+ default: React.ComponentType<any>;
541
+ } | {
542
+ default: typeof import('./widgets/AvatarField.js').AvatarField;
543
+ }>;
544
+ address: () => Promise<{
545
+ default: React.ComponentType<any>;
546
+ } | {
547
+ default: typeof import('./widgets/AddressField.js').AddressField;
548
+ }>;
549
+ geolocation: () => Promise<{
550
+ default: React.ComponentType<any>;
551
+ } | {
552
+ default: typeof import('./widgets/GeolocationField.js').GeolocationField;
553
+ }>;
554
+ signature: () => Promise<{
555
+ default: React.ComponentType<any>;
556
+ } | {
557
+ default: typeof import('./widgets/SignatureField.js').SignatureField;
558
+ }>;
559
+ qrcode: () => Promise<{
560
+ default: React.ComponentType<any>;
561
+ } | {
562
+ default: typeof import('./widgets/QRCodeField.js').QRCodeField;
563
+ }>;
564
+ 'object-ref': () => Promise<{
565
+ default: React.ComponentType<any>;
566
+ } | {
567
+ default: typeof import('./widgets/ObjectRefField.js').ObjectRefField;
568
+ }>;
569
+ 'filter-condition': () => Promise<{
570
+ default: React.ComponentType<any>;
571
+ } | {
572
+ default: typeof import('./widgets/FilterConditionField.js').FilterConditionField;
573
+ }>;
574
+ 'recipient-picker': () => Promise<{
575
+ default: React.ComponentType<any>;
576
+ } | {
577
+ default: typeof import('./widgets/RecipientPickerField.js').RecipientPickerField;
578
+ }>;
579
+ };
580
+ /** The registered field widget keys, as a literal union (objectui#4857). */
581
+ export type RegisteredFieldWidgetType = keyof typeof fieldWidgetMap;
307
582
  /**
308
583
  * Every field type the form can render (the canonical list of supported types).
309
584
  * Exported so inline editing can be checked against it — a form type must
@@ -323,6 +598,18 @@ export declare const FORM_FIELD_TYPES: readonly string[];
323
598
  * support can never drift behind the form surface (ADR-0059).
324
599
  */
325
600
  export declare function resolveFormWidgetType(fieldType: string): string;
601
+ /**
602
+ * The widget keys that must be fed the live record (`dependentValues`) so their
603
+ * offered option set can be re-resolved per option `visibleWhen` / `dependsOn`.
604
+ *
605
+ * Defined in `@object-ui/core`, next to `resolveCascadingOptions` — the
606
+ * evaluator that reads the record — and re-exported here because this is the
607
+ * package whose {@link resolveFormWidgetType} produces the keys the set is
608
+ * keyed on: a consumer resolving a widget key finds the allow-table in the
609
+ * same place. One definition, two doorways; never a second copy (objectui#4770,
610
+ * which converged the three private copies that preceded it).
611
+ */
612
+ export { CASCADE_OPTION_WIDGET_TYPES } from '@object-ui/core';
326
613
  /**
327
614
  * Lazily-loaded form field widget for a field type. Shares the exact loaders
328
615
  * of {@link fieldWidgetMap} (the same components `registerField` registers for
@@ -332,6 +619,59 @@ export declare function resolveFormWidgetType(fieldType: string): string;
332
619
  * widget via {@link resolveFormWidgetType}.
333
620
  */
334
621
  export declare function getLazyFieldWidget(fieldType: string): React.ComponentType<any>;
622
+ /**
623
+ * The labelling declaration of EVERY registered field widget
624
+ * (`ComponentMeta.labelling` — the closed `'control' | 'group' | 'display'`
625
+ * vocabulary, objectui#3961 extended by objectui#4857). This `Record` is keyed
626
+ * by the widget map's own literal key union, so it is exhaustive BY
627
+ * CONSTRUCTION: registering a widget without deciding how a host's label
628
+ * reaches it is a COMPILE error here, not a silent fall-through to the
629
+ * `'control'` path — the omitted-declaration degradation is exactly the trap
630
+ * the #4857 ruling named, and it is what turned the display-only four into
631
+ * fields with no accessible name.
632
+ *
633
+ * ## `'group'` — a surface no `<label for>` can reach; the WIDGET consumes the IDREF
634
+ *
635
+ * Two shapes, one declaration:
636
+ *
637
+ * - real composites — `address` / `geolocation` render several inputs under one
638
+ * container, `checkboxes` / `radio` / `rating` / `multiselect` a set of
639
+ * choice controls, and `grid` a whole table of cell inputs plus row actions;
640
+ * the host's label names the GROUP, each sub-control keeps its own name (a
641
+ * sub-label, the chip's text content, or a cell's own `aria-label`).
642
+ * - single non-labelable controls — `file`'s one control is a
643
+ * `div[role="button"]` dropzone, `slider`'s is Radix's `span[role="slider"]`
644
+ * thumb (objectui#3318), `signature`'s drawing surface is a `<canvas>`
645
+ * (objectui#3318). A `div`/`span`/`canvas` cannot be `for`-labelled, so the
646
+ * name goes by IDREF to the control (or, for `signature`, its container).
647
+ *
648
+ * Measured, not assumed: every `'group'` entry was verified in a real form —
649
+ * the #3961/#3975 probes for the first seven, the #3318 delivery for
650
+ * `slider`/`signature`, and the #4857 re-measurement for `grid` (bare config:
651
+ * one focusable, the auxiliary "Add line" BUTTON — routing `for` there would
652
+ * have label clicks INSERT A ROW; realistic config: 8 focusables across cell
653
+ * inputs and row actions — a composite, not a single control).
654
+ *
655
+ * ## `'display'` — a pure display in EVERY state; the HOST wraps (objectui#4857)
656
+ *
657
+ * `formula` / `summary` / `auto_number` / `vector` have no editable branch at
658
+ * all: the whole widget is a replacement display with no focusable control, in
659
+ * the editable state as much as the readonly one (on the real object-form path
660
+ * they arrive `disabled`, never `readonly`, so the #4788 readonly gate could
661
+ * not cover them). The form renderer answers the declaration with its own
662
+ * wrapper — id + `aria-labelledby` + `aria-describedby` + `role="group"`, the
663
+ * #4788 container — and the label emits no `for`. The widgets spread nothing,
664
+ * by design; the host is the named surface.
665
+ *
666
+ * ## `'control'` — everything else
667
+ *
668
+ * The host's `<label for>` reaches a real labelable element. At registration
669
+ * this is deliberately spelled as ABSENCE of the meta key (one spelling of the
670
+ * default, objectui#3961), so hosts keep one rule for these and for
671
+ * out-of-registry widgets alike; the entry here is still mandatory, because
672
+ * "defaulted by omission" and "decided to be the default" are different facts.
673
+ */
674
+ export declare const FIELD_WIDGET_LABELLING: Record<RegisteredFieldWidgetType, NonNullable<ComponentMeta['labelling']>>;
335
675
  export declare function registerField(fieldType: string): void;
336
676
  /**
337
677
  * Register all field types (for backward compatibility)
@@ -343,59 +683,72 @@ export declare function registerField(fieldType: string): void;
343
683
  * // Register all fields at once
344
684
  * registerAllFields();
345
685
  */
686
+ /**
687
+ * The widget a RETIRED field-type spelling renders (objectui#4814).
688
+ *
689
+ * Shape borrowed from the form renderer's spec-vocabulary boundary (#3090),
690
+ * which is this repo's settled answer to "an authored entry this renderer
691
+ * cannot honour": an inline alert that NAMES the offending entry, plus a
692
+ * `console.error` whose text doubles as the fix instruction. Nothing is thrown
693
+ * — one retired field must not take down the rest of a record form — but
694
+ * nothing is silently substituted either, which is the whole point: the author
695
+ * sees a refusal where they expected an input, not a text box that looks like
696
+ * it worked.
697
+ */
698
+ export declare const RetiredFieldTombstone: React.FC<Record<string, any>>;
346
699
  export declare function registerAllFields(): void;
347
- export * from './widgets/types';
348
- export * from './widgets/file-value';
349
- export * from './FieldEditWidget';
350
- export * from './widgets/TextField';
351
- export * from './widgets/NumberField';
352
- export * from './widgets/BooleanField';
353
- export * from './widgets/SelectField';
354
- export * from './widgets/DateField';
355
- export * from './widgets/DateTimeField';
356
- export * from './widgets/TimeField';
357
- export * from './widgets/EmailField';
358
- export * from './widgets/PhoneField';
359
- export * from './widgets/UrlField';
360
- export * from './widgets/CurrencyField';
361
- export * from './widgets/PercentField';
362
- export * from './widgets/PasswordField';
363
- export * from './widgets/TextAreaField';
364
- export * from './widgets/RichTextField';
365
- export * from './widgets/LookupField';
366
- export * from './widgets/CapabilityMultiSelectField';
367
- export * from './widgets/ObjectRefField';
368
- export * from './widgets/FilterConditionField';
369
- export * from './widgets/RecipientPickerField';
370
- export * from './widgets/RecordPickerDialog';
371
- export * from './widgets/deriveLookupColumns';
372
- export * from './widgets/FileField';
373
- export * from './widgets/ImageField';
374
- export { ImageCropperDialog } from './widgets/ImageCropperDialog';
375
- export type { ImageCropperDialogProps } from './widgets/ImageCropperDialog';
376
- export * from './widgets/LocationField';
377
- export * from './widgets/FormulaField';
378
- export * from './widgets/SummaryField';
379
- export * from './widgets/AutoNumberField';
380
- export * from './widgets/UserField';
381
- export * from './widgets/ObjectField';
382
- export * from './widgets/VectorField';
383
- export * from './widgets/GridField';
384
- export * from './widgets/ColorField';
385
- export * from './widgets/SliderField';
386
- export * from './widgets/RatingField';
387
- export * from './widgets/CodeField';
388
- export * from './widgets/AvatarField';
389
- export * from './widgets/AddressField';
390
- export * from './widgets/GeolocationField';
391
- export * from './widgets/SignatureField';
392
- export * from './widgets/QRCodeField';
393
- export * from './widgets/MasterDetailField';
394
- export * from './widgets/MultiSelectField';
395
- export * from './widgets/RadioField';
396
- export * from './widgets/CheckboxesField';
397
- export * from './widgets/TagsField';
398
- export { withFieldCarrier } from './withFieldCarrier';
399
- export { toDomProps } from './widgets/toDomProps';
400
- export type { DomProps } from './widgets/toDomProps';
401
- export { toDateInputValue, toDateTimeInputValue, fromDateTimeInputValue, } from './widgets/nativeDateValue';
700
+ export * from './widgets/types.js';
701
+ export * from './widgets/file-value.js';
702
+ export * from './FieldEditWidget.js';
703
+ export * from './widgets/TextField.js';
704
+ export * from './widgets/NumberField.js';
705
+ export * from './widgets/BooleanField.js';
706
+ export * from './widgets/SelectField.js';
707
+ export * from './widgets/DateField.js';
708
+ export * from './widgets/DateTimeField.js';
709
+ export * from './widgets/TimeField.js';
710
+ export * from './widgets/EmailField.js';
711
+ export * from './widgets/PhoneField.js';
712
+ export * from './widgets/UrlField.js';
713
+ export * from './widgets/CurrencyField.js';
714
+ export * from './widgets/PercentField.js';
715
+ export * from './widgets/PasswordField.js';
716
+ export * from './widgets/TextAreaField.js';
717
+ export * from './widgets/RichTextField.js';
718
+ export * from './widgets/LookupField.js';
719
+ export * from './widgets/CapabilityMultiSelectField.js';
720
+ export * from './widgets/ObjectRefField.js';
721
+ export * from './widgets/FilterConditionField.js';
722
+ export * from './widgets/RecipientPickerField.js';
723
+ export * from './widgets/RecordPickerDialog.js';
724
+ export * from './widgets/deriveLookupColumns.js';
725
+ export * from './widgets/FileField.js';
726
+ export * from './widgets/ImageField.js';
727
+ export { ImageCropperDialog } from './widgets/ImageCropperDialog.js';
728
+ export type { ImageCropperDialogProps } from './widgets/ImageCropperDialog.js';
729
+ export * from './widgets/LocationField.js';
730
+ export * from './widgets/FormulaField.js';
731
+ export * from './widgets/SummaryField.js';
732
+ export * from './widgets/AutoNumberField.js';
733
+ export * from './widgets/UserField.js';
734
+ export * from './widgets/ObjectField.js';
735
+ export * from './widgets/VectorField.js';
736
+ export * from './widgets/GridField.js';
737
+ export * from './widgets/ColorField.js';
738
+ export * from './widgets/SliderField.js';
739
+ export * from './widgets/RatingField.js';
740
+ export * from './widgets/CodeField.js';
741
+ export * from './widgets/AvatarField.js';
742
+ export * from './widgets/AddressField.js';
743
+ export * from './widgets/GeolocationField.js';
744
+ export * from './widgets/SignatureField.js';
745
+ export * from './widgets/QRCodeField.js';
746
+ export * from './widgets/MasterDetailField.js';
747
+ export * from './widgets/MultiSelectField.js';
748
+ export * from './widgets/RadioField.js';
749
+ export * from './widgets/CheckboxesField.js';
750
+ export * from './widgets/TagsField.js';
751
+ export { withFieldCarrier } from './withFieldCarrier.js';
752
+ export { toDomProps } from './widgets/toDomProps.js';
753
+ export type { DomProps } from './widgets/toDomProps.js';
754
+ export { toDateInputValue, toDateTimeInputValue, fromDateTimeInputValue, } from './widgets/nativeDateValue.js';