@dxos/react-ui-form 0.7.4 → 0.7.5-labs.5f04cf6

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 (65) hide show
  1. package/dist/lib/browser/index.mjs +574 -496
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +629 -565
  5. package/dist/lib/node/index.cjs.map +4 -4
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/lib/node-esm/index.mjs +574 -496
  8. package/dist/lib/node-esm/index.mjs.map +4 -4
  9. package/dist/lib/node-esm/meta.json +1 -1
  10. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts +2 -2
  11. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
  12. package/dist/types/src/components/Form/ArrayField.d.ts +16 -0
  13. package/dist/types/src/components/Form/ArrayField.d.ts.map +1 -0
  14. package/dist/types/src/components/Form/Defaults.d.ts +5 -6
  15. package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
  16. package/dist/types/src/components/Form/Form.d.ts +13 -17
  17. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  18. package/dist/types/src/components/Form/Form.stories.d.ts +7 -1
  19. package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
  20. package/dist/types/src/components/Form/FormActions.d.ts +7 -0
  21. package/dist/types/src/components/Form/FormActions.d.ts.map +1 -0
  22. package/dist/types/src/components/Form/FormContent.d.ts +26 -0
  23. package/dist/types/src/components/Form/FormContent.d.ts.map +1 -0
  24. package/dist/types/src/components/Form/FormContext.d.ts +20 -0
  25. package/dist/types/src/components/Form/FormContext.d.ts.map +1 -0
  26. package/dist/types/src/components/Form/Input.d.ts +5 -6
  27. package/dist/types/src/components/Form/Input.d.ts.map +1 -1
  28. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts +4 -0
  29. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts.map +1 -0
  30. package/dist/types/src/components/Form/custom/TupleInput.d.ts +6 -0
  31. package/dist/types/src/components/Form/custom/TupleInput.d.ts.map +1 -0
  32. package/dist/types/src/components/Form/custom/index.d.ts +3 -0
  33. package/dist/types/src/components/Form/custom/index.d.ts.map +1 -0
  34. package/dist/types/src/components/Form/factory.d.ts +2 -2
  35. package/dist/types/src/components/Form/factory.d.ts.map +1 -1
  36. package/dist/types/src/components/Form/index.d.ts +2 -2
  37. package/dist/types/src/components/Form/index.d.ts.map +1 -1
  38. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +6 -5
  39. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
  40. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
  41. package/dist/types/src/hooks/useForm.d.ts +13 -15
  42. package/dist/types/src/hooks/useForm.d.ts.map +1 -1
  43. package/dist/types/tsconfig.tsbuildinfo +1 -0
  44. package/package.json +26 -26
  45. package/src/components/FieldEditor/FieldEditor.stories.tsx +2 -2
  46. package/src/components/FieldEditor/FieldEditor.tsx +75 -50
  47. package/src/components/Form/ArrayField.tsx +111 -0
  48. package/src/components/Form/Defaults.tsx +20 -33
  49. package/src/components/Form/Form.stories.tsx +48 -6
  50. package/src/components/Form/Form.tsx +39 -333
  51. package/src/components/Form/FormActions.tsx +41 -0
  52. package/src/components/Form/FormContent.tsx +155 -0
  53. package/src/components/Form/FormContext.tsx +48 -0
  54. package/src/components/Form/Input.tsx +5 -6
  55. package/src/components/Form/custom/GeoPointInput.tsx +44 -0
  56. package/src/components/Form/custom/TupleInput.tsx +49 -0
  57. package/src/components/Form/custom/index.ts +6 -0
  58. package/src/components/Form/factory.tsx +4 -7
  59. package/src/components/Form/index.ts +3 -2
  60. package/src/components/ViewEditor/ViewEditor.stories.tsx +30 -8
  61. package/src/components/ViewEditor/ViewEditor.tsx +13 -8
  62. package/src/hooks/useForm.ts +67 -78
  63. package/dist/types/src/components/Form/Custom.d.ts +0 -5
  64. package/dist/types/src/components/Form/Custom.d.ts.map +0 -1
  65. package/src/components/Form/Custom.tsx +0 -65
@@ -32,12 +32,12 @@ __export(node_exports, {
32
32
  DeprecatedFormInput: () => DeprecatedFormInput,
33
33
  FieldEditor: () => FieldEditor,
34
34
  Form: () => Form,
35
- FormActions: () => FormActions,
36
- GeiPointInput: () => GeiPointInput,
35
+ GeoPointInput: () => GeoPointInput,
37
36
  InputHeader: () => InputHeader,
38
37
  NumberInput: () => NumberInput,
39
38
  SelectInput: () => SelectInput,
40
39
  TextInput: () => TextInput,
40
+ TupleInput: () => TupleInput,
41
41
  ViewEditor: () => ViewEditor,
42
42
  cellClassesForFieldType: () => cellClassesForFieldType,
43
43
  cellClassesForRowSelection: () => cellClassesForRowSelection,
@@ -56,37 +56,60 @@ var import_echo_schema = require("@dxos/echo-schema");
56
56
  var import_log = require("@dxos/log");
57
57
  var import_react_ui2 = require("@dxos/react-ui");
58
58
  var import_schema = require("@dxos/schema");
59
- var import_effect = require("effect");
60
- var import_String = require("effect/String");
61
59
  var import_react3 = __toESM(require("react"));
62
- var import_echo_schema2 = require("@dxos/echo-schema");
63
- var import_effect2 = require("@dxos/effect");
64
- var import_log2 = require("@dxos/log");
65
60
  var import_react_ui3 = require("@dxos/react-ui");
66
- var import_react_ui_theme = require("@dxos/react-ui-theme");
67
- var import_schema2 = require("@dxos/schema");
68
61
  var import_util = require("@dxos/util");
69
62
  var import_react4 = __toESM(require("react"));
70
63
  var import_react_ui4 = require("@dxos/react-ui");
64
+ var import_react_ui_theme = require("@dxos/react-ui-theme");
71
65
  var import_react5 = __toESM(require("react"));
72
66
  var import_react_ui5 = require("@dxos/react-ui");
73
67
  var import_react_ui_theme2 = require("@dxos/react-ui-theme");
74
- var import_echo_schema3 = require("@dxos/echo-schema");
68
+ var import_util2 = require("@dxos/util");
75
69
  var import_react6 = __toESM(require("react"));
76
70
  var import_react_ui6 = require("@dxos/react-ui");
77
- var import_react7 = require("react");
78
- var import_invariant = require("@dxos/invariant");
79
- var import_log3 = require("@dxos/log");
80
- var import_schema3 = require("@dxos/schema");
71
+ var import_react7 = __toESM(require("react"));
72
+ var import_react_ui_theme3 = require("@dxos/react-ui-theme");
81
73
  var import_react8 = __toESM(require("react"));
82
- var import_echo_schema4 = require("@dxos/echo-schema");
83
74
  var import_react_ui7 = require("@dxos/react-ui");
84
- var import_react_ui_list = require("@dxos/react-ui-list");
85
- var import_react_ui_theme3 = require("@dxos/react-ui-theme");
86
- var import_schema4 = require("@dxos/schema");
87
- var import_util2 = require("@dxos/util");
75
+ var import_react_ui_theme4 = require("@dxos/react-ui-theme");
76
+ var import_react9 = __toESM(require("react"));
77
+ var import_debug = require("@dxos/debug");
78
+ var import_echo_schema2 = require("@dxos/echo-schema");
79
+ var import_effect = require("@dxos/effect");
80
+ var import_react10 = require("react");
81
+ var import_echo_schema3 = require("@dxos/echo-schema");
82
+ var import_effect2 = require("@dxos/effect");
83
+ var import_invariant = require("@dxos/invariant");
84
+ var import_log2 = require("@dxos/log");
85
+ var import_schema2 = require("@dxos/schema");
86
+ var import_effect3 = require("effect");
87
+ var import_String = require("effect/String");
88
+ var import_react11 = __toESM(require("react"));
89
+ var import_echo_schema4 = require("@dxos/echo-schema");
90
+ var import_effect4 = require("@dxos/effect");
91
+ var import_react_ui_theme5 = require("@dxos/react-ui-theme");
92
+ var import_schema3 = require("@dxos/schema");
93
+ var import_util3 = require("@dxos/util");
94
+ var import_effect5 = require("effect");
95
+ var import_String2 = require("effect/String");
96
+ var import_react12 = __toESM(require("react"));
88
97
  var import_echo_schema5 = require("@dxos/echo-schema");
98
+ var import_effect6 = require("@dxos/effect");
99
+ var import_invariant2 = require("@dxos/invariant");
100
+ var import_react_ui8 = require("@dxos/react-ui");
101
+ var import_react_ui_theme6 = require("@dxos/react-ui-theme");
102
+ var import_schema4 = require("@dxos/schema");
89
103
  var import_echo_schema6 = require("@dxos/echo-schema");
104
+ var import_react13 = __toESM(require("react"));
105
+ var import_echo_schema7 = require("@dxos/echo-schema");
106
+ var import_react_ui9 = require("@dxos/react-ui");
107
+ var import_react_ui_list = require("@dxos/react-ui-list");
108
+ var import_react_ui_theme7 = require("@dxos/react-ui-theme");
109
+ var import_schema5 = require("@dxos/schema");
110
+ var import_util4 = require("@dxos/util");
111
+ var import_echo_schema8 = require("@dxos/echo-schema");
112
+ var import_echo_schema9 = require("@dxos/echo-schema");
90
113
  var translationKey = "react-ui-form";
91
114
  var translations_default = [
92
115
  {
@@ -163,161 +186,178 @@ var DeprecatedFormInput = ({ label, description, secondary, children }) => {
163
186
  return primary;
164
187
  };
165
188
  var InputHeader = ({ children, error }) => {
166
- return /* @__PURE__ */ import_react5.default.createElement("div", {
189
+ return /* @__PURE__ */ import_react4.default.createElement("div", {
167
190
  role: "none",
168
191
  className: "flex justify-between items-center mb-1"
169
- }, children, error && /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Tooltip.Root, null, /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Tooltip.Trigger, {
192
+ }, children, error && /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Tooltip.Root, null, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Tooltip.Trigger, {
170
193
  asChild: true
171
- }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Icon, {
194
+ }, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Icon, {
172
195
  icon: "ph--warning--regular",
173
196
  size: 4,
174
- classNames: import_react_ui_theme2.errorText
175
- })), /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Tooltip.Content, {
197
+ classNames: import_react_ui_theme.errorText
198
+ })), /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Tooltip.Content, {
176
199
  side: "bottom"
177
- }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Tooltip.Arrow, null), error)));
200
+ }, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Tooltip.Arrow, null), error)));
178
201
  };
