@dxos/react-ui-form 0.7.5-feature-compute.4d9d99a → 0.7.5-labs.a279d8c

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 (47) hide show
  1. package/dist/lib/browser/index.mjs +416 -409
  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 +461 -469
  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 +416 -409
  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/Form/ArrayField.d.ts +16 -0
  11. package/dist/types/src/components/Form/ArrayField.d.ts.map +1 -0
  12. package/dist/types/src/components/Form/Defaults.d.ts +5 -6
  13. package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
  14. package/dist/types/src/components/Form/Form.d.ts +10 -20
  15. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  16. package/dist/types/src/components/Form/Form.stories.d.ts +2 -1
  17. package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
  18. package/dist/types/src/components/Form/FormActions.d.ts +7 -0
  19. package/dist/types/src/components/Form/FormActions.d.ts.map +1 -0
  20. package/dist/types/src/components/Form/FormContent.d.ts +26 -0
  21. package/dist/types/src/components/Form/FormContent.d.ts.map +1 -0
  22. package/dist/types/src/components/Form/FormContext.d.ts +20 -0
  23. package/dist/types/src/components/Form/FormContext.d.ts.map +1 -0
  24. package/dist/types/src/components/Form/Input.d.ts +5 -6
  25. package/dist/types/src/components/Form/Input.d.ts.map +1 -1
  26. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts +1 -2
  27. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts.map +1 -1
  28. package/dist/types/src/components/Form/custom/TupleInput.d.ts +1 -2
  29. package/dist/types/src/components/Form/custom/TupleInput.d.ts.map +1 -1
  30. package/dist/types/src/components/Form/factory.d.ts +2 -2
  31. package/dist/types/src/components/Form/factory.d.ts.map +1 -1
  32. package/dist/types/src/hooks/useForm.d.ts +9 -10
  33. package/dist/types/src/hooks/useForm.d.ts.map +1 -1
  34. package/package.json +23 -23
  35. package/src/components/FieldEditor/FieldEditor.tsx +4 -4
  36. package/src/components/Form/ArrayField.tsx +111 -0
  37. package/src/components/Form/Defaults.tsx +18 -33
  38. package/src/components/Form/Form.stories.tsx +15 -5
  39. package/src/components/Form/Form.tsx +37 -359
  40. package/src/components/Form/FormActions.tsx +41 -0
  41. package/src/components/Form/FormContent.tsx +155 -0
  42. package/src/components/Form/FormContext.tsx +48 -0
  43. package/src/components/Form/Input.tsx +5 -6
  44. package/src/components/Form/custom/GeoPointInput.tsx +6 -15
  45. package/src/components/Form/custom/TupleInput.tsx +5 -9
  46. package/src/components/Form/factory.tsx +2 -5
  47. package/src/hooks/useForm.ts +54 -46
@@ -32,7 +32,6 @@ __export(node_exports, {
32
32
  DeprecatedFormInput: () => DeprecatedFormInput,
33
33
  FieldEditor: () => FieldEditor,
34
34
  Form: () => Form,
35
- FormActions: () => FormActions,
36
35
  GeoPointInput: () => GeoPointInput,
37
36
  InputHeader: () => InputHeader,
38
37
  NumberInput: () => NumberInput,
@@ -69,32 +68,48 @@ var import_react_ui_theme2 = require("@dxos/react-ui-theme");
69
68
  var import_util2 = require("@dxos/util");
70
69
  var import_react6 = __toESM(require("react"));
71
70
  var import_react_ui6 = require("@dxos/react-ui");
72
- var import_effect = require("effect");
73
- var import_String = require("effect/String");
74
71
  var import_react7 = __toESM(require("react"));
72
+ var import_react_ui_theme3 = require("@dxos/react-ui-theme");
73
+ var import_react8 = __toESM(require("react"));
74
+ var import_react_ui7 = require("@dxos/react-ui");
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");
75
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");
76
82
  var import_effect2 = require("@dxos/effect");
83
+ var import_invariant = require("@dxos/invariant");
77
84
  var import_log2 = require("@dxos/log");
78
- var import_react_ui7 = require("@dxos/react-ui");
79
- var import_react_ui_theme3 = require("@dxos/react-ui-theme");
80
85
  var import_schema2 = require("@dxos/schema");
81
- var import_util3 = require("@dxos/util");
82
- var import_echo_schema3 = require("@dxos/echo-schema");
83
- var import_react8 = require("react");
86
+ var import_effect3 = require("effect");
87
+ var import_String = require("effect/String");
88
+ var import_react11 = __toESM(require("react"));
84
89
  var import_echo_schema4 = require("@dxos/echo-schema");
85
- var import_effect3 = require("@dxos/effect");
86
- var import_invariant = require("@dxos/invariant");
87
- var import_log3 = require("@dxos/log");
90
+ var import_effect4 = require("@dxos/effect");
91
+ var import_react_ui_theme5 = require("@dxos/react-ui-theme");
88
92
  var import_schema3 = require("@dxos/schema");
89
- var import_react9 = __toESM(require("react"));
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"));
90
97
  var import_echo_schema5 = require("@dxos/echo-schema");
98
+ var import_effect6 = require("@dxos/effect");
99
+ var import_invariant2 = require("@dxos/invariant");
91
100
  var import_react_ui8 = require("@dxos/react-ui");
92
- var import_react_ui_list = require("@dxos/react-ui-list");
93
- var import_react_ui_theme4 = require("@dxos/react-ui-theme");
101
+ var import_react_ui_theme6 = require("@dxos/react-ui-theme");
94
102
  var import_schema4 = require("@dxos/schema");
95
- var import_util4 = require("@dxos/util");
96
103
  var import_echo_schema6 = require("@dxos/echo-schema");
104
+ var import_react13 = __toESM(require("react"));
97
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");
98
113
  var translationKey = "react-ui-form";
99
114
  var translations_default = [
100
115
  {
@@ -184,10 +199,10 @@ var InputHeader = ({ children, error }) => {
184
199
  side: "bottom"
185
200
  }, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Tooltip.Arrow, null), error)));
186
201
  };