179
- var TextInput = ({ property, type, label, inputOnly, disabled, placeholder, getStatus, getValue, onValueChange, onBlur }) => {
180
- const { status, error } = getStatus?.(property);
181
- return /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.Root, {
202
+ var GeoPointInput = ({ type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
203
+ const { t } = (0, import_react_ui3.useTranslation)(translationKey);
204
+ const { status, error } = getStatus();
205
+ const [lng = 0, lat = 0] = getValue3() ?? [];
206
+ return /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.Input.Root, {
182
207
  validationValence: status
183
- }, !inputOnly && /* @__PURE__ */ import_react4.default.createElement(InputHeader, {
208
+ }, /* @__PURE__ */ import_react3.default.createElement(InputHeader, {
184
209
  error
185
- }, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.Label, null, label)), /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.TextInput, {
210
+ }, /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.Input.Label, null, label)), /* @__PURE__ */ import_react3.default.createElement("div", {
211
+ className: "grid grid-cols-2 gap-2"
212
+ }, /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.Input.TextInput, {
213
+ type: "number",
214
+ disabled,
215
+ placeholder: t("placeholder longitude"),
216
+ value: lng,
217
+ onChange: (event) => onValueChange(type, [
218
+ lat,
219
+ (0, import_util.safeParseFloat)(event.target.value, 0)
220
+ ]),
221
+ onBlur
222
+ }), /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.Input.TextInput, {
223
+ type: "number",
224
+ disabled,
225
+ placeholder: t("placeholder latitude"),
226
+ value: lat,
227
+ onChange: (event) => onValueChange(type, [
228
+ (0, import_util.safeParseFloat)(event.target.value, 0),
229
+ lng
230
+ ]),
231
+ onBlur
232
+ })));
233
+ };
234
+ var gridCols = [
235
+ "grid-cols-1",
236
+ "grid-cols-2",
237
+ "grid-cols-3",
238
+ "grid-cols-4"
239
+ ];
240
+ var TupleInput = ({ binding, type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
241
+ const { status, error } = getStatus();
242
+ const values = getValue3() ?? {};
243
+ return /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Input.Root, {
244
+ validationValence: status
245
+ }, /* @__PURE__ */ import_react5.default.createElement(InputHeader, {
246
+ error
247
+ }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Input.Label, null, label)), /* @__PURE__ */ import_react5.default.createElement("div", {
248
+ className: (0, import_react_ui_theme2.mx)("grid gap-2", gridCols[binding.length - 1])
249
+ }, binding.map((prop) => /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Input.TextInput, {
250
+ key: prop,
251
+ type: "number",
252
+ disabled,
253
+ value: values[prop],
254
+ onChange: (event) => onValueChange(type, {
255
+ ...values,
256
+ [prop]: (0, import_util2.safeParseFloat)(event.target.value, 0)
257
+ }),
258
+ onBlur
259
+ }))));
260
+ };
261
+ var TextInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
262
+ const { status, error } = getStatus();
263
+ return /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Root, {
264
+ validationValence: status
265
+ }, !inputOnly && /* @__PURE__ */ import_react6.default.createElement(InputHeader, {
266
+ error
267
+ }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Label, null, label)), /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.TextInput, {
186
268
  disabled,
187
269
  placeholder,
188
- value: getValue(property) ?? "",
189
- onChange: (event) => onValueChange(property, type, event.target.value),
270
+ value: getValue3() ?? "",
271
+ onChange: (event) => onValueChange(type, event.target.value),
190
272
  onBlur
191
- }), inputOnly && /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.Validation, null, error));
273
+ }), inputOnly && /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Validation, null, error));
192
274
  };
193
- var NumberInput = ({ property, type, label, inputOnly, disabled, placeholder, getStatus, getValue, onValueChange, onBlur }) => {
194
- const { status, error } = getStatus?.(property);
195
- return /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.Root, {
275
+ var NumberInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
276
+ const { status, error } = getStatus();
277
+ return /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Root, {
196
278
  validationValence: status
197
- }, !inputOnly && /* @__PURE__ */ import_react4.default.createElement(InputHeader, {
279
+ }, !inputOnly && /* @__PURE__ */ import_react6.default.createElement(InputHeader, {
198
280
  error
199
- }, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.Label, null, label)), /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.TextInput, {
281
+ }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Label, null, label)), /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.TextInput, {
200
282
  type: "number",
201
283
  disabled,
202
284
  placeholder,
203
- value: getValue(property) ?? 0,
204
- onChange: (event) => onValueChange(property, type, event.target.value),
285
+ value: getValue3() ?? 0,
286
+ onChange: (event) => onValueChange(type, event.target.value),
205
287
  onBlur
206
- }), inputOnly && /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.DescriptionAndValidation, null, error));
288
+ }), inputOnly && /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.DescriptionAndValidation, null, error));
207
289
  };
208
- var BooleanInput = ({ property, type, label, inputOnly, getStatus, getValue, onValueChange }) => {
209
- const { status, error } = getStatus?.(property);
210
- return /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.Root, {
290
+ var BooleanInput = ({ type, label, inputOnly, getStatus, getValue: getValue3, onValueChange }) => {
291
+ const { status, error } = getStatus();
292
+ return /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Root, {
211
293
  validationValence: status
212
- }, !inputOnly && /* @__PURE__ */ import_react4.default.createElement(InputHeader, {
294
+ }, !inputOnly && /* @__PURE__ */ import_react6.default.createElement(InputHeader, {
213
295
  error
214
- }, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.Label, null, label)), /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.Switch, {
215
- checked: getValue(property),
216
- onCheckedChange: (value) => onValueChange(property, type, value)
217
- }), inputOnly && /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.DescriptionAndValidation, null, error));
296
+ }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Label, null, label)), /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Switch, {
297
+ checked: getValue3(),
298
+ onCheckedChange: (value) => onValueChange(type, value)
299
+ }), inputOnly && /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.DescriptionAndValidation, null, error));
218
300
  };
219
- var SelectInput = ({ property, type, label, inputOnly, disabled, placeholder, options, getStatus, getValue, onValueChange }) => {
220
- const { status, error } = getStatus?.(property);
221
- return /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.Root, {
301
+ var SelectInput = ({ type, label, inputOnly, disabled, placeholder, options, getStatus, getValue: getValue3, onValueChange }) => {
302
+ const { status, error } = getStatus();
303
+ return /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Root, {
222
304
  validationValence: status
223
- }, !inputOnly && /* @__PURE__ */ import_react4.default.createElement(InputHeader, {
305
+ }, !inputOnly && /* @__PURE__ */ import_react6.default.createElement(InputHeader, {
224
306
  error
225
- }, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.Label, null, label)), /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Select.Root, {
226
- value: getValue(property),
227
- onValueChange: (value) => onValueChange(property, type, value)
228
- }, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Select.TriggerButton, {
307
+ }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Label, null, label)), /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Select.Root, {
308
+ value: getValue3(),
309
+ onValueChange: (value) => onValueChange(type, value)
310
+ }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Select.TriggerButton, {
229
311
  classNames: "is-full",
230
312
  disabled,
231
313
  placeholder
232
- }), /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Select.Portal, null, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Select.Content, null, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Select.Viewport, null, options?.map(({ value, label: label2 }) => (
314
+ }), /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Select.Portal, null, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Select.Content, null, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Select.Viewport, null, options?.map(({ value, label: label2 }) => (
233
315
  // NOTE: Numeric values are converted to and from strings.
234
- /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Select.Option, {
316
+ /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Select.Option, {
235
317
  key: String(value),
236
318
  value: String(value)
237
319
  }, label2 ?? String(value))
238
- )))))), inputOnly && /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.DescriptionAndValidation, null, error));
239
- };
240
- var GeiPointInput = ({ property, type, label, disabled, getStatus, getValue, onValueChange, onBlur }) => {
241
- const { t } = (0, import_react_ui6.useTranslation)(translationKey);
242
- const { status, error } = getStatus?.(property);
243
- const [lng = 0, lat = 0] = getValue(property) ?? [];
244
- return /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Root, {
245
- validationValence: status
246
- }, /* @__PURE__ */ import_react6.default.createElement(InputHeader, {
247
- error
248
- }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Label, null, label)), /* @__PURE__ */ import_react6.default.createElement("div", {
249
- className: "grid grid-cols-2 gap-2"
250
- }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.TextInput, {
251
- type: "number",
252
- disabled,
253
- placeholder: t("placeholder longitude"),
254
- value: lng,
255
- onChange: (event) => onValueChange(property, type, [
256
- lat,
257
- safeParseFloat(event.target.value, 0)
258
- ]),
259
- onBlur
260
- }), /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.TextInput, {
261
- type: "number",
262
- disabled,
263
- placeholder: t("placeholder latitude"),
264
- value: lat,
265
- onChange: (event) => onValueChange(property, type, [
266
- safeParseFloat(event.target.value, 0),
267
- lng
268
- ]),
269
- onBlur
270
- })));
271
- };
272
- var safeParseFloat = (str, defaultValue) => {
273
- try {
274
- return parseFloat(str);
275
- } catch {
276
- return defaultValue ?? 0;
277
- }
278
- };
279
- var getInputComponent = (type, format) => {
280
- switch (format) {
281
- case import_echo_schema3.FormatEnum.LatLng:
282
- return GeiPointInput;
283
- }
284
- switch (type) {
285
- case "string":
286
- return TextInput;
287
- case "number":
288
- return NumberInput;
289
- case "boolean":
290
- return BooleanInput;
291
- }
320
+ )))))), inputOnly && /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.DescriptionAndValidation, null, error));
292
321
  };
293
322
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/hooks/useForm.ts";
294
323
  var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, onSave }) => {
295
- const [values, setValues] = (0, import_react7.useState)(initialValues);
296
- (0, import_react7.useEffect)(() => {
324
+ (0, import_invariant.invariant)(import_effect2.AST.isTypeLiteral(schema.ast), void 0, {
325
+ F: __dxlog_file,
326
+ L: 91,
327
+ S: void 0,
328
+ A: [
329
+ "AST.isTypeLiteral(schema.ast)",
330
+ ""
331
+ ]
332
+ });
333
+ const [values, setValues] = (0, import_react10.useState)(initialValues);
334
+ (0, import_react10.useEffect)(() => {
297
335
  setValues(initialValues);
298
336
  }, [
299
337
  initialValues
300
338
  ]);
301
- const [touched, setTouched] = (0, import_react7.useState)(createKeySet(initialValues, false));
302
- const [changed, setChanged] = (0, import_react7.useState)(createKeySet(initialValues, false));
303
- const [errors, setErrors] = (0, import_react7.useState)({});
304
- const [saving, setSaving] = (0, import_react7.useState)(false);
305
- const validate = (0, import_react7.useCallback)((values2) => {
306
- let errors2 = (0, import_schema3.validateSchema)(schema, values2) ?? [];
339
+ const [touched, setTouched] = (0, import_react10.useState)(createKeySet(initialValues, false));
340
+ const [changed, setChanged] = (0, import_react10.useState)(createKeySet(initialValues, false));
341
+ const [errors, setErrors] = (0, import_react10.useState)({});
342
+ const [saving, setSaving] = (0, import_react10.useState)(false);
343
+ const validate = (0, import_react10.useCallback)((values2) => {
344
+ let errors2 = (0, import_schema2.validateSchema)(schema, values2) ?? [];
307
345
  if (errors2.length === 0 && onValidate) {
308
- errors2 = onValidate(values2) ?? [];
346
+ const validatedValues = values2;
347
+ errors2 = onValidate(validatedValues) ?? [];
309
348
  }
310
349
  setErrors(flatMap(errors2));
311
- return errors2.length === 0;
350
+ const valid = errors2.length === 0;
351
+ return valid;
312
352
  }, [
313
353
  schema,
314
354
  onValidate
315
355
  ]);
316
- const [schemaDirty, setSchemaDirty] = (0, import_react7.useState)(false);
317
- (0, import_react7.useEffect)(() => setSchemaDirty(true), [
356
+ const [schemaDirty, setSchemaDirty] = (0, import_react10.useState)(false);
357
+ (0, import_react10.useEffect)(() => setSchemaDirty(true), [
318
358
  schema
319
359
  ]);
320
- (0, import_react7.useEffect)(() => {
360
+ (0, import_react10.useEffect)(() => {
321
361
  if (schemaDirty) {
322
362
  validate(values);
323
363
  setSchemaDirty(false);
@@ -326,13 +366,13 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
326
366
  values,
327
367
  schemaDirty
328
368
  ]);
329
- const canSave = (0, import_react7.useMemo)(() => !saving && Object.keys(values).every((property) => touched[property] === false || !errors[property]), [
330
- values,
369
+ const canSave = (0, import_react10.useMemo)(() => !saving && // Check if any error paths that are touched have errors
370
+ !Object.entries(touched).some(([path, isTouched]) => isTouched && Object.keys(errors).some((errorPath) => errorPath === path || errorPath.startsWith(`${path}.`) || errorPath.startsWith(`${path}[`))), [
331
371
  touched,
332
372
  errors,
333
373
  saving
334
374
  ]);
335
- const handleSave = (0, import_react7.useCallback)(async () => {
375
+ const handleSave = (0, import_react10.useCallback)(async () => {
336
376
  if (validate(values)) {
337
377
  setSaving(true);
338
378
  try {
@@ -346,38 +386,45 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
346
386
  }, [
347
387
  values,
348
388
  validate,
349
- onSave
389
+ onSave,
390
+ changed
350
391
  ]);
351
- const getStatus = (0, import_react7.useCallback)((property) => ({
352
- status: errors[property] ? "error" : void 0,
353
- error: errors[property] ? errors[property] : void 0
354
- }), [
355
- touched,
392
+ const getStatus = (0, import_react10.useCallback)((path) => {
393
+ const jsonPath = Array.isArray(path) ? (0, import_effect2.createJsonPath)(path) : path;
394
+ const matchingError = Object.entries(errors).find(([errorPath]) => errorPath === jsonPath || errorPath.startsWith(`${jsonPath}.`) || errorPath.startsWith(`${jsonPath}[`));
395
+ return {
396
+ status: matchingError ? "error" : void 0,
397
+ error: matchingError ? matchingError[1] : void 0
398
+ };
399
+ }, [
356
400
  errors
357
401
  ]);
358
- const getValue = (property) => {
359
- return getByPath(values, property);
402
+ const getFormValue = (path) => {
403
+ return (0, import_echo_schema3.getValue)(values, (0, import_effect2.createJsonPath)(path));
360
404
  };
361
- const onValueChange = (property, type, value) => {
405
+ const onValueChange = (path, type, value) => {
406
+ const jsonPath = (0, import_effect2.createJsonPath)(path);
362
407
  let parsedValue = value;
363
408
  try {
364
409
  if (type === "number") {
365
410
  parsedValue = parseFloat(value) || 0;
366
411
  }
367
412
  } catch (err) {
368
- import_log3.log.catch(err, void 0, {
413
+ import_log2.log.catch(err, void 0, {
369
414
  F: __dxlog_file,
370
- L: 183,
415
+ L: 194,
371
416
  S: void 0,
372
417
  C: (f, a) => f(...a)
373
418
  });
374
419
  parsedValue = void 0;
375
420
  }
376
- const newValues = setByPath(values, property, parsedValue);
421
+ const newValues = {
422
+ ...(0, import_echo_schema3.setValue)(values, jsonPath, parsedValue)
423
+ };
377
424
  setValues(newValues);
378
425
  setChanged((prev) => ({
379
426
  ...prev,
380
- [property]: true
427
+ [jsonPath]: true
381
428
  }));
382
429
  onValuesChanged?.(newValues);
383
430
  const isValid = validate(newValues);
@@ -387,15 +434,12 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
387
434
  });
388
435
  }
389
436
  };
390
- const onBlur = (0, import_react7.useCallback)((event) => {
391
- const { name } = event.target;
437
+ const onTouched = (0, import_react10.useCallback)((path) => {
438
+ const jsonPath = (0, import_effect2.createJsonPath)(path);
392
439
  setTouched((touched2) => ({
393
440
  ...touched2,
394
- [name]: true
441
+ [jsonPath]: true
395
442
  }));
396
- if (event.relatedTarget?.getAttribute("type") === "submit") {
397
- setTouched(createKeySet(values, true));
398
- }
399
443
  validate(values);
400
444
  }, [
401
445
  validate,
@@ -411,15 +455,15 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
411
455
  handleSave,
412
456
  // Field utils.
413
457
  getStatus,
414
- getValue,
458
+ getValue: getFormValue,
415
459
  onValueChange,
416
- onBlur
460
+ onTouched
417
461
  };
418
462
  };
419
463
  var createKeySet = (obj, value) => {
420
464
  (0, import_invariant.invariant)(obj, void 0, {
421
465
  F: __dxlog_file,
422
- L: 234,
466
+ L: 236,
423
467
  S: void 0,
424
468
  A: [
425
469
  "obj",
@@ -433,316 +477,313 @@ var createKeySet = (obj, value) => {
433
477
  };
434
478
  var flatMap = (errors) => {
435
479
  return errors.reduce((result, { path, message }) => {
436
- if (!(path in result)) {
437
- result[path] = message;
480
+ const jsonPath = (0, import_effect2.fromEffectValidationPath)(path);
481
+ if (!(jsonPath in result)) {
482
+ result[jsonPath] = message;
438
483
  }
439
484
  return result;
440
485
  }, {});
441
486
  };
442
- var getByPath = (obj, path) => {
443
- const [key, index] = path.split(".");
444
- return index === void 0 ? obj[key] : obj[key][parseInt(index)];
487
+ var FormContext = /* @__PURE__ */ (0, import_react9.createContext)(void 0);
488
+ var useFormContext = () => {
489
+ return (0, import_react9.useContext)(FormContext) ?? (0, import_debug.raise)(new Error("Missing FormContext"));
490
+ };
491
+ var useFormValues = (path = []) => {
492
+ const { values: formValues } = useFormContext();
493
+ const jsonPath = (0, import_effect.createJsonPath)(path);
494
+ return (0, import_echo_schema2.getValue)(formValues, jsonPath);
445
495
  };
446
- var setByPath = (obj, path, value) => {
447
- const [key, index] = path.split(".");
448
- const newValue = index === void 0 ? value : [
449
- ...obj[key]
450
- ].map((v, i) => i === parseInt(index) ? value : v);
496
+ var useInputProps = (path = []) => {
497
+ const { getStatus, getValue: getFormValue, onValueChange, onTouched } = useFormContext();
451
498
  return {
452
- ...obj,
453
- [key]: newValue
499
+ getStatus: () => getStatus(path),
500
+ getValue: () => getFormValue(path),
501
+ onValueChange: (type, value) => onValueChange(path, type, value),
502
+ onBlur: () => onTouched(path)
454
503
  };
455
504
  };
456
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/Form/Form.tsx";
505
+ var FormProvider = ({ children, ...formOptions }) => {
506
+ const formHandler = useForm(formOptions);
507
+ return /* @__PURE__ */ import_react9.default.createElement(FormContext.Provider, {
508
+ value: formHandler
509
+ }, children);
510
+ };
511
+ var FormActions = ({ onCancel, readonly }) => {
512
+ const { t } = (0, import_react_ui7.useTranslation)(translationKey);
513
+ const { canSave, handleSave } = useFormContext();
514
+ return /* @__PURE__ */ import_react8.default.createElement("div", {
515
+ role: "none",
516
+ className: "flex justify-center"
517
+ }, /* @__PURE__ */ import_react8.default.createElement("div", {
518
+ role: "none",
519
+ className: (0, import_react_ui_theme4.mx)(onCancel && !readonly && "grid grid-cols-2 gap-2")
520
+ }, onCancel && !readonly && /* @__PURE__ */ import_react8.default.createElement(import_react_ui7.IconButton, {
521
+ "data-testid": "cancel-button",
522
+ icon: "ph--x--regular",
523
+ label: t("button cancel"),
524
+ onClick: onCancel
525
+ }), handleSave && /* @__PURE__ */ import_react8.default.createElement(import_react_ui7.IconButton, {
526
+ type: "submit",
527
+ "data-testid": "save-button",
528
+ disabled: !canSave,
529
+ icon: "ph--check--regular",
530
+ label: t("button save"),
531
+ onClick: handleSave
532
+ })));
533
+ };
534
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/Form/ArrayField.tsx";
457
535
  var padding = "px-2";
458
- var Form = ({ classNames, schema, values: initialValues, path = [], readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, Custom }) => {
459
- const onValid = (0, import_react3.useMemo)(() => autoSave ? onSave : void 0, [
460
- autoSave,
461
- onSave
462
- ]);
463
- const { canSave, values, errors, handleSave, ...inputProps } = useForm({
464
- schema,
465
- initialValues,
466
- onValuesChanged,
467
- onValidate,
468
- onValid,
469
- onSave
536
+ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponent }) => {
537
+ const { t } = (0, import_react_ui8.useTranslation)(translationKey);
538
+ const { ast, name, type, title } = property;
539
+ const values = useFormValues(path ?? []);
540
+ (0, import_invariant2.invariant)(Array.isArray(values), void 0, {
541
+ F: __dxlog_file2,
542
+ L: 37,
543
+ S: void 0,
544
+ A: [
545
+ "Array.isArray(values)",
546
+ ""
547
+ ]
470
548
  });
471
- const properties = (0, import_react3.useMemo)(() => {
472
- const props = (0, import_schema2.getSchemaProperties)(schema.ast, values);
473
- const filtered = filter ? filter(props) : props;
474
- const findIndex = (props2, prop) => {
475
- const idx = props2.findIndex((p) => p === prop);
476
- return idx === -1 ? Infinity : idx;
477
- };
478
- return sort ? filtered.sort(({ name: a }, { name: b }) => findIndex(sort, a) - findIndex(sort, b)) : filtered;
549
+ const label = title ?? (0, import_effect5.pipe)(name, import_String2.capitalize);
550
+ const tupleType = (0, import_effect6.findNode)(ast, import_echo_schema5.AST.isTupleType);
551
+ const elementType = tupleType?.rest[0]?.type;
552
+ const getDefaultObjectValue = (typeNode) => {
553
+ const baseNode = (0, import_effect6.findNode)(typeNode, import_effect6.isDiscriminatedUnion);
554
+ const typeLiteral = baseNode ? (0, import_effect6.getDiscriminatedType)(baseNode, {}) : (0, import_effect6.findNode)(typeNode, import_echo_schema5.AST.isTypeLiteral);
555
+ if (!typeLiteral) {
556
+ return {};
557
+ }
558
+ return Object.fromEntries((0, import_schema4.getSchemaProperties)(typeLiteral, {}).map((prop) => [
559
+ prop.name,
560
+ prop.defaultValue
561
+ ]));
562
+ };
563
+ const newValue = (0, import_react12.useMemo)(() => {
564
+ if (type === "object" && elementType) {
565
+ return getDefaultObjectValue(elementType);
566
+ } else {
567
+ return import_effect6.SimpleType.getDefaultValue(type);
568
+ }
479
569
  }, [
480
- schema,
481
- filter,
570
+ type,
571
+ elementType
572
+ ]);
573
+ const handleAdd = (0, import_react12.useCallback)(() => {
574
+ inputProps.onValueChange(type, [
575
+ ...values,
576
+ newValue
577
+ ]);
578
+ }, [
579
+ type,
580
+ elementType,
581
+ inputProps,
582
+ newValue,
482
583
  values
483
584
  ]);
484
- (0, import_react3.useEffect)(() => {
485
- if (errors && Object.keys(errors).length) {
486
- import_log2.log.warn("validation", {
487
- errors
488
- }, {
489
- F: __dxlog_file2,
490
- L: 100,
491
- S: void 0,
492
- C: (f, a) => f(...a)
493
- });
494
- }
585
+ const handleRemove = (0, import_react12.useCallback)((index) => {
586
+ const newValues = values.filter((_, i) => i !== index);
587
+ inputProps.onValueChange(type, newValues);
495
588
  }, [
496
- errors
589
+ type,
590
+ inputProps,
591
+ values
497
592
  ]);
498
- return /* @__PURE__ */ import_react3.default.createElement("div", {
499
- role: "form",
500
- className: (0, import_react_ui_theme.mx)("flex flex-col w-full gap-2 py-2", classNames),
501
- "data-testid": testId
502
- }, properties.map((property) => {
503
- const { ast, name, type, format, title, description, examples, options, array } = property;
504
- const key = [
505
- ...path,
506
- name
507
- ];
508
- const label = title ?? (0, import_effect.pipe)(name, import_String.capitalize);
509
- const placeholder = examples?.length ? `Example: "${examples[0]}"` : description;
510
- let InputComponent = Custom?.[key.join(".")];
511
- if (!InputComponent) {
512
- if (options) {
513
- return /* @__PURE__ */ import_react3.default.createElement("div", {
514
- key: name,
515
- role: "none",
516
- className: padding
517
- }, /* @__PURE__ */ import_react3.default.createElement(SelectInput, {
518
- type,
519
- format,
520
- property: name,
521
- disabled: readonly,
522
- label,
523
- options: options.map((option) => ({
524
- value: option,
525
- label: String(option)
526
- })),
527
- placeholder,
528
- ...inputProps
529
- }));
530
- }
531
- InputComponent = getInputComponent(type, format);
532
- if (array) {
533
- return /* @__PURE__ */ import_react3.default.createElement(ArrayField, {
534
- key: name,
535
- name,
536
- type,
537
- array: true,
538
- label,
539
- ast,
540
- values,
541
- format,
542
- readonly,
543
- placeholder,
544
- inputProps,
545
- Custom
546
- });
547
- }
548
- }
549
- if (!InputComponent) {
550
- if (type === "object") {
551
- const baseNode = (0, import_effect2.findNode)(ast, import_effect2.isDiscriminatedUnion);
552
- const typeLiteral = baseNode ? (0, import_effect2.getDiscriminatedType)(baseNode, values[name]) : (0, import_effect2.findNode)(ast, import_echo_schema2.AST.isTypeLiteral);
553
- if (typeLiteral) {
554
- const schema2 = import_echo_schema2.S.make(typeLiteral);
555
- return /* @__PURE__ */ import_react3.default.createElement("div", {
556
- key: name,
557
- role: "none"
558
- }, /* @__PURE__ */ import_react3.default.createElement("div", {
559
- className: padding
560
- }, label), /* @__PURE__ */ import_react3.default.createElement(Form, {
561
- schema: schema2,
562
- path: key,
563
- values: values[name] ?? {},
564
- onValuesChanged: (childValues) => {
565
- inputProps.onValueChange(name, "object", childValues);
566
- },
567
- Custom
568
- }));
569
- }
570
- }
571
- (0, import_log2.log)("no renderer for property", {
572
- name,
573
- type
574
- }, {
575
- F: __dxlog_file2,
576
- L: 185,
577
- S: void 0,
578
- C: (f, a) => f(...a)
579
- });
580
- return null;
581
- }
582
- return /* @__PURE__ */ import_react3.default.createElement("div", {
583
- key: name,
584
- role: "none",
585
- className: padding
586
- }, /* @__PURE__ */ import_react3.default.createElement(InputComponent, {
587
- type,
588
- format,
589
- property: name,
590
- disabled: readonly,
591
- label,
592
- placeholder,
593
- ...inputProps
594
- }));
595
- }).filter(import_util.isNotFalsy), (onCancel || onSave) && !autoSave && /* @__PURE__ */ import_react3.default.createElement(FormActions, {
596
- onCancel,
597
- onSubmit: handleSave,
598
- canSubmit: canSave,
599
- readonly
600
- }));
601
- };
602
- var ArrayField = ({ name, type, label, ast, values, format, readonly, placeholder, inputProps, Custom }) => {
603
- const { t } = (0, import_react_ui3.useTranslation)(translationKey);
604
- const arrayValues = values[name] ?? [];
605
- const key = [
606
- name
607
- ];
608
- const tupleType = (0, import_effect2.findNode)(ast, import_echo_schema2.AST.isTupleType);
609
- const elementType = tupleType?.rest[0]?.type;
610
- if (type === "object" && elementType) {
611
- const baseNode = (0, import_effect2.findNode)(elementType, import_effect2.isDiscriminatedUnion);
612
- const typeLiteral = baseNode ? (0, import_effect2.getDiscriminatedType)(baseNode, values[name]) : (0, import_effect2.findNode)(elementType, import_echo_schema2.AST.isTypeLiteral);
613
- if (typeLiteral) {
614
- const schema = import_echo_schema2.S.make(typeLiteral);
615
- return /* @__PURE__ */ import_react3.default.createElement("div", {
616
- key: name,
617
- role: "none",
618
- className: (0, import_react_ui_theme.mx)(padding)
619
- }, /* @__PURE__ */ import_react3.default.createElement(InputHeader, null, label), /* @__PURE__ */ import_react3.default.createElement("div", {
620
- role: "none",
621
- className: "flex flex-col gap-1"
622
- }, arrayValues.map((value, index) => {
623
- return /* @__PURE__ */ import_react3.default.createElement("div", {
624
- key: index,
625
- role: "none",
626
- className: "flex items-center gap-1"
627
- }, /* @__PURE__ */ import_react3.default.createElement("div", {
628
- role: "none",
629
- className: "flex-1"
630
- }, /* @__PURE__ */ import_react3.default.createElement(Form, {
631
- schema,
632
- path: [
633
- ...key,
634
- index.toString()
635
- ],
636
- values: value,
637
- onValuesChanged: (childValues) => {
638
- const newValues = [
639
- ...arrayValues
640
- ];
641
- newValues[index] = childValues;
642
- inputProps.onValueChange(name, "object", newValues);
643
- },
644
- Custom
645
- })), /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.IconButton, {
646
- icon: "ph--trash--regular",
647
- iconOnly: true,
648
- label: t("button remove"),
649
- onClick: () => {
650
- const newValues = arrayValues.filter((_, i) => i !== index);
651
- inputProps.onValueChange(name, type, newValues);
652
- }
653
- }));
654
- })), /* @__PURE__ */ import_react3.default.createElement("div", {
655
- role: "none",
656
- className: "flex justify-between items-center plb-1"
657
- }, /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.IconButton, {
658
- icon: "ph--plus--regular",
659
- iconOnly: true,
660
- label: t("button add"),
661
- onClick: () => {
662
- const newValues = [
663
- ...arrayValues,
664
- {}
665
- ];
666
- inputProps.onValueChange(name, type, newValues);
667
- }
668
- })));
669
- }
670
- return /* @__PURE__ */ import_react3.default.createElement("div", {
671
- key: name,
672
- role: "none"
673
- }, "Nested form not supported in arrays, yet.");
674
- }
675
- const InputComponent = getInputComponent(type, format);
676
- if (!InputComponent) {
593
+ if (!elementType) {
677
594
  return null;
678
595
  }
679
- return /* @__PURE__ */ import_react3.default.createElement("div", {
596
+ return /* @__PURE__ */ import_react12.default.createElement("div", {
680
597
  role: "none",
681
- key: "meta-input",
682
- className: (0, import_react_ui_theme.mx)(padding)
683
- }, /* @__PURE__ */ import_react3.default.createElement(InputHeader, null, label), /* @__PURE__ */ import_react3.default.createElement("div", {
598
+ className: (0, import_react_ui_theme6.mx)(padding)
599
+ }, /* @__PURE__ */ import_react12.default.createElement(InputHeader, null, label), /* @__PURE__ */ import_react12.default.createElement("div", {
684
600
  role: "none",
685
601
  className: "flex flex-col gap-1"
686
- }, arrayValues.map((_, index) => /* @__PURE__ */ import_react3.default.createElement("div", {
602
+ }, values.map((_value, index) => /* @__PURE__ */ import_react12.default.createElement("div", {
687
603
  key: index,
688
604
  role: "none",
689
- className: "flex items-start gap-1"
690
- }, /* @__PURE__ */ import_react3.default.createElement("div", {
605
+ className: "flex items-center gap-1"
606
+ }, /* @__PURE__ */ import_react12.default.createElement("div", {
691
607
  role: "none",
692
608
  className: "flex-1"
693
- }, /* @__PURE__ */ import_react3.default.createElement(InputComponent, {
694
- type,
695
- format,
696
- label,
697
- inputOnly: true,
698
- property: `${name}.${index}`,
699
- disabled: readonly,
700
- placeholder,
701
- ...inputProps
702
- })), /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.IconButton, {
609
+ }, /* @__PURE__ */ import_react12.default.createElement(FormField, {
610
+ property: {
611
+ ...property,
612
+ array: false,
613
+ ast: elementType
614
+ },
615
+ path: [
616
+ ...path ?? [],
617
+ index
618
+ ],
619
+ readonly,
620
+ inline: true,
621
+ Custom,
622
+ lookupComponent
623
+ })), /* @__PURE__ */ import_react12.default.createElement(import_react_ui8.IconButton, {
703
624
  icon: "ph--trash--regular",
704
625
  iconOnly: true,
705
626
  label: t("button remove"),
706
- onClick: () => {
707
- const newValues = arrayValues.filter((_2, i) => i !== index);
708
- inputProps.onValueChange(name, type, newValues);
709
- }
710
- })))), /* @__PURE__ */ import_react3.default.createElement("div", {
627
+ onClick: () => handleRemove(index)
628
+ })))), /* @__PURE__ */ import_react12.default.createElement("div", {
711
629
  role: "none",
712
630
  className: "flex justify-between items-center plb-1"
713
- }, /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.IconButton, {
631
+ }, /* @__PURE__ */ import_react12.default.createElement(import_react_ui8.IconButton, {
714
632
  icon: "ph--plus--regular",
715
633
  iconOnly: true,
716
634
  label: t("button add"),
717
- onClick: () => {
718
- const newValues = [
719
- ...arrayValues,
720
- import_effect2.SimpleType.getDefaultValue(type)
721
- ];
722
- inputProps.onValueChange(name, type, newValues);
723
- }
635
+ onClick: handleAdd
724
636
  })));
725
637
  };
726
- var FormActions = ({ onCancel, onSubmit, canSubmit, readonly }) => {
727
- const { t } = (0, import_react_ui3.useTranslation)(translationKey);
728
- return /* @__PURE__ */ import_react3.default.createElement("div", {
729
- role: "none",
730
- className: "flex justify-center"
731
- }, /* @__PURE__ */ import_react3.default.createElement("div", {
638
+ var getInputComponent = (type, format) => {
639
+ switch (format) {
640
+ case import_echo_schema6.FormatEnum.LatLng:
641
+ return GeoPointInput;
642
+ }
643
+ switch (type) {
644
+ case "string":
645
+ return TextInput;
646
+ case "number":
647
+ return NumberInput;
648
+ case "boolean":
649
+ return BooleanInput;
650
+ }
651
+ };
652
+ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom }) => {
653
+ const inputProps = useInputProps(path);
654
+ const { ast, name, type, format, title, description, options, examples, array } = property;
655
+ const label = (0, import_react11.useMemo)(() => title ?? (0, import_effect3.pipe)(name, import_String.capitalize), [
656
+ title,
657
+ name
658
+ ]);
659
+ const placeholder = (0, import_react11.useMemo)(() => examples?.length ? `Example: "${examples[0]}"` : description, [
660
+ examples,
661
+ description
662
+ ]);
663
+ if (array) {
664
+ return /* @__PURE__ */ import_react11.default.createElement(ArrayField, {
665
+ property,
666
+ path,
667
+ inputProps,
668
+ readonly,
669
+ Custom
670
+ });
671
+ }
672
+ const FoundComponent = lookupComponent?.({
673
+ prop: name,
674
+ schema: import_echo_schema4.S.make(ast),
675
+ inputProps: {
676
+ type,
677
+ format,
678
+ label,
679
+ disabled: readonly,
680
+ placeholder,
681
+ ...inputProps
682
+ }
683
+ });
684
+ if (FoundComponent) {
685
+ return /* @__PURE__ */ import_react11.default.createElement("div", null, FoundComponent);
686
+ }
687
+ const jsonPath = (0, import_effect4.createJsonPath)(path ?? []);
688
+ const InputComponent = Custom?.[jsonPath] || getInputComponent(type, format);
689
+ if (InputComponent) {
690
+ return /* @__PURE__ */ import_react11.default.createElement("div", null, /* @__PURE__ */ import_react11.default.createElement(InputComponent, {
691
+ type,
692
+ format,
693
+ label,
694
+ inputOnly: inline,
695
+ placeholder,
696
+ disabled: readonly,
697
+ ...inputProps
698
+ }));
699
+ }
700
+ if (options) {
701
+ return /* @__PURE__ */ import_react11.default.createElement("div", {
702
+ role: "none"
703
+ }, /* @__PURE__ */ import_react11.default.createElement(SelectInput, {
704
+ type,
705
+ format,
706
+ disabled: readonly,
707
+ inputOnly: inline,
708
+ label,
709
+ options: options.map((option) => ({
710
+ value: option,
711
+ label: String(option)
712
+ })),
713
+ placeholder,
714
+ ...inputProps
715
+ }));
716
+ }
717
+ if (type === "object") {
718
+ const baseNode = (0, import_effect4.findNode)(ast, import_effect4.isDiscriminatedUnion);
719
+ const typeLiteral = baseNode ? (0, import_effect4.getDiscriminatedType)(baseNode, inputProps.getValue()) : (0, import_effect4.findNode)(ast, import_echo_schema4.AST.isTypeLiteral);
720
+ if (typeLiteral) {
721
+ return /* @__PURE__ */ import_react11.default.createElement("div", null, !inline && /* @__PURE__ */ import_react11.default.createElement("div", null, label), /* @__PURE__ */ import_react11.default.createElement(FormFields, {
722
+ schema: import_echo_schema4.S.make(typeLiteral),
723
+ path,
724
+ readonly,
725
+ Custom
726
+ }));
727
+ }
728
+ }
729
+ return null;
730
+ };
731
+ var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custom }) => {
732
+ const values = useFormValues(path);
733
+ const properties = (0, import_react11.useMemo)(() => {
734
+ const props = (0, import_schema3.getSchemaProperties)(schema.ast, values);
735
+ const filtered = filter ? filter(props) : props;
736
+ return sort ? filtered.sort((a, b) => sort.indexOf(a.name) - sort.indexOf(b.name)) : filtered;
737
+ }, [
738
+ schema,
739
+ values,
740
+ filter,
741
+ sort
742
+ ]);
743
+ return /* @__PURE__ */ import_react11.default.createElement("div", {
744
+ role: "form",
745
+ className: (0, import_react_ui_theme5.mx)("flex flex-col w-full gap-2 py-2")
746
+ }, properties.map((property) => {
747
+ return /* @__PURE__ */ import_react11.default.createElement(FormField, {
748
+ key: property.name,
749
+ property,
750
+ path: [
751
+ ...path ?? [],
752
+ property.name
753
+ ],
754
+ readonly,
755
+ lookupComponent,
756
+ Custom
757
+ });
758
+ }).filter(import_util3.isNotFalsy));
759
+ };
760
+ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, lookupComponent, Custom }) => {
761
+ const onValid = (0, import_react7.useMemo)(() => autoSave ? onSave : void 0, [
762
+ autoSave,
763
+ onSave
764
+ ]);
765
+ return /* @__PURE__ */ import_react7.default.createElement(FormProvider, {
766
+ schema,
767
+ initialValues,
768
+ onValuesChanged,
769
+ onValidate,
770
+ onValid,
771
+ onSave
772
+ }, /* @__PURE__ */ import_react7.default.createElement("div", {
732
773
  role: "none",
733
- className: (0, import_react_ui_theme.mx)(onCancel && !readonly && "grid grid-cols-2 gap-2")
734
- }, onCancel && !readonly && /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.IconButton, {
735
- "data-testid": "cancel-button",
736
- icon: "ph--x--regular",
737
- label: t("button cancel"),
738
- onClick: onCancel
739
- }), onSubmit && /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.IconButton, {
740
- type: "submit",
741
- "data-testid": "save-button",
742
- disabled: !canSubmit,
743
- icon: "ph--check--regular",
744
- label: t("button save"),
745
- onClick: onSubmit
774
+ className: (0, import_react_ui_theme3.mx)("p-2", classNames),
775
+ "data-testid": testId
776
+ }, /* @__PURE__ */ import_react7.default.createElement(FormFields, {
777
+ schema,
778
+ path,
779
+ readonly,
780
+ filter,
781
+ sort,
782
+ lookupComponent,
783
+ Custom
784
+ }), (onCancel || onSave) && !autoSave && /* @__PURE__ */ import_react7.default.createElement(FormActions, {
785
+ onCancel,
786
+ readonly
746
787
  })));
747
788
  };
748
789
  var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
@@ -758,9 +799,11 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
758
799
  if (!registry) {
759
800
  return;
760
801
  }
761
- const subscription = registry.subscribe(setSchemas);
802
+ const subscription = registry.query().subscribe((query) => setSchemas(query.results), {
803
+ fire: true
804
+ });
762
805
  const t2 = setTimeout(async () => {
763
- const schemas2 = await registry.query();
806
+ const schemas2 = await registry.query().run();
764
807
  setSchemas(schemas2);
765
808
  });
766
809
  return () => {
@@ -770,9 +813,9 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
770
813
  }, [
771
814
  registry
772
815
  ]);
773
- const [schema, setSchema] = (0, import_react2.useState)();
816
+ const [referenceSchema, setReferenceSchema] = (0, import_react2.useState)();
774
817
  (0, import_react2.useEffect)(() => {
775
- setSchema(schemas.find((schema2) => schema2.typename === props?.referenceSchema));
818
+ setReferenceSchema(schemas.find((schema) => schema.typename === props?.referenceSchema));
776
819
  }, [
777
820
  schemas,
778
821
  props?.referenceSchema
@@ -781,14 +824,24 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
781
824
  fieldSchema: (0, import_schema.getFormatSchema)(props?.format)
782
825
  });
783
826
  const handleValuesChanged = (0, import_react2.useCallback)((_props) => {
784
- if (_props.format !== props.format) {
785
- setFieldSchema({
786
- fieldSchema: (0, import_schema.getFormatSchema)(_props.format)
787
- });
788
- }
789
- if (_props.referenceSchema !== props.referenceSchema) {
790
- setSchema(schemas.find((schema2) => schema2.typename === _props.referenceSchema));
791
- }
827
+ setFieldSchema((prev) => {
828
+ const fieldSchema2 = (0, import_schema.getFormatSchema)(_props.format);
829
+ if (prev.fieldSchema === fieldSchema2) {
830
+ return prev;
831
+ }
832
+ return {
833
+ fieldSchema: fieldSchema2
834
+ };
835
+ });
836
+ setReferenceSchema((prev) => {
837
+ if (_props.referenceSchema !== prev?.typename) {
838
+ const newSchema = schemas.find((schema) => schema.typename === _props.referenceSchema);
839
+ if (newSchema) {
840
+ return newSchema;
841
+ }
842
+ }
843
+ return prev;
844
+ });
792
845
  setProps((props2) => {
793
846
  const type = import_echo_schema.formatToType[_props.format];
794
847
  if (props2.type !== type) {
@@ -802,7 +855,8 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
802
855
  });
803
856
  }, [
804
857
  schemas,
805
- props
858
+ props.format,
859
+ props.referenceSchema
806
860
  ]);
807
861
  const handleValidate = (0, import_react2.useCallback)(({ property }) => {
808
862
  if (property && view.fields.find((f) => f.path === property && f.path !== field.path)) {
@@ -834,12 +888,38 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
834
888
  }, [
835
889
  onSave
836
890
  ]);
891
+ const Custom = (0, import_react2.useMemo)(() => ({
892
+ ["format"]: (props2) => /* @__PURE__ */ import_react2.default.createElement(SelectInput, {
893
+ ...props2,
894
+ options: import_echo_schema.FormatEnums.filter((value) => value !== import_echo_schema.FormatEnum.None).map((value) => ({
895
+ value,
896
+ label: t(`format ${value}`)
897
+ }))
898
+ }),
899
+ ["referenceSchema"]: (props2) => /* @__PURE__ */ import_react2.default.createElement(SelectInput, {
900
+ ...props2,
901
+ options: schemas.map((schema) => ({
902
+ value: schema.typename
903
+ }))
904
+ }),
905
+ ["referencePath"]: (props2) => /* @__PURE__ */ import_react2.default.createElement(SelectInput, {
906
+ ...props2,
907
+ options: referenceSchema ? (0, import_schema.getSchemaProperties)(referenceSchema.ast).sort(import_schema.sortProperties).map((p) => ({
908
+ value: p.name
909
+ })) : []
910
+ })
911
+ }), [
912
+ t,
913
+ schemas,
914
+ referenceSchema
915
+ ]);
916
+ const propIsNotType = (0, import_react2.useCallback)((props2) => props2.filter((p) => p.name !== "type"), []);
837
917
  if (!fieldSchema) {
838
918
  import_log.log.warn("invalid format", {
839
919
  props
840
920
  }, {
841
921
  F: __dxlog_file3,
842
- L: 118,
922
+ L: 173,
843
923
  S: void 0,
844
924
  C: (f, a) => f(...a)
845
925
  });
@@ -850,7 +930,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
850
930
  autoFocus: true,
851
931
  values: props,
852
932
  schema: fieldSchema,
853
- filter: (props2) => props2.filter((p) => p.name !== "type"),
933
+ filter: propIsNotType,
854
934
  sort: [
855
935
  "property",
856
936
  "format"
@@ -859,46 +939,26 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
859
939
  onValidate: handleValidate,
860
940
  onSave: handleSave,
861
941
  onCancel: handleCancel,
862
- Custom: {
863
- ["format"]: (props2) => /* @__PURE__ */ import_react2.default.createElement(SelectInput, {
864
- ...props2,
865
- options: import_echo_schema.FormatEnums.filter((value) => value !== import_echo_schema.FormatEnum.None).map((value) => ({
866
- value,
867
- label: t(`format ${value}`)
868
- }))
869
- }),
870
- ["referenceSchema"]: (props2) => /* @__PURE__ */ import_react2.default.createElement(SelectInput, {
871
- ...props2,
872
- options: schemas.map((schema2) => ({
873
- value: schema2.typename
874
- }))
875
- }),
876
- ["referencePath"]: (props2) => /* @__PURE__ */ import_react2.default.createElement(SelectInput, {
877
- ...props2,
878
- options: schema ? (0, import_schema.getSchemaProperties)(schema.schema.ast).sort(import_schema.sortProperties).map((p) => ({
879
- value: p.name
880
- })) : []
881
- })
882
- }
942
+ Custom
883
943
  });
884
944
  };
885
945
  var grid = "grid grid-cols-[32px_1fr_32px] min-bs-[2.5rem]";
886
- var ViewMetaSchema = import_echo_schema4.S.Struct({
887
- name: import_echo_schema4.S.String.annotations({
888
- [import_echo_schema4.AST.TitleAnnotationId]: "View"
946
+ var ViewMetaSchema = import_echo_schema7.S.Struct({
947
+ name: import_echo_schema7.S.String.annotations({
948
+ [import_echo_schema7.AST.TitleAnnotationId]: "View"
889
949
  }),
890
- typename: import_echo_schema4.Format.DXN.annotations({
891
- [import_echo_schema4.AST.TitleAnnotationId]: "Typename"
950
+ typename: import_echo_schema7.Format.DXN.annotations({
951
+ [import_echo_schema7.AST.TitleAnnotationId]: "Typename"
892
952
  })
893
- }).pipe(import_echo_schema4.S.mutable);
894
- var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading = false, onDelete }) => {
895
- const { t } = (0, import_react_ui7.useTranslation)(translationKey);
896
- const projection = (0, import_react8.useMemo)(() => new import_schema4.ViewProjection(schema, view), [
953
+ }).pipe(import_echo_schema7.S.mutable);
954
+ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading = false, onTypenameChanged, onDelete }) => {
955
+ const { t } = (0, import_react_ui9.useTranslation)(translationKey);
956
+ const projection = (0, import_react13.useMemo)(() => new import_schema5.ViewProjection(schema, view), [
897
957
  schema,
898
958
  view
899
959
  ]);
900
- const [field, setField] = (0, import_react8.useState)();
901
- const viewValues = (0, import_react8.useMemo)(() => {
960
+ const [field, setField] = (0, import_react13.useState)();
961
+ const viewValues = (0, import_react13.useMemo)(() => {
902
962
  return {
903
963
  name: view.name,
904
964
  // TODO(burdon): Need to warn user of possible consequences of editing.
@@ -908,82 +968,86 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
908
968
  }, [
909
969
  view
910
970
  ]);
911
- const handleViewUpdate = (0, import_react8.useCallback)(({ name, typename }) => {
971
+ const handleViewUpdate = (0, import_react13.useCallback)(({ name, typename }) => {
912
972
  requestAnimationFrame(() => {
913
- view.name = name;
914
- view.query.type = typename;
915
- schema.updateTypename(typename);
973
+ if (view.name !== name) {
974
+ view.name = name;
975
+ }
976
+ if (view.query.type !== typename) {
977
+ onTypenameChanged(typename);
978
+ }
916
979
  });
917
980
  }, [
918
981
  view,
919
- schema
982
+ schema,
983
+ onTypenameChanged
920
984
  ]);
921
- const handleSelect = (0, import_react8.useCallback)((field2) => {
985
+ const handleSelect = (0, import_react13.useCallback)((field2) => {
922
986
  setField((f) => f === field2 ? void 0 : field2);
923
987
  }, []);
924
- const handleAdd = (0, import_react8.useCallback)(() => {
988
+ const handleAdd = (0, import_react13.useCallback)(() => {
925
989
  const field2 = projection.createFieldProjection();
926
990
  setField(field2);
927
991
  }, [
928
992
  view
929
993
  ]);
930
- const handleMove = (0, import_react8.useCallback)((fromIndex, toIndex) => {
931
- (0, import_util2.arrayMove)(view.fields, fromIndex, toIndex);
994
+ const handleMove = (0, import_react13.useCallback)((fromIndex, toIndex) => {
995
+ (0, import_util4.arrayMove)(view.fields, fromIndex, toIndex);
932
996
  }, [
933
997
  view.fields
934
998
  ]);
935
- const handleClose = (0, import_react8.useCallback)(() => setField(void 0), []);
936
- return /* @__PURE__ */ import_react8.default.createElement("div", {
999
+ const handleClose = (0, import_react13.useCallback)(() => setField(void 0), []);
1000
+ return /* @__PURE__ */ import_react13.default.createElement("div", {
937
1001
  role: "none",
938
- className: (0, import_react_ui_theme3.mx)("flex flex-col w-full divide-y divide-separator", classNames)
939
- }, /* @__PURE__ */ import_react8.default.createElement(Form, {
1002
+ className: (0, import_react_ui_theme7.mx)("flex flex-col w-full divide-y divide-separator", classNames)
1003
+ }, /* @__PURE__ */ import_react13.default.createElement(Form, {
940
1004
  autoFocus: true,
941
1005
  autoSave: true,
942
1006
  schema: ViewMetaSchema,
943
1007
  values: viewValues,
944
1008
  onSave: handleViewUpdate
945
- }), /* @__PURE__ */ import_react8.default.createElement("div", null, /* @__PURE__ */ import_react8.default.createElement("div", {
1009
+ }), /* @__PURE__ */ import_react13.default.createElement("div", null, /* @__PURE__ */ import_react13.default.createElement("div", {
946
1010
  role: "none",
947
1011
  className: "p-2"
948
- }, /* @__PURE__ */ import_react8.default.createElement("label", {
949
- className: (0, import_react_ui_theme3.mx)(import_react_ui_theme3.inputTextLabel)
950
- }, t("fields label"))), /* @__PURE__ */ import_react8.default.createElement(import_react_ui_list.List.Root, {
1012
+ }, /* @__PURE__ */ import_react13.default.createElement("label", {
1013
+ className: (0, import_react_ui_theme7.mx)(import_react_ui_theme7.inputTextLabel)
1014
+ }, t("fields label"))), /* @__PURE__ */ import_react13.default.createElement(import_react_ui_list.List.Root, {
951
1015
  items: view.fields,
952
- isItem: import_echo_schema4.S.is(import_schema4.FieldSchema),
1016
+ isItem: import_echo_schema7.S.is(import_schema5.FieldSchema),
953
1017
  getId: (field2) => field2.id,
954
1018
  onMove: handleMove
955
- }, ({ items: fields }) => /* @__PURE__ */ import_react8.default.createElement(import_react8.default.Fragment, null, showHeading && /* @__PURE__ */ import_react8.default.createElement("div", {
1019
+ }, ({ items: fields }) => /* @__PURE__ */ import_react13.default.createElement(import_react13.default.Fragment, null, showHeading && /* @__PURE__ */ import_react13.default.createElement("div", {
956
1020
  role: "heading",
957
1021
  className: grid
958
- }, /* @__PURE__ */ import_react8.default.createElement("div", null), /* @__PURE__ */ import_react8.default.createElement("div", {
1022
+ }, /* @__PURE__ */ import_react13.default.createElement("div", null), /* @__PURE__ */ import_react13.default.createElement("div", {
959
1023
  className: "flex items-center text-sm"
960
- }, t("field path label"))), /* @__PURE__ */ import_react8.default.createElement("div", {
1024
+ }, t("field path label"))), /* @__PURE__ */ import_react13.default.createElement("div", {
961
1025
  role: "list",
962
1026
  className: "flex flex-col w-full"
963
- }, fields?.map((field2) => /* @__PURE__ */ import_react8.default.createElement(import_react_ui_list.List.Item, {
1027
+ }, fields?.map((field2) => /* @__PURE__ */ import_react13.default.createElement(import_react_ui_list.List.Item, {
964
1028
  key: field2.id,
965
1029
  item: field2,
966
- classNames: (0, import_react_ui_theme3.mx)(grid, import_react_ui_theme3.ghostHover, "cursor-pointer")
967
- }, /* @__PURE__ */ import_react8.default.createElement(import_react_ui_list.List.ItemDragHandle, null), /* @__PURE__ */ import_react8.default.createElement(import_react_ui_list.List.ItemTitle, {
1030
+ classNames: (0, import_react_ui_theme7.mx)(grid, import_react_ui_theme7.ghostHover, "cursor-pointer")
1031
+ }, /* @__PURE__ */ import_react13.default.createElement(import_react_ui_list.List.ItemDragHandle, null), /* @__PURE__ */ import_react13.default.createElement(import_react_ui_list.List.ItemTitle, {
968
1032
  onClick: () => handleSelect(field2)
969
- }, field2.path), /* @__PURE__ */ import_react8.default.createElement(import_react_ui_list.List.ItemDeleteButton, {
1033
+ }, field2.path), /* @__PURE__ */ import_react13.default.createElement(import_react_ui_list.List.ItemDeleteButton, {
970
1034
  disabled: view.fields.length <= 1,
971
1035
  onClick: () => onDelete(field2.id)
972
- }))))))), field && /* @__PURE__ */ import_react8.default.createElement(FieldEditor, {
1036
+ }))))))), field && /* @__PURE__ */ import_react13.default.createElement(FieldEditor, {
973
1037
  key: field.id,
974
1038
  view,
975
1039
  projection,
976
1040
  field,
977
1041
  registry,
978
1042
  onSave: handleClose
979
- }), !readonly && !field && /* @__PURE__ */ import_react8.default.createElement("div", {
1043
+ }), !readonly && !field && /* @__PURE__ */ import_react13.default.createElement("div", {
980
1044
  className: "flex p-2 justify-center"
981
- }, /* @__PURE__ */ import_react8.default.createElement(import_react_ui7.IconButton, {
1045
+ }, /* @__PURE__ */ import_react13.default.createElement(import_react_ui9.IconButton, {
982
1046
  icon: "ph--plus--regular",
983
1047
  label: t("button add property"),
984
1048
  onClick: handleAdd,
985
1049
  // TODO(burdon): Show field limit in ux (not tooltip).
986
- disabled: view.fields.length >= import_schema4.VIEW_FIELD_LIMIT
1050
+ disabled: view.fields.length >= import_schema5.VIEW_FIELD_LIMIT
987
1051
  })));
988
1052
  };
989
1053
  var parseValue = ({ type, format, value }) => {
@@ -992,7 +1056,7 @@ var parseValue = ({ type, format, value }) => {
992
1056
  }
993
1057
  const parseScalar = (type2) => {
994
1058
  switch (type2) {
995
- case import_echo_schema5.TypeEnum.Boolean: {
1059
+ case import_echo_schema8.TypeEnum.Boolean: {
996
1060
  if (typeof value === "string") {
997
1061
  const lowercaseValue = value.toLowerCase();
998
1062
  if (lowercaseValue === "0" || lowercaseValue === "false") {
@@ -1003,13 +1067,13 @@ var parseValue = ({ type, format, value }) => {
1003
1067
  }
1004
1068
  return Boolean(value);
1005
1069
  }
1006
- case import_echo_schema5.TypeEnum.Number: {
1070
+ case import_echo_schema8.TypeEnum.Number: {
1007
1071
  const cleaned = typeof value === "string" ? value.replace(/[^0-9.-]+/g, "") : value;
1008
1072
  const num = Number(cleaned);
1009
1073
  return Number.isNaN(num) ? null : num;
1010
1074
  }
1011
- case import_echo_schema5.TypeEnum.String:
1012
- case import_echo_schema5.TypeEnum.Ref:
1075
+ case import_echo_schema8.TypeEnum.String:
1076
+ case import_echo_schema8.TypeEnum.Ref:
1013
1077
  return String(value);
1014
1078
  default: {
1015
1079
  return value;
@@ -1020,22 +1084,22 @@ var parseValue = ({ type, format, value }) => {
1020
1084
  return parseScalar(type);
1021
1085
  }
1022
1086
  switch (format) {
1023
- case import_echo_schema5.FormatEnum.Boolean:
1024
- return parseScalar(import_echo_schema5.TypeEnum.Boolean);
1025
- case import_echo_schema5.FormatEnum.Number:
1026
- case import_echo_schema5.FormatEnum.Percent:
1027
- case import_echo_schema5.FormatEnum.Currency:
1028
- return parseScalar(import_echo_schema5.TypeEnum.Number);
1029
- case import_echo_schema5.FormatEnum.String:
1030
- case import_echo_schema5.FormatEnum.Markdown: {
1031
- return parseScalar(import_echo_schema5.TypeEnum.String);
1087
+ case import_echo_schema8.FormatEnum.Boolean:
1088
+ return parseScalar(import_echo_schema8.TypeEnum.Boolean);
1089
+ case import_echo_schema8.FormatEnum.Number:
1090
+ case import_echo_schema8.FormatEnum.Percent:
1091
+ case import_echo_schema8.FormatEnum.Currency:
1092
+ return parseScalar(import_echo_schema8.TypeEnum.Number);
1093
+ case import_echo_schema8.FormatEnum.String:
1094
+ case import_echo_schema8.FormatEnum.Markdown: {
1095
+ return parseScalar(import_echo_schema8.TypeEnum.String);
1032
1096
  }
1033
- case import_echo_schema5.FormatEnum.Ref:
1034
- throw new Error(`unexpected format: ${import_echo_schema5.FormatEnum.Ref}`);
1035
- case import_echo_schema5.FormatEnum.DateTime:
1036
- case import_echo_schema5.FormatEnum.Date:
1037
- case import_echo_schema5.FormatEnum.Time:
1038
- case import_echo_schema5.FormatEnum.Timestamp: {
1097
+ case import_echo_schema8.FormatEnum.Ref:
1098
+ throw new Error(`unexpected format: ${import_echo_schema8.FormatEnum.Ref}`);
1099
+ case import_echo_schema8.FormatEnum.DateTime:
1100
+ case import_echo_schema8.FormatEnum.Date:
1101
+ case import_echo_schema8.FormatEnum.Time:
1102
+ case import_echo_schema8.FormatEnum.Timestamp: {
1039
1103
  const date = new Date(value);
1040
1104
  return isNaN(date.getTime()) ? null : date;
1041
1105
  }
@@ -1047,19 +1111,19 @@ var parseValue = ({ type, format, value }) => {
1047
1111
  var cellClassesForFieldType = ({ type, format }) => {
1048
1112
  if (!format) {
1049
1113
  switch (type) {
1050
- case import_echo_schema5.TypeEnum.Number:
1114
+ case import_echo_schema8.TypeEnum.Number:
1051
1115
  return [
1052
1116
  "text-right",
1053
1117
  "font-mono"
1054
1118
  ];
1055
- case import_echo_schema5.TypeEnum.Boolean:
1119
+ case import_echo_schema8.TypeEnum.Boolean:
1056
1120
  return [
1057
1121
  "text-right",
1058
1122
  "font-mono"
1059
1123
  ];
1060
- case import_echo_schema5.TypeEnum.String:
1124
+ case import_echo_schema8.TypeEnum.String:
1061
1125
  return void 0;
1062
- case import_echo_schema5.TypeEnum.Ref:
1126
+ case import_echo_schema8.TypeEnum.Ref:
1063
1127
  return void 0;
1064
1128
  default: {
1065
1129
  return void 0;
@@ -1067,20 +1131,20 @@ var cellClassesForFieldType = ({ type, format }) => {
1067
1131
  }
1068
1132
  }
1069
1133
  switch (format) {
1070
- case import_echo_schema5.FormatEnum.Markdown:
1134
+ case import_echo_schema8.FormatEnum.Markdown:
1071
1135
  return void 0;
1072
- case import_echo_schema5.FormatEnum.Timestamp:
1073
- case import_echo_schema5.FormatEnum.DateTime:
1074
- case import_echo_schema5.FormatEnum.Date:
1075
- case import_echo_schema5.FormatEnum.Time:
1136
+ case import_echo_schema8.FormatEnum.Timestamp:
1137
+ case import_echo_schema8.FormatEnum.DateTime:
1138
+ case import_echo_schema8.FormatEnum.Date:
1139
+ case import_echo_schema8.FormatEnum.Time:
1076
1140
  return [
1077
1141
  "font-mono"
1078
1142
  ];
1079
- case import_echo_schema5.FormatEnum.Currency:
1143
+ case import_echo_schema8.FormatEnum.Currency:
1080
1144
  return [
1081
1145
  "text-right"
1082
1146
  ];
1083
- case import_echo_schema5.FormatEnum.JSON:
1147
+ case import_echo_schema8.FormatEnum.JSON:
1084
1148
  return [
1085
1149
  "font-mono"
1086
1150
  ];
@@ -1098,12 +1162,12 @@ var pathNotUniqueError = (path) => ({
1098
1162
  var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
1099
1163
  const formatScalar = (type2) => {
1100
1164
  switch (type2) {
1101
- case import_echo_schema6.TypeEnum.Boolean:
1165
+ case import_echo_schema9.TypeEnum.Boolean:
1102
1166
  return value.toLocaleString().toUpperCase();
1103
- case import_echo_schema6.TypeEnum.Number:
1167
+ case import_echo_schema9.TypeEnum.Number:
1104
1168
  return value.toLocaleString(locale);
1105
- case import_echo_schema6.TypeEnum.String:
1106
- case import_echo_schema6.TypeEnum.Ref:
1169
+ case import_echo_schema9.TypeEnum.String:
1170
+ case import_echo_schema9.TypeEnum.Ref:
1107
1171
  return String(value);
1108
1172
  default: {
1109
1173
  return String(value);
@@ -1114,20 +1178,20 @@ var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
1114
1178
  return formatScalar(type);
1115
1179
  }
1116
1180
  switch (format) {
1117
- case import_echo_schema6.FormatEnum.Boolean: {
1118
- return formatScalar(import_echo_schema6.TypeEnum.Boolean);
1181
+ case import_echo_schema9.FormatEnum.Boolean: {
1182
+ return formatScalar(import_echo_schema9.TypeEnum.Boolean);
1119
1183
  }
1120
- case import_echo_schema6.FormatEnum.Number: {
1121
- return formatScalar(import_echo_schema6.TypeEnum.Number);
1184
+ case import_echo_schema9.FormatEnum.Number: {
1185
+ return formatScalar(import_echo_schema9.TypeEnum.Number);
1122
1186
  }
1123
- case import_echo_schema6.FormatEnum.String:
1124
- case import_echo_schema6.FormatEnum.Ref: {
1125
- return formatScalar(import_echo_schema6.TypeEnum.String);
1187
+ case import_echo_schema9.FormatEnum.String:
1188
+ case import_echo_schema9.FormatEnum.Ref: {
1189
+ return formatScalar(import_echo_schema9.TypeEnum.String);
1126
1190
  }
1127
- case import_echo_schema6.FormatEnum.Percent: {
1191
+ case import_echo_schema9.FormatEnum.Percent: {
1128
1192
  return `${value * 100}%`;
1129
1193
  }
1130
- case import_echo_schema6.FormatEnum.Currency: {
1194
+ case import_echo_schema9.FormatEnum.Currency: {
1131
1195
  return value.toLocaleString(locale, {
1132
1196
  style: "currency",
1133
1197
  currency: "USD",
@@ -1135,13 +1199,13 @@ var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
1135
1199
  maximumFractionDigits: 2
1136
1200
  });
1137
1201
  }
1138
- case import_echo_schema6.FormatEnum.DateTime:
1139
- case import_echo_schema6.FormatEnum.Date:
1140
- case import_echo_schema6.FormatEnum.Time: {
1202
+ case import_echo_schema9.FormatEnum.DateTime:
1203
+ case import_echo_schema9.FormatEnum.Date:
1204
+ case import_echo_schema9.FormatEnum.Time: {
1141
1205
  const date = new Date(value);
1142
- if (format === import_echo_schema6.FormatEnum.DateTime) {
1206
+ if (format === import_echo_schema9.FormatEnum.DateTime) {
1143
1207
  return date.toLocaleString(locale);
1144
- } else if (format === import_echo_schema6.FormatEnum.Date) {
1208
+ } else if (format === import_echo_schema9.FormatEnum.Date) {
1145
1209
  return date.toLocaleDateString(locale);
1146
1210
  } else {
1147
1211
  return date.toLocaleTimeString(locale);
@@ -1158,10 +1222,10 @@ var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
1158
1222
  var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1159
1223
  const formatScalar = (type2) => {
1160
1224
  switch (type2) {
1161
- case import_echo_schema6.TypeEnum.Boolean:
1162
- case import_echo_schema6.TypeEnum.Number:
1163
- case import_echo_schema6.TypeEnum.String:
1164
- case import_echo_schema6.TypeEnum.Ref:
1225
+ case import_echo_schema9.TypeEnum.Boolean:
1226
+ case import_echo_schema9.TypeEnum.Number:
1227
+ case import_echo_schema9.TypeEnum.String:
1228
+ case import_echo_schema9.TypeEnum.Ref:
1165
1229
  return String(value);
1166
1230
  default:
1167
1231
  return String(value);
@@ -1171,27 +1235,27 @@ var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1171
1235
  return formatScalar(type);
1172
1236
  }
1173
1237
  switch (format) {
1174
- case import_echo_schema6.FormatEnum.Boolean:
1175
- case import_echo_schema6.FormatEnum.Number:
1176
- case import_echo_schema6.FormatEnum.String:
1177
- case import_echo_schema6.FormatEnum.Ref: {
1238
+ case import_echo_schema9.FormatEnum.Boolean:
1239
+ case import_echo_schema9.FormatEnum.Number:
1240
+ case import_echo_schema9.FormatEnum.String:
1241
+ case import_echo_schema9.FormatEnum.Ref: {
1178
1242
  return formatScalar(type);
1179
1243
  }
1180
- case import_echo_schema6.FormatEnum.Percent: {
1244
+ case import_echo_schema9.FormatEnum.Percent: {
1181
1245
  return String(value * 100);
1182
1246
  }
1183
- case import_echo_schema6.FormatEnum.Currency: {
1247
+ case import_echo_schema9.FormatEnum.Currency: {
1184
1248
  return String(value);
1185
1249
  }
1186
- case import_echo_schema6.FormatEnum.DateTime: {
1250
+ case import_echo_schema9.FormatEnum.DateTime: {
1187
1251
  const date = new Date(value);
1188
1252
  return date.toISOString();
1189
1253
  }
1190
- case import_echo_schema6.FormatEnum.Date: {
1254
+ case import_echo_schema9.FormatEnum.Date: {
1191
1255
  const date = new Date(value);
1192
1256
  return date.toISOString().split("T")[0];
1193
1257
  }
1194
- case import_echo_schema6.FormatEnum.Time: {
1258
+ case import_echo_schema9.FormatEnum.Time: {
1195
1259
  const date = new Date(value);
1196
1260
  return date.toISOString().split("T")[1].split(".")[0];
1197
1261
  }
@@ -1206,12 +1270,12 @@ var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1206
1270
  DeprecatedFormInput,
1207
1271
  FieldEditor,
1208
1272
  Form,
1209
- FormActions,
1210
- GeiPointInput,
1273
+ GeoPointInput,
1211
1274
  InputHeader,
1212
1275
  NumberInput,
1213
1276
  SelectInput,
1214
1277
  TextInput,
1278
+ TupleInput,
1215
1279
  ViewEditor,
1216
1280
  cellClassesForFieldType,
1217
1281
  cellClassesForRowSelection,