187
- var GeoPointInput = ({ property, type, label, disabled, getStatus, getValue: getValue2, onValueChange, onBlur }) => {
202
+ var GeoPointInput = ({ type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
188
203
  const { t } = (0, import_react_ui3.useTranslation)(translationKey);
189
- const { status, error } = getStatus?.(property);
190
- const [lng = 0, lat = 0] = getValue2(property) ?? [];
204
+ const { status, error } = getStatus();
205
+ const [lng = 0, lat = 0] = getValue3() ?? [];
191
206
  return /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.Input.Root, {
192
207
  validationValence: status
193
208
  }, /* @__PURE__ */ import_react3.default.createElement(InputHeader, {
@@ -199,7 +214,7 @@ var GeoPointInput = ({ property, type, label, disabled, getStatus, getValue: get
199
214
  disabled,
200
215
  placeholder: t("placeholder longitude"),
201
216
  value: lng,
202
- onChange: (event) => onValueChange(property, type, [
217
+ onChange: (event) => onValueChange(type, [
203
218
  lat,
204
219
  (0, import_util.safeParseFloat)(event.target.value, 0)
205
220
  ]),
@@ -209,7 +224,7 @@ var GeoPointInput = ({ property, type, label, disabled, getStatus, getValue: get
209
224
  disabled,
210
225
  placeholder: t("placeholder latitude"),
211
226
  value: lat,
212
- onChange: (event) => onValueChange(property, type, [
227
+ onChange: (event) => onValueChange(type, [
213
228
  (0, import_util.safeParseFloat)(event.target.value, 0),
214
229
  lng
215
230
  ]),
@@ -222,9 +237,9 @@ var gridCols = [
222
237
  "grid-cols-3",
223
238
  "grid-cols-4"
224
239
  ];
225
- var TupleInput = ({ binding, property, type, label, disabled, getStatus, getValue: getValue2, onValueChange, onBlur }) => {
226
- const { status, error } = getStatus?.(property);
227
- const values = getValue2(property) ?? {};
240
+ var TupleInput = ({ binding, type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
241
+ const { status, error } = getStatus();
242
+ const values = getValue3() ?? {};
228
243
  return /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Input.Root, {
229
244
  validationValence: status
230
245
  }, /* @__PURE__ */ import_react5.default.createElement(InputHeader, {
@@ -236,15 +251,15 @@ var TupleInput = ({ binding, property, type, label, disabled, getStatus, getValu
236
251
  type: "number",
237
252
  disabled,
238
253
  value: values[prop],
239
- onChange: (event) => onValueChange(property, type, {
254
+ onChange: (event) => onValueChange(type, {
240
255
  ...values,
241
256
  [prop]: (0, import_util2.safeParseFloat)(event.target.value, 0)
242
257
  }),
243
258
  onBlur
244
259
  }))));
245
260
  };
246
- var TextInput = ({ property, type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue2, onValueChange, onBlur }) => {
247
- const { status, error } = getStatus?.(property);
261
+ var TextInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
262
+ const { status, error } = getStatus();
248
263
  return /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Root, {
249
264
  validationValence: status
250
265
  }, !inputOnly && /* @__PURE__ */ import_react6.default.createElement(InputHeader, {
@@ -252,13 +267,13 @@ var TextInput = ({ property, type, label, inputOnly, disabled, placeholder, getS
252
267
  }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Label, null, label)), /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.TextInput, {
253
268
  disabled,
254
269
  placeholder,
255
- value: getValue2(property) ?? "",
256
- onChange: (event) => onValueChange(property, type, event.target.value),
270
+ value: getValue3() ?? "",
271
+ onChange: (event) => onValueChange(type, event.target.value),
257
272
  onBlur
258
273
  }), inputOnly && /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Validation, null, error));
259
274
  };
260
- var NumberInput = ({ property, type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue2, onValueChange, onBlur }) => {
261
- const { status, error } = getStatus?.(property);
275
+ var NumberInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
276
+ const { status, error } = getStatus();
262
277
  return /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Root, {
263
278
  validationValence: status
264
279
  }, !inputOnly && /* @__PURE__ */ import_react6.default.createElement(InputHeader, {
@@ -267,31 +282,31 @@ var NumberInput = ({ property, type, label, inputOnly, disabled, placeholder, ge
267
282
  type: "number",
268
283
  disabled,
269
284
  placeholder,
270
- value: getValue2(property) ?? 0,
271
- onChange: (event) => onValueChange(property, type, event.target.value),
285
+ value: getValue3() ?? 0,
286
+ onChange: (event) => onValueChange(type, event.target.value),
272
287
  onBlur
273
288
  }), inputOnly && /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.DescriptionAndValidation, null, error));
274
289
  };
275
- var BooleanInput = ({ property, type, label, inputOnly, getStatus, getValue: getValue2, onValueChange }) => {
276
- const { status, error } = getStatus?.(property);
290
+ var BooleanInput = ({ type, label, inputOnly, getStatus, getValue: getValue3, onValueChange }) => {
291
+ const { status, error } = getStatus();
277
292
  return /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Root, {
278
293
  validationValence: status
279
294
  }, !inputOnly && /* @__PURE__ */ import_react6.default.createElement(InputHeader, {
280
295
  error
281
296
  }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Label, null, label)), /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Switch, {
282
- checked: getValue2(property),
283
- onCheckedChange: (value) => onValueChange(property, type, value)
297
+ checked: getValue3(),
298
+ onCheckedChange: (value) => onValueChange(type, value)
284
299
  }), inputOnly && /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.DescriptionAndValidation, null, error));
285
300
  };
286
- var SelectInput = ({ property, type, label, inputOnly, disabled, placeholder, options, getStatus, getValue: getValue2, onValueChange }) => {
287
- const { status, error } = getStatus?.(property);
301
+ var SelectInput = ({ type, label, inputOnly, disabled, placeholder, options, getStatus, getValue: getValue3, onValueChange }) => {
302
+ const { status, error } = getStatus();
288
303
  return /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Root, {
289
304
  validationValence: status
290
305
  }, !inputOnly && /* @__PURE__ */ import_react6.default.createElement(InputHeader, {
291
306
  error
292
307
  }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Label, null, label)), /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Select.Root, {
293
- value: getValue2(property),
294
- onValueChange: (value) => onValueChange(property, type, value)
308
+ value: getValue3(),
309
+ onValueChange: (value) => onValueChange(type, value)
295
310
  }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Select.TriggerButton, {
296
311
  classNames: "is-full",
297
312
  disabled,
@@ -304,23 +319,9 @@ var SelectInput = ({ property, type, label, inputOnly, disabled, placeholder, op
304
319
  }, label2 ?? String(value))
305
320
  )))))), inputOnly && /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.DescriptionAndValidation, null, error));
306
321
  };
307
- var getInputComponent = (type, format) => {
308
- switch (format) {
309
- case import_echo_schema3.FormatEnum.LatLng:
310
- return GeoPointInput;
311
- }
312
- switch (type) {
313
- case "string":
314
- return TextInput;
315
- case "number":
316
- return NumberInput;
317
- case "boolean":
318
- return BooleanInput;
319
- }
320
- };
321
322
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/hooks/useForm.ts";
322
323
  var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, onSave }) => {
323
- (0, import_invariant.invariant)(import_effect3.AST.isTypeLiteral(schema.ast), void 0, {
324
+ (0, import_invariant.invariant)(import_effect2.AST.isTypeLiteral(schema.ast), void 0, {
324
325
  F: __dxlog_file,
325
326
  L: 91,
326
327
  S: void 0,
@@ -329,18 +330,18 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
329
330
  ""
330
331
  ]
331
332
  });
332
- const [values, setValues] = (0, import_react8.useState)(initialValues);
333
- (0, import_react8.useEffect)(() => {
333
+ const [values, setValues] = (0, import_react10.useState)(initialValues);
334
+ (0, import_react10.useEffect)(() => {
334
335
  setValues(initialValues);
335
336
  }, [
336
337
  initialValues
337
338
  ]);
338
- const [touched, setTouched] = (0, import_react8.useState)(createKeySet(initialValues, false));
339
- const [changed, setChanged] = (0, import_react8.useState)(createKeySet(initialValues, false));
340
- const [errors, setErrors] = (0, import_react8.useState)({});
341
- const [saving, setSaving] = (0, import_react8.useState)(false);
342
- const validate = (0, import_react8.useCallback)((values2) => {
343
- 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) ?? [];
344
345
  if (errors2.length === 0 && onValidate) {
345
346
  const validatedValues = values2;
346
347
  errors2 = onValidate(validatedValues) ?? [];
@@ -352,11 +353,11 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
352
353
  schema,
353
354
  onValidate
354
355
  ]);
355
- const [schemaDirty, setSchemaDirty] = (0, import_react8.useState)(false);
356
- (0, import_react8.useEffect)(() => setSchemaDirty(true), [
356
+ const [schemaDirty, setSchemaDirty] = (0, import_react10.useState)(false);
357
+ (0, import_react10.useEffect)(() => setSchemaDirty(true), [
357
358
  schema
358
359
  ]);
359
- (0, import_react8.useEffect)(() => {
360
+ (0, import_react10.useEffect)(() => {
360
361
  if (schemaDirty) {
361
362
  validate(values);
362
363
  setSchemaDirty(false);
@@ -365,13 +366,13 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
365
366
  values,
366
367
  schemaDirty
367
368
  ]);
368
- const canSave = (0, import_react8.useMemo)(() => !saving && Object.keys(values).every((property) => touched[property] === false || !errors[property]), [
369
- 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}[`))), [
370
371
  touched,
371
372
  errors,
372
373
  saving
373
374
  ]);
374
- const handleSave = (0, import_react8.useCallback)(async () => {
375
+ const handleSave = (0, import_react10.useCallback)(async () => {
375
376
  if (validate(values)) {
376
377
  setSaving(true);
377
378
  try {
@@ -388,38 +389,42 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
388
389
  onSave,
389
390
  changed
390
391
  ]);
391
- const getStatus = (0, import_react8.useCallback)((property) => ({
392
- status: errors[property] ? "error" : void 0,
393
- error: errors[property] ? errors[property] : void 0
394
- }), [
395
- 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
+ }, [
396
400
  errors
397
401
  ]);
398
- const getFormValue = (property) => {
399
- return (0, import_echo_schema4.getValue)(values, property);
402
+ const getFormValue = (path) => {
403
+ return (0, import_echo_schema3.getValue)(values, (0, import_effect2.createJsonPath)(path));
400
404
  };
401
- const onValueChange = (property, type, value) => {
405
+ const onValueChange = (path, type, value) => {
406
+ const jsonPath = (0, import_effect2.createJsonPath)(path);
402
407
  let parsedValue = value;
403
408
  try {
404
409
  if (type === "number") {
405
410
  parsedValue = parseFloat(value) || 0;
406
411
  }
407
412
  } catch (err) {
408
- import_log3.log.catch(err, void 0, {
413
+ import_log2.log.catch(err, void 0, {
409
414
  F: __dxlog_file,
410
- L: 179,
415
+ L: 194,
411
416
  S: void 0,
412
417
  C: (f, a) => f(...a)
413
418
  });
414
419
  parsedValue = void 0;
415
420
  }
416
421
  const newValues = {
417
- ...(0, import_echo_schema4.setValue)(values, property, parsedValue)
422
+ ...(0, import_echo_schema3.setValue)(values, jsonPath, parsedValue)
418
423
  };
419
424
  setValues(newValues);
420
425
  setChanged((prev) => ({
421
426
  ...prev,
422
- [property]: true
427
+ [jsonPath]: true
423
428
  }));
424
429
  onValuesChanged?.(newValues);
425
430
  const isValid = validate(newValues);
@@ -429,15 +434,12 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
429
434
  });
430
435
  }
431
436
  };
432
- const onBlur = (0, import_react8.useCallback)((event) => {
433
- const { name } = event.target;
437
+ const onTouched = (0, import_react10.useCallback)((path) => {
438
+ const jsonPath = (0, import_effect2.createJsonPath)(path);
434
439
  setTouched((touched2) => ({
435
440
  ...touched2,
436
- [name]: true
441
+ [jsonPath]: true
437
442
  }));
438
- if (event.relatedTarget?.getAttribute("type") === "submit") {
439
- setTouched(createKeySet(values, true));
440
- }
441
443
  validate(values);
442
444
  }, [
443
445
  validate,
@@ -455,13 +457,13 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
455
457
  getStatus,
456
458
  getValue: getFormValue,
457
459
  onValueChange,
458
- onBlur
460
+ onTouched
459
461
  };
460
462
  };
461
463
  var createKeySet = (obj, value) => {
462
464
  (0, import_invariant.invariant)(obj, void 0, {
463
465
  F: __dxlog_file,
464
- L: 230,
466
+ L: 236,
465
467
  S: void 0,
466
468
  A: [
467
469
  "obj",
@@ -475,322 +477,313 @@ var createKeySet = (obj, value) => {
475
477
  };
476
478
  var flatMap = (errors) => {
477
479
  return errors.reduce((result, { path, message }) => {
478
- if (!(path in result)) {
479
- result[path] = message;
480
+ const jsonPath = (0, import_effect2.fromEffectValidationPath)(path);
481
+ if (!(jsonPath in result)) {
482
+ result[jsonPath] = message;
480
483
  }
481
484
  return result;
482
485
  }, {});
483
486
  };
484
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/Form/Form.tsx";
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);
495
+ };
496
+ var useInputProps = (path = []) => {
497
+ const { getStatus, getValue: getFormValue, onValueChange, onTouched } = useFormContext();
498
+ return {
499
+ getStatus: () => getStatus(path),
500
+ getValue: () => getFormValue(path),
501
+ onValueChange: (type, value) => onValueChange(path, type, value),
502
+ onBlur: () => onTouched(path)
503
+ };
504
+ };
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";
485
535
  var padding = "px-2";
486
- var Form = ({ classNames, schema, values: initialValues, path = [], readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, lookupComponent, Custom }) => {
487
- const onValid = (0, import_react7.useMemo)(() => autoSave ? onSave : void 0, [
488
- autoSave,
489
- onSave
490
- ]);
491
- const { canSave, values, errors, handleSave, ...inputProps } = useForm({
492
- schema,
493
- initialValues,
494
- onValuesChanged,
495
- onValidate,
496
- onValid,
497
- 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
+ ]
498
548
  });
499
- const properties = (0, import_react7.useMemo)(() => {
500
- const props = (0, import_schema2.getSchemaProperties)(schema.ast, values);
501
- const filtered = filter ? filter(props) : props;
502
- const findIndex = (props2, prop) => {
503
- const idx = props2.findIndex((p) => p === prop);
504
- return idx === -1 ? Infinity : idx;
505
- };
506
- 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
+ }
507
569
  }, [
508
- schema,
509
- 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,
510
583
  values
511
584
  ]);
512
- (0, import_react7.useEffect)(() => {
513
- if (errors && Object.keys(errors).length) {
514
- import_log2.log.warn("validation", {
515
- errors
516
- }, {
517
- F: __dxlog_file2,
518
- L: 106,
519
- S: void 0,
520
- C: (f, a) => f(...a)
521
- });
522
- }
585
+ const handleRemove = (0, import_react12.useCallback)((index) => {
586
+ const newValues = values.filter((_, i) => i !== index);
587
+ inputProps.onValueChange(type, newValues);
523
588
  }, [
524
- errors
589
+ type,
590
+ inputProps,
591
+ values
525
592
  ]);
526
- return /* @__PURE__ */ import_react7.default.createElement("div", {
527
- role: "form",
528
- className: (0, import_react_ui_theme3.mx)("flex flex-col w-full gap-2 py-2", classNames),
529
- "data-testid": testId
530
- }, properties.map((property) => {
531
- const { ast, name, type, format, title, description, examples, options, array } = property;
532
- const key = [
533
- ...path,
534
- name
535
- ];
536
- const label = title ?? (0, import_effect.pipe)(name, import_String.capitalize);
537
- const placeholder = examples?.length ? `Example: "${examples[0]}"` : description;
538
- const FoundComponent = lookupComponent?.({
539
- prop: name,
540
- schema: import_echo_schema2.S.make(ast),
541
- inputProps: {
542
- property: name,
543
- type,
544
- format,
545
- label,
546
- disabled: readonly,
547
- placeholder,
548
- ...inputProps
549
- }
550
- });
551
- if (FoundComponent) {
552
- return /* @__PURE__ */ import_react7.default.createElement("div", {
553
- key: name,
554
- role: "none",
555
- className: padding
556
- }, FoundComponent);
557
- }
558
- let InputComponent = Custom?.[key.join(".")];
559
- if (!InputComponent) {
560
- if (options) {
561
- return /* @__PURE__ */ import_react7.default.createElement("div", {
562
- key: name,
563
- role: "none",
564
- className: padding
565
- }, /* @__PURE__ */ import_react7.default.createElement(SelectInput, {
566
- type,
567
- format,
568
- property: name,
569
- disabled: readonly,
570
- label,
571
- options: options.map((option) => ({
572
- value: option,
573
- label: String(option)
574
- })),
575
- placeholder,
576
- ...inputProps
577
- }));
578
- }
579
- InputComponent = getInputComponent(type, format);
580
- if (array) {
581
- return /* @__PURE__ */ import_react7.default.createElement(ArrayField, {
582
- key: name,
583
- name,
584
- type,
585
- array: true,
586
- label,
587
- ast,
588
- values,
589
- format,
590
- readonly,
591
- placeholder,
592
- inputProps,
593
- Custom
594
- });
595
- }
596
- }
597
- if (!InputComponent) {
598
- if (type === "object") {
599
- const baseNode = (0, import_effect2.findNode)(ast, import_effect2.isDiscriminatedUnion);
600
- const typeLiteral = baseNode ? (0, import_effect2.getDiscriminatedType)(baseNode, values[name]) : (0, import_effect2.findNode)(ast, import_echo_schema2.AST.isTypeLiteral);
601
- if (typeLiteral) {
602
- const schema2 = import_echo_schema2.S.make(typeLiteral);
603
- return /* @__PURE__ */ import_react7.default.createElement("div", {
604
- key: name,
605
- role: "none"
606
- }, /* @__PURE__ */ import_react7.default.createElement("div", {
607
- className: padding
608
- }, label), /* @__PURE__ */ import_react7.default.createElement(Form, {
609
- schema: schema2,
610
- path: key,
611
- values: values[name] ?? {},
612
- onValuesChanged: (childValues) => {
613
- inputProps.onValueChange(name, "object", childValues);
614
- },
615
- Custom
616
- }));
617
- }
618
- }
619
- (0, import_log2.log)("no renderer for property", {
620
- name,
621
- type
622
- }, {
623
- F: __dxlog_file2,
624
- L: 213,
625
- S: void 0,
626
- C: (f, a) => f(...a)
627
- });
628
- return null;
629
- }
630
- return /* @__PURE__ */ import_react7.default.createElement("div", {
631
- key: name,
632
- role: "none",
633
- className: padding
634
- }, /* @__PURE__ */ import_react7.default.createElement(InputComponent, {
635
- type,
636
- format,
637
- property: name,
638
- disabled: readonly,
639
- label,
640
- placeholder,
641
- ...inputProps
642
- }));
643
- }).filter(import_util3.isNotFalsy), (onCancel || onSave) && !autoSave && /* @__PURE__ */ import_react7.default.createElement(FormActions, {
644
- onCancel,
645
- onSubmit: handleSave,
646
- canSubmit: canSave,
647
- readonly
648
- }));
649
- };
650
- var ArrayField = ({ name, type, label, ast, values, format, readonly, placeholder, inputProps, Custom }) => {
651
- const { t } = (0, import_react_ui7.useTranslation)(translationKey);
652
- const arrayValues = values[name] ?? [];
653
- const key = [
654
- name
655
- ];
656
- const tupleType = (0, import_effect2.findNode)(ast, import_echo_schema2.AST.isTupleType);
657
- const elementType = tupleType?.rest[0]?.type;
658
- if (type === "object" && elementType) {
659
- const baseNode = (0, import_effect2.findNode)(elementType, import_effect2.isDiscriminatedUnion);
660
- const typeLiteral = baseNode ? (0, import_effect2.getDiscriminatedType)(baseNode, values[name]) : (0, import_effect2.findNode)(elementType, import_echo_schema2.AST.isTypeLiteral);
661
- if (typeLiteral) {
662
- const schema = import_echo_schema2.S.make(typeLiteral);
663
- return /* @__PURE__ */ import_react7.default.createElement("div", {
664
- key: name,
665
- role: "none",
666
- className: (0, import_react_ui_theme3.mx)(padding)
667
- }, /* @__PURE__ */ import_react7.default.createElement(InputHeader, null, label), /* @__PURE__ */ import_react7.default.createElement("div", {
668
- role: "none",
669
- className: "flex flex-col gap-1"
670
- }, arrayValues.map((value, index) => {
671
- return /* @__PURE__ */ import_react7.default.createElement("div", {
672
- key: index,
673
- role: "none",
674
- className: "flex items-center gap-1"
675
- }, /* @__PURE__ */ import_react7.default.createElement("div", {
676
- role: "none",
677
- className: "flex-1"
678
- }, /* @__PURE__ */ import_react7.default.createElement(Form, {
679
- schema,
680
- path: [
681
- ...key,
682
- `[${index}]`
683
- ],
684
- values: value,
685
- onValuesChanged: (childValues) => {
686
- const newValues = [
687
- ...arrayValues
688
- ];
689
- newValues[index] = childValues;
690
- inputProps.onValueChange(name, "object", newValues);
691
- },
692
- Custom
693
- })), /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.IconButton, {
694
- icon: "ph--trash--regular",
695
- iconOnly: true,
696
- label: t("button remove"),
697
- onClick: () => {
698
- const newValues = arrayValues.filter((_, i) => i !== index);
699
- inputProps.onValueChange(name, type, newValues);
700
- }
701
- }));
702
- })), /* @__PURE__ */ import_react7.default.createElement("div", {
703
- role: "none",
704
- className: "flex justify-between items-center plb-1"
705
- }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.IconButton, {
706
- icon: "ph--plus--regular",
707
- iconOnly: true,
708
- label: t("button add"),
709
- onClick: () => {
710
- const newValues = [
711
- ...arrayValues,
712
- {}
713
- ];
714
- inputProps.onValueChange(name, type, newValues);
715
- }
716
- })));
717
- }
718
- return /* @__PURE__ */ import_react7.default.createElement("div", {
719
- key: name,
720
- role: "none"
721
- }, "Nested form not supported in arrays, yet.");
722
- }
723
- const InputComponent = getInputComponent(type, format);
724
- if (!InputComponent) {
593
+ if (!elementType) {
725
594
  return null;
726
595
  }
727
- return /* @__PURE__ */ import_react7.default.createElement("div", {
596
+ return /* @__PURE__ */ import_react12.default.createElement("div", {
728
597
  role: "none",
729
- key: "meta-input",
730
- className: (0, import_react_ui_theme3.mx)(padding)
731
- }, /* @__PURE__ */ import_react7.default.createElement(InputHeader, null, label), /* @__PURE__ */ import_react7.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", {
732
600
  role: "none",
733
601
  className: "flex flex-col gap-1"
734
- }, arrayValues.map((_, index) => /* @__PURE__ */ import_react7.default.createElement("div", {
602
+ }, values.map((_value, index) => /* @__PURE__ */ import_react12.default.createElement("div", {
735
603
  key: index,
736
604
  role: "none",
737
- className: "flex items-start gap-1"
738
- }, /* @__PURE__ */ import_react7.default.createElement("div", {
605
+ className: "flex items-center gap-1"
606
+ }, /* @__PURE__ */ import_react12.default.createElement("div", {
739
607
  role: "none",
740
608
  className: "flex-1"
741
- }, /* @__PURE__ */ import_react7.default.createElement(InputComponent, {
742
- type,
743
- format,
744
- label,
745
- inputOnly: true,
746
- property: `${name}[${index}]`,
747
- disabled: readonly,
748
- placeholder,
749
- ...inputProps
750
- })), /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.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, {
751
624
  icon: "ph--trash--regular",
752
625
  iconOnly: true,
753
626
  label: t("button remove"),
754
- onClick: () => {
755
- const newValues = arrayValues.filter((_2, i) => i !== index);
756
- inputProps.onValueChange(name, type, newValues);
757
- }
758
- })))), /* @__PURE__ */ import_react7.default.createElement("div", {
627
+ onClick: () => handleRemove(index)
628
+ })))), /* @__PURE__ */ import_react12.default.createElement("div", {
759
629
  role: "none",
760
630
  className: "flex justify-between items-center plb-1"
761
- }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.IconButton, {
631
+ }, /* @__PURE__ */ import_react12.default.createElement(import_react_ui8.IconButton, {
762
632
  icon: "ph--plus--regular",
763
633
  iconOnly: true,
764
634
  label: t("button add"),
765
- onClick: () => {
766
- const newValues = [
767
- ...arrayValues,
768
- import_effect2.SimpleType.getDefaultValue(type)
769
- ];
770
- inputProps.onValueChange(name, type, newValues);
771
- }
635
+ onClick: handleAdd
772
636
  })));
773
637
  };
774
- var FormActions = ({ onCancel, onSubmit, canSubmit, readonly }) => {
775
- const { t } = (0, import_react_ui7.useTranslation)(translationKey);
776
- return /* @__PURE__ */ import_react7.default.createElement("div", {
777
- role: "none",
778
- className: "flex justify-center"
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
779
772
  }, /* @__PURE__ */ import_react7.default.createElement("div", {
780
773
  role: "none",
781
- className: (0, import_react_ui_theme3.mx)(onCancel && !readonly && "grid grid-cols-2 gap-2")
782
- }, onCancel && !readonly && /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.IconButton, {
783
- "data-testid": "cancel-button",
784
- icon: "ph--x--regular",
785
- label: t("button cancel"),
786
- onClick: onCancel
787
- }), onSubmit && /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.IconButton, {
788
- type: "submit",
789
- "data-testid": "save-button",
790
- disabled: !canSubmit,
791
- icon: "ph--check--regular",
792
- label: t("button save"),
793
- 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
794
787
  })));
795
788
  };
796
789
  var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
@@ -950,22 +943,22 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
950
943
  });
951
944
  };
952
945
  var grid = "grid grid-cols-[32px_1fr_32px] min-bs-[2.5rem]";
953
- var ViewMetaSchema = import_echo_schema5.S.Struct({
954
- name: import_echo_schema5.S.String.annotations({
955
- [import_echo_schema5.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"
956
949
  }),
957
- typename: import_echo_schema5.Format.DXN.annotations({
958
- [import_echo_schema5.AST.TitleAnnotationId]: "Typename"
950
+ typename: import_echo_schema7.Format.DXN.annotations({
951
+ [import_echo_schema7.AST.TitleAnnotationId]: "Typename"
959
952
  })
960
- }).pipe(import_echo_schema5.S.mutable);
953
+ }).pipe(import_echo_schema7.S.mutable);
961
954
  var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading = false, onTypenameChanged, onDelete }) => {
962
- const { t } = (0, import_react_ui8.useTranslation)(translationKey);
963
- const projection = (0, import_react9.useMemo)(() => new import_schema4.ViewProjection(schema, view), [
955
+ const { t } = (0, import_react_ui9.useTranslation)(translationKey);
956
+ const projection = (0, import_react13.useMemo)(() => new import_schema5.ViewProjection(schema, view), [
964
957
  schema,
965
958
  view
966
959
  ]);
967
- const [field, setField] = (0, import_react9.useState)();
968
- const viewValues = (0, import_react9.useMemo)(() => {
960
+ const [field, setField] = (0, import_react13.useState)();
961
+ const viewValues = (0, import_react13.useMemo)(() => {
969
962
  return {
970
963
  name: view.name,
971
964
  // TODO(burdon): Need to warn user of possible consequences of editing.
@@ -975,7 +968,7 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
975
968
  }, [
976
969
  view
977
970
  ]);
978
- const handleViewUpdate = (0, import_react9.useCallback)(({ name, typename }) => {
971
+ const handleViewUpdate = (0, import_react13.useCallback)(({ name, typename }) => {
979
972
  requestAnimationFrame(() => {
980
973
  if (view.name !== name) {
981
974
  view.name = name;
@@ -989,72 +982,72 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
989
982
  schema,
990
983
  onTypenameChanged
991
984
  ]);
992
- const handleSelect = (0, import_react9.useCallback)((field2) => {
985
+ const handleSelect = (0, import_react13.useCallback)((field2) => {
993
986
  setField((f) => f === field2 ? void 0 : field2);
994
987
  }, []);
995
- const handleAdd = (0, import_react9.useCallback)(() => {
988
+ const handleAdd = (0, import_react13.useCallback)(() => {
996
989
  const field2 = projection.createFieldProjection();
997
990
  setField(field2);
998
991
  }, [
999
992
  view
1000
993
  ]);
1001
- const handleMove = (0, import_react9.useCallback)((fromIndex, toIndex) => {
994
+ const handleMove = (0, import_react13.useCallback)((fromIndex, toIndex) => {
1002
995
  (0, import_util4.arrayMove)(view.fields, fromIndex, toIndex);
1003
996
  }, [
1004
997
  view.fields
1005
998
  ]);
1006
- const handleClose = (0, import_react9.useCallback)(() => setField(void 0), []);
1007
- return /* @__PURE__ */ import_react9.default.createElement("div", {
999
+ const handleClose = (0, import_react13.useCallback)(() => setField(void 0), []);
1000
+ return /* @__PURE__ */ import_react13.default.createElement("div", {
1008
1001
  role: "none",
1009
- className: (0, import_react_ui_theme4.mx)("flex flex-col w-full divide-y divide-separator", classNames)
1010
- }, /* @__PURE__ */ import_react9.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, {
1011
1004
  autoFocus: true,
1012
1005
  autoSave: true,
1013
1006
  schema: ViewMetaSchema,
1014
1007
  values: viewValues,
1015
1008
  onSave: handleViewUpdate
1016
- }), /* @__PURE__ */ import_react9.default.createElement("div", null, /* @__PURE__ */ import_react9.default.createElement("div", {
1009
+ }), /* @__PURE__ */ import_react13.default.createElement("div", null, /* @__PURE__ */ import_react13.default.createElement("div", {
1017
1010
  role: "none",
1018
1011
  className: "p-2"
1019
- }, /* @__PURE__ */ import_react9.default.createElement("label", {
1020
- className: (0, import_react_ui_theme4.mx)(import_react_ui_theme4.inputTextLabel)
1021
- }, t("fields label"))), /* @__PURE__ */ import_react9.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, {
1022
1015
  items: view.fields,
1023
- isItem: import_echo_schema5.S.is(import_schema4.FieldSchema),
1016
+ isItem: import_echo_schema7.S.is(import_schema5.FieldSchema),
1024
1017
  getId: (field2) => field2.id,
1025
1018
  onMove: handleMove
1026
- }, ({ items: fields }) => /* @__PURE__ */ import_react9.default.createElement(import_react9.default.Fragment, null, showHeading && /* @__PURE__ */ import_react9.default.createElement("div", {
1019
+ }, ({ items: fields }) => /* @__PURE__ */ import_react13.default.createElement(import_react13.default.Fragment, null, showHeading && /* @__PURE__ */ import_react13.default.createElement("div", {
1027
1020
  role: "heading",
1028
1021
  className: grid
1029
- }, /* @__PURE__ */ import_react9.default.createElement("div", null), /* @__PURE__ */ import_react9.default.createElement("div", {
1022
+ }, /* @__PURE__ */ import_react13.default.createElement("div", null), /* @__PURE__ */ import_react13.default.createElement("div", {
1030
1023
  className: "flex items-center text-sm"
1031
- }, t("field path label"))), /* @__PURE__ */ import_react9.default.createElement("div", {
1024
+ }, t("field path label"))), /* @__PURE__ */ import_react13.default.createElement("div", {
1032
1025
  role: "list",
1033
1026
  className: "flex flex-col w-full"
1034
- }, fields?.map((field2) => /* @__PURE__ */ import_react9.default.createElement(import_react_ui_list.List.Item, {
1027
+ }, fields?.map((field2) => /* @__PURE__ */ import_react13.default.createElement(import_react_ui_list.List.Item, {
1035
1028
  key: field2.id,
1036
1029
  item: field2,
1037
- classNames: (0, import_react_ui_theme4.mx)(grid, import_react_ui_theme4.ghostHover, "cursor-pointer")
1038
- }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui_list.List.ItemDragHandle, null), /* @__PURE__ */ import_react9.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, {
1039
1032
  onClick: () => handleSelect(field2)
1040
- }, field2.path), /* @__PURE__ */ import_react9.default.createElement(import_react_ui_list.List.ItemDeleteButton, {
1033
+ }, field2.path), /* @__PURE__ */ import_react13.default.createElement(import_react_ui_list.List.ItemDeleteButton, {
1041
1034
  disabled: view.fields.length <= 1,
1042
1035
  onClick: () => onDelete(field2.id)
1043
- }))))))), field && /* @__PURE__ */ import_react9.default.createElement(FieldEditor, {
1036
+ }))))))), field && /* @__PURE__ */ import_react13.default.createElement(FieldEditor, {
1044
1037
  key: field.id,
1045
1038
  view,
1046
1039
  projection,
1047
1040
  field,
1048
1041
  registry,
1049
1042
  onSave: handleClose
1050
- }), !readonly && !field && /* @__PURE__ */ import_react9.default.createElement("div", {
1043
+ }), !readonly && !field && /* @__PURE__ */ import_react13.default.createElement("div", {
1051
1044
  className: "flex p-2 justify-center"
1052
- }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui8.IconButton, {
1045
+ }, /* @__PURE__ */ import_react13.default.createElement(import_react_ui9.IconButton, {
1053
1046
  icon: "ph--plus--regular",
1054
1047
  label: t("button add property"),
1055
1048
  onClick: handleAdd,
1056
1049
  // TODO(burdon): Show field limit in ux (not tooltip).
1057
- disabled: view.fields.length >= import_schema4.VIEW_FIELD_LIMIT
1050
+ disabled: view.fields.length >= import_schema5.VIEW_FIELD_LIMIT
1058
1051
  })));
1059
1052
  };
1060
1053
  var parseValue = ({ type, format, value }) => {
@@ -1063,7 +1056,7 @@ var parseValue = ({ type, format, value }) => {
1063
1056
  }
1064
1057
  const parseScalar = (type2) => {
1065
1058
  switch (type2) {
1066
- case import_echo_schema6.TypeEnum.Boolean: {
1059
+ case import_echo_schema8.TypeEnum.Boolean: {
1067
1060
  if (typeof value === "string") {
1068
1061
  const lowercaseValue = value.toLowerCase();
1069
1062
  if (lowercaseValue === "0" || lowercaseValue === "false") {
@@ -1074,13 +1067,13 @@ var parseValue = ({ type, format, value }) => {
1074
1067
  }
1075
1068
  return Boolean(value);
1076
1069
  }
1077
- case import_echo_schema6.TypeEnum.Number: {
1070
+ case import_echo_schema8.TypeEnum.Number: {
1078
1071
  const cleaned = typeof value === "string" ? value.replace(/[^0-9.-]+/g, "") : value;
1079
1072
  const num = Number(cleaned);
1080
1073
  return Number.isNaN(num) ? null : num;
1081
1074
  }
1082
- case import_echo_schema6.TypeEnum.String:
1083
- case import_echo_schema6.TypeEnum.Ref:
1075
+ case import_echo_schema8.TypeEnum.String:
1076
+ case import_echo_schema8.TypeEnum.Ref:
1084
1077
  return String(value);
1085
1078
  default: {
1086
1079
  return value;
@@ -1091,22 +1084,22 @@ var parseValue = ({ type, format, value }) => {
1091
1084
  return parseScalar(type);
1092
1085
  }
1093
1086
  switch (format) {
1094
- case import_echo_schema6.FormatEnum.Boolean:
1095
- return parseScalar(import_echo_schema6.TypeEnum.Boolean);
1096
- case import_echo_schema6.FormatEnum.Number:
1097
- case import_echo_schema6.FormatEnum.Percent:
1098
- case import_echo_schema6.FormatEnum.Currency:
1099
- return parseScalar(import_echo_schema6.TypeEnum.Number);
1100
- case import_echo_schema6.FormatEnum.String:
1101
- case import_echo_schema6.FormatEnum.Markdown: {
1102
- return parseScalar(import_echo_schema6.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);
1103
1096
  }
1104
- case import_echo_schema6.FormatEnum.Ref:
1105
- throw new Error(`unexpected format: ${import_echo_schema6.FormatEnum.Ref}`);
1106
- case import_echo_schema6.FormatEnum.DateTime:
1107
- case import_echo_schema6.FormatEnum.Date:
1108
- case import_echo_schema6.FormatEnum.Time:
1109
- case import_echo_schema6.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: {
1110
1103
  const date = new Date(value);
1111
1104
  return isNaN(date.getTime()) ? null : date;
1112
1105
  }
@@ -1118,19 +1111,19 @@ var parseValue = ({ type, format, value }) => {
1118
1111
  var cellClassesForFieldType = ({ type, format }) => {
1119
1112
  if (!format) {
1120
1113
  switch (type) {
1121
- case import_echo_schema6.TypeEnum.Number:
1114
+ case import_echo_schema8.TypeEnum.Number:
1122
1115
  return [
1123
1116
  "text-right",
1124
1117
  "font-mono"
1125
1118
  ];
1126
- case import_echo_schema6.TypeEnum.Boolean:
1119
+ case import_echo_schema8.TypeEnum.Boolean:
1127
1120
  return [
1128
1121
  "text-right",
1129
1122
  "font-mono"
1130
1123
  ];
1131
- case import_echo_schema6.TypeEnum.String:
1124
+ case import_echo_schema8.TypeEnum.String:
1132
1125
  return void 0;
1133
- case import_echo_schema6.TypeEnum.Ref:
1126
+ case import_echo_schema8.TypeEnum.Ref:
1134
1127
  return void 0;
1135
1128
  default: {
1136
1129
  return void 0;
@@ -1138,20 +1131,20 @@ var cellClassesForFieldType = ({ type, format }) => {
1138
1131
  }
1139
1132
  }
1140
1133
  switch (format) {
1141
- case import_echo_schema6.FormatEnum.Markdown:
1134
+ case import_echo_schema8.FormatEnum.Markdown:
1142
1135
  return void 0;
1143
- case import_echo_schema6.FormatEnum.Timestamp:
1144
- case import_echo_schema6.FormatEnum.DateTime:
1145
- case import_echo_schema6.FormatEnum.Date:
1146
- case import_echo_schema6.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:
1147
1140
  return [
1148
1141
  "font-mono"
1149
1142
  ];
1150
- case import_echo_schema6.FormatEnum.Currency:
1143
+ case import_echo_schema8.FormatEnum.Currency:
1151
1144
  return [
1152
1145
  "text-right"
1153
1146
  ];
1154
- case import_echo_schema6.FormatEnum.JSON:
1147
+ case import_echo_schema8.FormatEnum.JSON:
1155
1148
  return [
1156
1149
  "font-mono"
1157
1150
  ];
@@ -1169,12 +1162,12 @@ var pathNotUniqueError = (path) => ({
1169
1162
  var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
1170
1163
  const formatScalar = (type2) => {
1171
1164
  switch (type2) {
1172
- case import_echo_schema7.TypeEnum.Boolean:
1165
+ case import_echo_schema9.TypeEnum.Boolean:
1173
1166
  return value.toLocaleString().toUpperCase();
1174
- case import_echo_schema7.TypeEnum.Number:
1167
+ case import_echo_schema9.TypeEnum.Number:
1175
1168
  return value.toLocaleString(locale);
1176
- case import_echo_schema7.TypeEnum.String:
1177
- case import_echo_schema7.TypeEnum.Ref:
1169
+ case import_echo_schema9.TypeEnum.String:
1170
+ case import_echo_schema9.TypeEnum.Ref:
1178
1171
  return String(value);
1179
1172
  default: {
1180
1173
  return String(value);
@@ -1185,20 +1178,20 @@ var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
1185
1178
  return formatScalar(type);
1186
1179
  }
1187
1180
  switch (format) {
1188
- case import_echo_schema7.FormatEnum.Boolean: {
1189
- return formatScalar(import_echo_schema7.TypeEnum.Boolean);
1181
+ case import_echo_schema9.FormatEnum.Boolean: {
1182
+ return formatScalar(import_echo_schema9.TypeEnum.Boolean);
1190
1183
  }
1191
- case import_echo_schema7.FormatEnum.Number: {
1192
- return formatScalar(import_echo_schema7.TypeEnum.Number);
1184
+ case import_echo_schema9.FormatEnum.Number: {
1185
+ return formatScalar(import_echo_schema9.TypeEnum.Number);
1193
1186
  }
1194
- case import_echo_schema7.FormatEnum.String:
1195
- case import_echo_schema7.FormatEnum.Ref: {
1196
- return formatScalar(import_echo_schema7.TypeEnum.String);
1187
+ case import_echo_schema9.FormatEnum.String:
1188
+ case import_echo_schema9.FormatEnum.Ref: {
1189
+ return formatScalar(import_echo_schema9.TypeEnum.String);
1197
1190
  }
1198
- case import_echo_schema7.FormatEnum.Percent: {
1191
+ case import_echo_schema9.FormatEnum.Percent: {
1199
1192
  return `${value * 100}%`;
1200
1193
  }
1201
- case import_echo_schema7.FormatEnum.Currency: {
1194
+ case import_echo_schema9.FormatEnum.Currency: {
1202
1195
  return value.toLocaleString(locale, {
1203
1196
  style: "currency",
1204
1197
  currency: "USD",
@@ -1206,13 +1199,13 @@ var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
1206
1199
  maximumFractionDigits: 2
1207
1200
  });
1208
1201
  }
1209
- case import_echo_schema7.FormatEnum.DateTime:
1210
- case import_echo_schema7.FormatEnum.Date:
1211
- case import_echo_schema7.FormatEnum.Time: {
1202
+ case import_echo_schema9.FormatEnum.DateTime:
1203
+ case import_echo_schema9.FormatEnum.Date:
1204
+ case import_echo_schema9.FormatEnum.Time: {
1212
1205
  const date = new Date(value);
1213
- if (format === import_echo_schema7.FormatEnum.DateTime) {
1206
+ if (format === import_echo_schema9.FormatEnum.DateTime) {
1214
1207
  return date.toLocaleString(locale);
1215
- } else if (format === import_echo_schema7.FormatEnum.Date) {
1208
+ } else if (format === import_echo_schema9.FormatEnum.Date) {
1216
1209
  return date.toLocaleDateString(locale);
1217
1210
  } else {
1218
1211
  return date.toLocaleTimeString(locale);
@@ -1229,10 +1222,10 @@ var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
1229
1222
  var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1230
1223
  const formatScalar = (type2) => {
1231
1224
  switch (type2) {
1232
- case import_echo_schema7.TypeEnum.Boolean:
1233
- case import_echo_schema7.TypeEnum.Number:
1234
- case import_echo_schema7.TypeEnum.String:
1235
- case import_echo_schema7.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:
1236
1229
  return String(value);
1237
1230
  default:
1238
1231
  return String(value);
@@ -1242,27 +1235,27 @@ var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1242
1235
  return formatScalar(type);
1243
1236
  }
1244
1237
  switch (format) {
1245
- case import_echo_schema7.FormatEnum.Boolean:
1246
- case import_echo_schema7.FormatEnum.Number:
1247
- case import_echo_schema7.FormatEnum.String:
1248
- case import_echo_schema7.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: {
1249
1242
  return formatScalar(type);
1250
1243
  }
1251
- case import_echo_schema7.FormatEnum.Percent: {
1244
+ case import_echo_schema9.FormatEnum.Percent: {
1252
1245
  return String(value * 100);
1253
1246
  }
1254
- case import_echo_schema7.FormatEnum.Currency: {
1247
+ case import_echo_schema9.FormatEnum.Currency: {
1255
1248
  return String(value);
1256
1249
  }
1257
- case import_echo_schema7.FormatEnum.DateTime: {
1250
+ case import_echo_schema9.FormatEnum.DateTime: {
1258
1251
  const date = new Date(value);
1259
1252
  return date.toISOString();
1260
1253
  }
1261
- case import_echo_schema7.FormatEnum.Date: {
1254
+ case import_echo_schema9.FormatEnum.Date: {
1262
1255
  const date = new Date(value);
1263
1256
  return date.toISOString().split("T")[0];
1264
1257
  }
1265
- case import_echo_schema7.FormatEnum.Time: {
1258
+ case import_echo_schema9.FormatEnum.Time: {
1266
1259
  const date = new Date(value);
1267
1260
  return date.toISOString().split("T")[1].split(".")[0];
1268
1261
  }
@@ -1277,7 +1270,6 @@ var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1277
1270
  DeprecatedFormInput,
1278
1271
  FieldEditor,
1279
1272
  Form,
1280
- FormActions,
1281
1273
  GeoPointInput,
1282
1274
  InputHeader,
1283
1275
  NumberInput,