@dxos/react-ui-form 0.8.1-main.ae460ac → 0.8.1-staging.31c3ee1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dist/lib/browser/index.mjs +672 -499
  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 +744 -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 +672 -499
  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/ControlSection.d.ts +20 -0
  11. package/dist/types/src/components/ControlSection.d.ts.map +1 -0
  12. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts +2 -1
  13. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
  14. package/dist/types/src/components/Form/ArrayField.d.ts +2 -1
  15. package/dist/types/src/components/Form/ArrayField.d.ts.map +1 -1
  16. package/dist/types/src/components/Form/Defaults.d.ts +6 -5
  17. package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
  18. package/dist/types/src/components/Form/Form.d.ts +2 -2
  19. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  20. package/dist/types/src/components/Form/Form.stories.d.ts +9 -9
  21. package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
  22. package/dist/types/src/components/Form/FormActions.d.ts +2 -1
  23. package/dist/types/src/components/Form/FormActions.d.ts.map +1 -1
  24. package/dist/types/src/components/Form/FormContent.d.ts +3 -2
  25. package/dist/types/src/components/Form/FormContent.d.ts.map +1 -1
  26. package/dist/types/src/components/Form/FormContext.d.ts +1 -1
  27. package/dist/types/src/components/Form/FormContext.d.ts.map +1 -1
  28. package/dist/types/src/components/Form/Input.d.ts +3 -3
  29. package/dist/types/src/components/Form/Input.d.ts.map +1 -1
  30. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts +2 -1
  31. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts.map +1 -1
  32. package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts +2 -1
  33. package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts.map +1 -1
  34. package/dist/types/src/components/Form/custom/TupleInput.d.ts +2 -1
  35. package/dist/types/src/components/Form/custom/TupleInput.d.ts.map +1 -1
  36. package/dist/types/src/components/Form/index.d.ts +1 -2
  37. package/dist/types/src/components/Form/index.d.ts.map +1 -1
  38. package/dist/types/src/components/ViewEditor/Test.stories.d.ts +2 -1
  39. package/dist/types/src/components/ViewEditor/Test.stories.d.ts.map +1 -1
  40. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +6 -5
  41. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
  42. package/dist/types/src/components/deprecated/Form.d.ts +2 -1
  43. package/dist/types/src/components/deprecated/Form.d.ts.map +1 -1
  44. package/dist/types/src/components/deprecated/Form.stories.d.ts +2 -1
  45. package/dist/types/src/components/deprecated/Form.stories.d.ts.map +1 -1
  46. package/dist/types/src/components/deprecated/FormInput.d.ts +2 -2
  47. package/dist/types/src/components/deprecated/FormInput.d.ts.map +1 -1
  48. package/dist/types/src/components/index.d.ts +1 -0
  49. package/dist/types/src/components/index.d.ts.map +1 -1
  50. package/dist/types/src/components/testing.d.ts +3 -3
  51. package/dist/types/src/components/testing.d.ts.map +1 -1
  52. package/dist/types/src/hooks/useForm.d.ts.map +1 -1
  53. package/dist/types/src/translations.d.ts +1 -0
  54. package/dist/types/src/translations.d.ts.map +1 -1
  55. package/dist/types/src/util/field.d.ts +0 -1
  56. package/dist/types/src/util/field.d.ts.map +1 -1
  57. package/dist/types/src/util/formatting.d.ts.map +1 -1
  58. package/package.json +26 -26
  59. package/src/components/ControlSection.tsx +113 -0
  60. package/src/components/FieldEditor/FieldEditor.stories.tsx +1 -1
  61. package/src/components/Form/Form.stories.tsx +2 -2
  62. package/src/components/Form/Input.tsx +1 -1
  63. package/src/components/Form/custom/SelectOptionsInput.tsx +5 -1
  64. package/src/components/Form/index.ts +1 -3
  65. package/src/components/ViewEditor/ViewEditor.stories.tsx +1 -1
  66. package/src/components/ViewEditor/ViewEditor.tsx +105 -20
  67. package/src/components/index.ts +1 -1
  68. package/src/hooks/useForm.ts +10 -1
  69. package/src/translations.ts +1 -0
  70. package/src/util/field.ts +4 -4
  71. package/src/util/formatting.ts +9 -10
@@ -29,10 +29,18 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
29
29
  var node_exports = {};
30
30
  __export(node_exports, {
31
31
  BooleanInput: () => BooleanInput,
32
+ ControlFrame: () => ControlFrame,
33
+ ControlFrameItem: () => ControlFrameItem,
34
+ ControlGroup: () => ControlGroup,
35
+ ControlItem: () => ControlItem,
36
+ ControlItemInput: () => ControlItemInput,
37
+ ControlSection: () => ControlSection,
38
+ ControlSectionHeading: () => ControlSectionHeading,
32
39
  DeprecatedFormContainer: () => DeprecatedFormContainer,
33
40
  DeprecatedFormInput: () => DeprecatedFormInput,
34
41
  FieldEditor: () => FieldEditor,
35
42
  Form: () => Form,
43
+ FormProvider: () => FormProvider,
36
44
  GeoPointInput: () => GeoPointInput,
37
45
  InputHeader: () => InputHeader,
38
46
  MarkdownInput: () => MarkdownInput,
@@ -43,62 +51,66 @@ __export(node_exports, {
43
51
  TupleInput: () => TupleInput,
44
52
  ViewEditor: () => ViewEditor,
45
53
  cellClassesForFieldType: () => cellClassesForFieldType,
46
- cellClassesForRowSelection: () => cellClassesForRowSelection,
54
+ controlItemClasses: () => controlItemClasses,
47
55
  formatForDisplay: () => formatForDisplay,
48
56
  formatForEditing: () => formatForEditing,
49
57
  parseValue: () => parseValue,
50
58
  pathNotUniqueError: () => pathNotUniqueError,
51
59
  translations: () => translations_default,
52
60
  useForm: () => useForm,
53
- useFormValues: () => useFormValues
61
+ useFormContext: () => useFormContext,
62
+ useFormValues: () => useFormValues,
63
+ useInputProps: () => useInputProps
54
64
  });
55
65
  module.exports = __toCommonJS(node_exports);
56
66
  var import_react = __toESM(require("react"));
57
67
  var import_react_ui = require("@dxos/react-ui");
58
68
  var import_react_ui_theme = require("@dxos/react-ui-theme");
59
69
  var import_react2 = __toESM(require("react"));
70
+ var import_react_ui2 = require("@dxos/react-ui");
71
+ var import_react3 = __toESM(require("react"));
60
72
  var import_echo_schema = require("@dxos/echo-schema");
61
73
  var import_log = require("@dxos/log");
62
- var import_react_ui2 = require("@dxos/react-ui");
74
+ var import_react_ui3 = require("@dxos/react-ui");
63
75
  var import_schema = require("@dxos/schema");
64
- var import_react3 = __toESM(require("react"));
65
- var import_debug = require("@dxos/debug");
76
+ var import_react4 = __toESM(require("react"));
66
77
  var import_echo_schema2 = require("@dxos/echo-schema");
67
- var import_effect = require("@dxos/effect");
68
- var import_effect2 = require("effect");
69
- var import_react4 = require("react");
70
- var import_echo_schema3 = require("@dxos/echo-schema");
71
- var import_effect3 = require("@dxos/effect");
72
- var import_invariant = require("@dxos/invariant");
73
- var import_log2 = require("@dxos/log");
74
- var import_schema2 = require("@dxos/schema");
75
- var import_react5 = __toESM(require("react"));
76
- var import_echo_schema4 = require("@dxos/echo-schema");
77
- var import_react_ui3 = require("@dxos/react-ui");
78
- var import_util = require("@dxos/util");
79
- var import_react6 = __toESM(require("react"));
80
78
  var import_react_ui4 = require("@dxos/react-ui");
79
+ var import_util = require("@dxos/util");
80
+ var import_react5 = __toESM(require("react"));
81
+ var import_react_ui5 = require("@dxos/react-ui");
81
82
  var import_react_ui_theme2 = require("@dxos/react-ui-theme");
82
- var import_react7 = __toESM(require("react"));
83
+ var import_react6 = __toESM(require("react"));
83
84
  var import_keys = require("@dxos/keys");
84
- var import_react_ui5 = require("@dxos/react-ui");
85
+ var import_react_ui6 = require("@dxos/react-ui");
85
86
  var import_react_ui_list = require("@dxos/react-ui-list");
86
87
  var import_react_ui_pickers = require("@dxos/react-ui-pickers");
87
88
  var import_react_ui_theme3 = require("@dxos/react-ui-theme");
88
- var import_react8 = __toESM(require("react"));
89
- var import_react_ui6 = require("@dxos/react-ui");
89
+ var import_react7 = __toESM(require("react"));
90
+ var import_react_ui7 = require("@dxos/react-ui");
90
91
  var import_react_ui_theme4 = require("@dxos/react-ui-theme");
91
92
  var import_util2 = require("@dxos/util");
93
+ var import_react8 = __toESM(require("react"));
94
+ var import_react_ui8 = require("@dxos/react-ui");
92
95
  var import_react9 = __toESM(require("react"));
93
- var import_react_ui7 = require("@dxos/react-ui");
94
- var import_react10 = __toESM(require("react"));
95
96
  var import_react_ui_theme5 = require("@dxos/react-ui-theme");
96
- var import_react11 = __toESM(require("react"));
97
- var import_react_ui8 = require("@dxos/react-ui");
97
+ var import_react10 = __toESM(require("react"));
98
+ var import_react_ui9 = require("@dxos/react-ui");
98
99
  var import_react_ui_theme6 = require("@dxos/react-ui-theme");
100
+ var import_react11 = __toESM(require("react"));
101
+ var import_debug = require("@dxos/debug");
102
+ var import_echo_schema3 = require("@dxos/echo-schema");
103
+ var import_effect = require("@dxos/effect");
104
+ var import_effect2 = require("effect");
105
+ var import_react12 = require("react");
106
+ var import_echo_schema4 = require("@dxos/echo-schema");
107
+ var import_effect3 = require("@dxos/effect");
108
+ var import_invariant = require("@dxos/invariant");
109
+ var import_log2 = require("@dxos/log");
110
+ var import_schema2 = require("@dxos/schema");
99
111
  var import_effect4 = require("effect");
100
112
  var import_String = require("effect/String");
101
- var import_react12 = __toESM(require("react"));
113
+ var import_react13 = __toESM(require("react"));
102
114
  var import_echo_schema5 = require("@dxos/echo-schema");
103
115
  var import_effect5 = require("@dxos/effect");
104
116
  var import_react_ui_theme7 = require("@dxos/react-ui-theme");
@@ -106,21 +118,23 @@ var import_schema3 = require("@dxos/schema");
106
118
  var import_util3 = require("@dxos/util");
107
119
  var import_effect6 = require("effect");
108
120
  var import_String2 = require("effect/String");
109
- var import_react13 = __toESM(require("react"));
121
+ var import_react14 = __toESM(require("react"));
110
122
  var import_echo_schema6 = require("@dxos/echo-schema");
111
123
  var import_effect7 = require("@dxos/effect");
112
124
  var import_invariant2 = require("@dxos/invariant");
113
- var import_react_ui9 = require("@dxos/react-ui");
125
+ var import_react_ui10 = require("@dxos/react-ui");
114
126
  var import_react_ui_theme8 = require("@dxos/react-ui-theme");
115
127
  var import_schema4 = require("@dxos/schema");
116
128
  var import_echo_schema7 = require("@dxos/echo-schema");
117
- var import_react14 = __toESM(require("react"));
129
+ var import_react15 = __toESM(require("react"));
118
130
  var import_echo_schema8 = require("@dxos/echo-schema");
119
- var import_react_ui10 = require("@dxos/react-ui");
131
+ var import_invariant3 = require("@dxos/invariant");
132
+ var import_react_ui11 = require("@dxos/react-ui");
120
133
  var import_react_ui_list2 = require("@dxos/react-ui-list");
121
134
  var import_react_ui_theme9 = require("@dxos/react-ui-theme");
122
135
  var import_schema5 = require("@dxos/schema");
123
136
  var import_echo_schema9 = require("@dxos/echo-schema");
137
+ var import_format = require("date-fns/format");
124
138
  var import_echo_schema10 = require("@dxos/echo-schema");
125
139
  var translationKey = "react-ui-form";
126
140
  var translations_default = [
@@ -128,6 +142,7 @@ var translations_default = [
128
142
  "en-US": {
129
143
  [translationKey]: {
130
144
  "fields label": "Fields",
145
+ "hidden fields label": "Hidden Fields",
131
146
  // TODO(burdon): Standardize field/property.
132
147
  "button add property": "Add property",
133
148
  "field property label": "Property",
@@ -215,303 +230,108 @@ var DeprecatedFormInput = ({ label, description, secondary, children }) => {
215
230
  }
216
231
  return primary;
217
232
  };
218
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/hooks/useForm.ts";
219
- var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, onSave }) => {
220
- (0, import_invariant.invariant)(import_effect2.SchemaAST.isTypeLiteral(schema.ast), void 0, {
221
- F: __dxlog_file,
222
- L: 93,
223
- S: void 0,
224
- A: [
225
- "AST.isTypeLiteral(schema.ast)",
226
- ""
227
- ]
228
- });
229
- const [values, setValues] = (0, import_react4.useState)(initialValues);
230
- (0, import_react4.useEffect)(() => {
231
- setValues(initialValues);
232
- }, [
233
- initialValues
234
- ]);
235
- const [touched, setTouched] = (0, import_react4.useState)(createKeySet(initialValues, false));
236
- const [changed, setChanged] = (0, import_react4.useState)(createKeySet(initialValues, false));
237
- const [errors, setErrors] = (0, import_react4.useState)({});
238
- const [saving, setSaving] = (0, import_react4.useState)(false);
239
- const validate = (0, import_react4.useCallback)((values2) => {
240
- let errors2 = (0, import_schema2.validateSchema)(schema, values2) ?? [];
241
- if (errors2.length === 0 && onValidate) {
242
- const validatedValues = values2;
243
- errors2 = onValidate(validatedValues) ?? [];
244
- }
245
- setErrors(flatMap(errors2));
246
- const valid = errors2.length === 0;
247
- return valid;
248
- }, [
249
- schema,
250
- onValidate
251
- ]);
252
- const [schemaDirty, setSchemaDirty] = (0, import_react4.useState)(false);
253
- (0, import_react4.useEffect)(() => setSchemaDirty(true), [
254
- schema
255
- ]);
256
- (0, import_react4.useEffect)(() => {
257
- if (schemaDirty) {
258
- validate(values);
259
- setSchemaDirty(false);
260
- }
261
- }, [
262
- values,
263
- schemaDirty
264
- ]);
265
- const formIsValid = (0, import_react4.useMemo)(() => {
266
- return Object.keys(errors).length === 0;
267
- }, [
268
- errors
269
- ]);
270
- const canSave = (0, import_react4.useMemo)(() => !saving && // Check if any error paths that are touched have errors.
271
- !Object.entries(touched).some(([path, isTouched]) => isTouched && Object.keys(errors).some((errorPath) => errorPath === path || errorPath.startsWith(`${path}.`) || errorPath.startsWith(`${path}[`))), [
272
- touched,
273
- errors,
274
- saving
275
- ]);
276
- const handleSave = (0, import_react4.useCallback)(async () => {
277
- if (validate(values)) {
278
- setSaving(true);
279
- try {
280
- await onSave?.(values, {
281
- changed
282
- });
283
- } finally {
284
- setSaving(false);
285
- }
286
- }
287
- }, [
288
- values,
289
- validate,
290
- onSave,
291
- changed
292
- ]);
293
- const getStatus = (0, import_react4.useCallback)((path) => {
294
- const jsonPath = Array.isArray(path) ? (0, import_effect3.createJsonPath)(path) : path;
295
- const matchingError = Object.entries(errors).find(([errorPath]) => errorPath === jsonPath || errorPath.startsWith(`${jsonPath}.`) || errorPath.startsWith(`${jsonPath}[`));
296
- return {
297
- status: matchingError ? "error" : void 0,
298
- error: matchingError ? matchingError[1] : void 0
299
- };
300
- }, [
301
- errors
302
- ]);
303
- const getFormValue = (0, import_react4.useCallback)((path) => {
304
- return (0, import_echo_schema3.getValue)(values, (0, import_effect3.createJsonPath)(path));
305
- }, [
306
- values
307
- ]);
308
- const onValueChange = (0, import_react4.useCallback)((path, type, value) => {
309
- const jsonPath = (0, import_effect3.createJsonPath)(path);
310
- let parsedValue = value;
311
- try {
312
- if (type === "number") {
313
- parsedValue = parseFloat(value) || 0;
314
- }
315
- } catch (err) {
316
- import_log2.log.catch(err, void 0, {
317
- F: __dxlog_file,
318
- L: 203,
319
- S: void 0,
320
- C: (f, a) => f(...a)
321
- });
322
- parsedValue = void 0;
323
- }
324
- const newValues = {
325
- ...(0, import_echo_schema3.setValue)(values, jsonPath, parsedValue)
326
- };
327
- setValues(newValues);
328
- setChanged((prev) => ({
329
- ...prev,
330
- [jsonPath]: true
331
- }));
332
- onValuesChanged?.(newValues);
333
- const isValid = validate(newValues);
334
- if (isValid && onValid) {
335
- onValid(newValues, {
336
- changed
337
- });
338
- }
339
- }, [
340
- values,
341
- onValuesChanged,
342
- validate,
343
- onValid,
344
- changed
345
- ]);
346
- const onTouched = (0, import_react4.useCallback)((path) => {
347
- const jsonPath = (0, import_effect3.createJsonPath)(path);
348
- setTouched((touched2) => ({
349
- ...touched2,
350
- [jsonPath]: true
351
- }));
352
- validate(values);
353
- }, [
354
- validate,
355
- values
356
- ]);
357
- return (0, import_react4.useMemo)(() => ({
358
- // State.
359
- values,
360
- errors,
361
- touched,
362
- changed,
363
- canSave,
364
- formIsValid,
365
- // Actions.
366
- handleSave,
367
- // Field utils.
368
- getStatus,
369
- getValue: getFormValue,
370
- onValueChange,
371
- onTouched
372
- }), [
373
- values,
374
- errors,
375
- touched,
376
- changed,
377
- canSave,
378
- formIsValid,
379
- handleSave,
380
- getStatus,
381
- getFormValue,
382
- onValueChange,
383
- onTouched
384
- ]);
385
- };
386
- var createKeySet = (obj, value) => {
387
- (0, import_invariant.invariant)(obj, void 0, {
388
- F: __dxlog_file,
389
- L: 265,
390
- S: void 0,
391
- A: [
392
- "obj",
393
- ""
394
- ]
395
- });
396
- return Object.keys(obj).reduce((acc, key) => ({
397
- ...acc,
398
- [key]: value
399
- }), {});
400
- };
401
- var flatMap = (errors) => {
402
- return errors.reduce((result, { path, message }) => {
403
- const jsonPath = (0, import_effect3.fromEffectValidationPath)(path);
404
- if (!(jsonPath in result)) {
405
- result[jsonPath] = message;
406
- }
407
- return result;
408
- }, {});
233
+ var ControlSectionHeading = ({ title, description }) => {
234
+ const { t } = (0, import_react_ui2.useTranslation)(translationKey);
235
+ return /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement("h2", {
236
+ className: "pli-4 container-max-width text-xl mbs-6 mbe-4"
237
+ }, (0, import_react_ui2.toLocalizedString)(title, t)), description && /* @__PURE__ */ import_react2.default.createElement("p", {
238
+ className: "pli-4 mlb-4 container-max-width text-description"
239
+ }, (0, import_react_ui2.toLocalizedString)(description, t)));
409
240
  };
410
- var FormContext = /* @__PURE__ */ (0, import_react3.createContext)(void 0);
411
- var useFormContext = () => {
412
- return (0, import_react3.useContext)(FormContext) ?? (0, import_debug.raise)(new Error("Missing FormContext"));
241
+ var ControlSection = ({ title, description, children }) => {
242
+ return /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement(ControlSectionHeading, {
243
+ title,
244
+ description
245
+ }), children);
413
246
  };
414
- var useFormValues = (path = []) => {
415
- const { values: formValues } = useFormContext();
416
- const jsonPath = (0, import_effect.createJsonPath)(path);
417
- return (0, import_echo_schema2.getValue)(formValues, jsonPath);
247
+ var ControlGroup = ({ children }) => /* @__PURE__ */ import_react2.default.createElement("div", {
248
+ role: "none",
249
+ className: "group container-max-width grid grid-cols-1 md:grid-cols-[1fr_min-content] gap-4"
250
+ }, children);
251
+ var ControlFrame = ({ children }) => /* @__PURE__ */ import_react2.default.createElement("div", {
252
+ role: "none",
253
+ className: "p-4 border border-separator rounded-lg container-max-width grid grid-cols-1 md:grid-cols-[1fr_1fr] gap-2 md:gap-8"
254
+ }, children);
255
+ var controlItemClasses = "p-4 border border-separator rounded-lg container-max-width grid md:col-span-2 grid-cols-subgrid items-center";
256
+ var controlItemTitleClasses = "text-lg font-normal mbe-2";
257
+ var controlItemDescriptionClasses = "text-base mlb-2 md:mbe-0 text-description";
258
+ var ControlItem = ({ title, description, children }) => {
259
+ const { t } = (0, import_react_ui2.useTranslation)(translationKey);
260
+ return /* @__PURE__ */ import_react2.default.createElement("div", {
261
+ className: controlItemClasses
262
+ }, /* @__PURE__ */ import_react2.default.createElement("div", {
263
+ role: "none"
264
+ }, /* @__PURE__ */ import_react2.default.createElement("h3", {
265
+ className: controlItemTitleClasses
266
+ }, (0, import_react_ui2.toLocalizedString)(title, t)), description && /* @__PURE__ */ import_react2.default.createElement("p", {
267
+ className: controlItemDescriptionClasses
268
+ }, (0, import_react_ui2.toLocalizedString)(description, t))), children);
418
269
  };
419
- var useInputProps = (path = []) => {
420
- const { getStatus, getValue: getFormValue, onValueChange, onTouched } = useFormContext();
421
- const stablePath = (0, import_react3.useMemo)(() => path, [
422
- Array.isArray(path) ? path.join(".") : path
423
- ]);
424
- return (0, import_react3.useMemo)(() => ({
425
- getStatus: () => getStatus(stablePath),
426
- getValue: () => getFormValue(stablePath),
427
- onValueChange: (type, value) => onValueChange(stablePath, type, value),
428
- onBlur: () => onTouched(stablePath)
429
- }), [
430
- getStatus,
431
- getFormValue,
432
- onValueChange,
433
- onTouched,
434
- stablePath
435
- ]);
270
+ var ControlItemInput = ({ title, description, children }) => {
271
+ const { t } = (0, import_react_ui2.useTranslation)(translationKey);
272
+ return /* @__PURE__ */ import_react2.default.createElement(import_react_ui2.Input.Root, null, /* @__PURE__ */ import_react2.default.createElement("div", {
273
+ className: controlItemClasses
274
+ }, /* @__PURE__ */ import_react2.default.createElement("div", {
275
+ role: "none"
276
+ }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui2.Input.Label, {
277
+ classNames: controlItemTitleClasses
278
+ }, (0, import_react_ui2.toLocalizedString)(title, t)), description && /* @__PURE__ */ import_react2.default.createElement(import_react_ui2.Input.DescriptionAndValidation, null, /* @__PURE__ */ import_react2.default.createElement(import_react_ui2.Input.Description, {
279
+ classNames: controlItemDescriptionClasses
280
+ }, (0, import_react_ui2.toLocalizedString)(description, t)))), children));
436
281
  };
437
- var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
438
- const form = useForm(formOptions);
439
- (0, import_react3.useEffect)(() => {
440
- if (!formRef?.current) {
441
- return;
442
- }
443
- const handleKeyDown = (event) => {
444
- const keyIsEnter = event.key === "Enter";
445
- const modifierUsed = event.ctrlKey || event.altKey || event.metaKey || event.shiftKey;
446
- const inputIsTextarea = event.target.tagName.toLowerCase() === "textarea";
447
- const inputOptOut = event.target.hasAttribute("data-no-submit");
448
- const shouldSubmitRegularInput = !inputIsTextarea && keyIsEnter && !modifierUsed;
449
- const shouldSubmitTextarea = inputIsTextarea && keyIsEnter && event.metaKey;
450
- if ((shouldSubmitRegularInput || shouldSubmitTextarea) && !inputOptOut) {
451
- if (!autoSave && form.canSave) {
452
- form.handleSave();
453
- }
454
- if (autoSave && form.formIsValid) {
455
- event.target.blur();
456
- }
457
- }
458
- };
459
- const formElement = formRef.current;
460
- formElement.addEventListener("keydown", handleKeyDown);
461
- return () => formElement.removeEventListener("keydown", handleKeyDown);
462
- }, [
463
- formRef,
464
- form.canSave,
465
- form.formIsValid,
466
- form.handleSave,
467
- autoSave
468
- ]);
469
- return /* @__PURE__ */ import_react3.default.createElement(FormContext.Provider, {
470
- value: form
471
- }, children);
282
+ var ControlFrameItem = ({ title, description, children }) => {
283
+ const { t } = (0, import_react_ui2.useTranslation)(translationKey);
284
+ return /* @__PURE__ */ import_react2.default.createElement("div", {
285
+ role: "group",
286
+ className: "min-is-0"
287
+ }, /* @__PURE__ */ import_react2.default.createElement("h3", {
288
+ className: "text-lg mbe-2"
289
+ }, (0, import_react_ui2.toLocalizedString)(title, t)), description && /* @__PURE__ */ import_react2.default.createElement("p", {
290
+ className: "mlb-2 md:mbe-0 text-description"
291
+ }, (0, import_react_ui2.toLocalizedString)(description, t)), children);
472
292
  };
473
293
  var InputHeader = ({ children, error }) => {
474
- return /* @__PURE__ */ import_react6.default.createElement("div", {
294
+ return /* @__PURE__ */ import_react5.default.createElement("div", {
475
295
  role: "none",
476
296
  className: "flex justify-between items-center mb-1"
477
- }, children, error && /* @__PURE__ */ import_react6.default.createElement(import_react_ui4.Tooltip.Root, null, /* @__PURE__ */ import_react6.default.createElement(import_react_ui4.Tooltip.Trigger, {
297
+ }, children, error && /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Tooltip.Root, null, /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Tooltip.Trigger, {
478
298
  asChild: true
479
- }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui4.Icon, {
299
+ }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Icon, {
480
300
  icon: "ph--warning--regular",
481
301
  size: 4,
482
302
  classNames: import_react_ui_theme2.errorText
483
- })), /* @__PURE__ */ import_react6.default.createElement(import_react_ui4.Tooltip.Content, {
303
+ })), /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Tooltip.Content, {
484
304
  side: "bottom"
485
- }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui4.Tooltip.Arrow, null), error)));
305
+ }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Tooltip.Arrow, null), error)));
486
306
  };
487
307
  var GeoPointInput = ({ type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
488
- const { t } = (0, import_react_ui3.useTranslation)(translationKey);
308
+ const { t } = (0, import_react_ui4.useTranslation)(translationKey);
489
309
  const { status, error } = getStatus();
490
- const geoPoint = (0, import_react5.useMemo)(() => getValue3() ?? [
310
+ const geoPoint = (0, import_react4.useMemo)(() => getValue3() ?? [
491
311
  0,
492
312
  0
493
313
  ], [
494
314
  getValue3
495
315
  ]);
496
- const geoLocation = (0, import_react5.useMemo)(() => import_echo_schema4.GeoLocation.fromGeoPoint(geoPoint), [
316
+ const geoLocation = (0, import_react4.useMemo)(() => import_echo_schema2.GeoLocation.fromGeoPoint(geoPoint), [
497
317
  geoPoint
498
318
  ]);
499
- const [longitudeText, setLongitudeText] = (0, import_react5.useState)(geoLocation.longitude?.toString());
500
- const [latitudeText, setLatitudeText] = (0, import_react5.useState)(geoLocation.latitude?.toString());
501
- (0, import_react5.useEffect)(() => {
502
- const location = import_echo_schema4.GeoLocation.fromGeoPoint(geoPoint);
319
+ const [longitudeText, setLongitudeText] = (0, import_react4.useState)(geoLocation.longitude?.toString());
320
+ const [latitudeText, setLatitudeText] = (0, import_react4.useState)(geoLocation.latitude?.toString());
321
+ (0, import_react4.useEffect)(() => {
322
+ const location = import_echo_schema2.GeoLocation.fromGeoPoint(geoPoint);
503
323
  setLongitudeText(location.longitude.toString());
504
324
  setLatitudeText(location.latitude.toString());
505
325
  }, [
506
326
  geoPoint
507
327
  ]);
508
- const handleCoordinateChange = (0, import_react5.useCallback)((coordinateType, setText) => (event) => {
328
+ const handleCoordinateChange = (0, import_react4.useCallback)((coordinateType, setText) => (event) => {
509
329
  const inputText = event.target.value;
510
330
  setText(inputText);
511
331
  if (inputText !== "" && inputText !== "-") {
512
332
  const coord = (0, import_util.safeParseFloat)(inputText);
513
333
  if (coord !== void 0 && !isNaN(coord)) {
514
- const currentLocation = import_echo_schema4.GeoLocation.fromGeoPoint(getValue3() ?? [
334
+ const currentLocation = import_echo_schema2.GeoLocation.fromGeoPoint(getValue3() ?? [
515
335
  0,
516
336
  0
517
337
  ]);
@@ -519,7 +339,7 @@ var GeoPointInput = ({ type, label, disabled, getStatus, getValue: getValue3, on
519
339
  ...currentLocation,
520
340
  [coordinateType]: coord
521
341
  };
522
- const newValue = import_echo_schema4.GeoLocation.toGeoPoint(newLocation);
342
+ const newValue = import_echo_schema2.GeoLocation.toGeoPoint(newLocation);
523
343
  onValueChange(type, newValue);
524
344
  }
525
345
  }
@@ -528,14 +348,14 @@ var GeoPointInput = ({ type, label, disabled, getStatus, getValue: getValue3, on
528
348
  onValueChange,
529
349
  type
530
350
  ]);
531
- return /* @__PURE__ */ import_react5.default.createElement(import_react_ui3.Input.Root, {
351
+ return /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.Root, {
532
352
  validationValence: status
533
- }, /* @__PURE__ */ import_react5.default.createElement(InputHeader, {
353
+ }, /* @__PURE__ */ import_react4.default.createElement(InputHeader, {
534
354
  error
535
- }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui3.Input.Label, null, label)), /* @__PURE__ */ import_react5.default.createElement("div", {
355
+ }, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.Label, null, label)), /* @__PURE__ */ import_react4.default.createElement("div", {
536
356
  role: "none",
537
357
  className: "grid grid-cols-2 gap-2"
538
- }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui3.Input.TextInput, {
358
+ }, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.TextInput, {
539
359
  type: "text",
540
360
  pattern: "^-?[0-9]*\\.?[0-9]*$",
541
361
  disabled,
@@ -543,7 +363,7 @@ var GeoPointInput = ({ type, label, disabled, getStatus, getValue: getValue3, on
543
363
  value: latitudeText,
544
364
  onChange: handleCoordinateChange("latitude", setLatitudeText),
545
365
  onBlur
546
- }), /* @__PURE__ */ import_react5.default.createElement(import_react_ui3.Input.TextInput, {
366
+ }), /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.TextInput, {
547
367
  type: "text",
548
368
  pattern: "^-?[0-9]*\\.?[0-9]*$",
549
369
  disabled,
@@ -554,13 +374,13 @@ var GeoPointInput = ({ type, label, disabled, getStatus, getValue: getValue3, on
554
374
  })));
555
375
  };
556
376
  var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3, onValueChange }) => {
557
- const [selected, setSelectedId] = (0, import_react7.useState)(null);
558
- const [isNewOption, setIsNewOption] = (0, import_react7.useState)(false);
559
- const inputRef = (0, import_react7.useRef)(null);
560
- const { t } = (0, import_react_ui5.useTranslation)(translationKey);
377
+ const [selected, setSelectedId] = (0, import_react6.useState)(null);
378
+ const [isNewOption, setIsNewOption] = (0, import_react6.useState)(false);
379
+ const inputRef = (0, import_react6.useRef)(null);
380
+ const { t } = (0, import_react_ui6.useTranslation)(translationKey);
561
381
  const { status, error } = getStatus();
562
382
  const options = getValue3();
563
- (0, import_react7.useEffect)(() => {
383
+ (0, import_react6.useEffect)(() => {
564
384
  if (options === void 0) {
565
385
  onValueChange(type, []);
566
386
  }
@@ -579,7 +399,7 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
579
399
  const availableHues = import_react_ui_theme3.hues.filter((hue) => !lastThree.has(hue));
580
400
  return availableHues[Math.floor(Math.random() * availableHues.length)] ?? import_react_ui_theme3.hues[Math.floor(Math.random() * import_react_ui_theme3.hues.length)];
581
401
  };
582
- const handleAdd = (0, import_react7.useCallback)(() => {
402
+ const handleAdd = (0, import_react6.useCallback)(() => {
583
403
  const newId = import_keys.PublicKey.random().truncate();
584
404
  const newOption = {
585
405
  id: newId,
@@ -597,7 +417,7 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
597
417
  type,
598
418
  onValueChange
599
419
  ]);
600
- const handleDelete = (0, import_react7.useCallback)((id) => {
420
+ const handleDelete = (0, import_react6.useCallback)((id) => {
601
421
  const newOptions = options?.filter((option) => option.id !== id) ?? [];
602
422
  onValueChange(type, newOptions);
603
423
  setSelectedId(null);
@@ -606,7 +426,7 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
606
426
  type,
607
427
  onValueChange
608
428
  ]);
609
- const handleMove = (0, import_react7.useCallback)((from, to) => {
429
+ const handleMove = (0, import_react6.useCallback)((from, to) => {
610
430
  if (!options) {
611
431
  return;
612
432
  }
@@ -621,10 +441,10 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
621
441
  type,
622
442
  onValueChange
623
443
  ]);
624
- const handleClick = (0, import_react7.useCallback)((id) => {
444
+ const handleClick = (0, import_react6.useCallback)((id) => {
625
445
  setSelectedId((current) => current === id ? null : id);
626
446
  }, []);
627
- const handleTitleChange = (0, import_react7.useCallback)((id) => (e) => {
447
+ const handleTitleChange = (0, import_react6.useCallback)((id) => (e) => {
628
448
  const newOptions = options?.map((o) => o.id === id ? {
629
449
  ...o,
630
450
  title: e.target.value
@@ -635,12 +455,12 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
635
455
  type,
636
456
  onValueChange
637
457
  ]);
638
- const handleKeyDown = (0, import_react7.useCallback)((e) => {
458
+ const handleKeyDown = (0, import_react6.useCallback)((e) => {
639
459
  if (e.key === "Enter") {
640
460
  setSelectedId(null);
641
461
  }
642
462
  }, []);
643
- const handleColorChange = (0, import_react7.useCallback)((id) => (hue) => {
463
+ const handleColorChange = (0, import_react6.useCallback)((id) => (hue) => {
644
464
  const newOptions = options?.map((o) => o.id === id ? {
645
465
  ...o,
646
466
  color: hue
@@ -651,7 +471,7 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
651
471
  type,
652
472
  onValueChange
653
473
  ]);
654
- (0, import_react7.useEffect)(() => {
474
+ (0, import_react6.useEffect)(() => {
655
475
  if (selected && isNewOption && inputRef.current) {
656
476
  inputRef.current.focus();
657
477
  setIsNewOption(false);
@@ -660,43 +480,43 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
660
480
  selected,
661
481
  isNewOption
662
482
  ]);
663
- return /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Input.Root, {
483
+ return /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Root, {
664
484
  validationValence: status
665
- }, /* @__PURE__ */ import_react7.default.createElement(InputHeader, {
485
+ }, /* @__PURE__ */ import_react6.default.createElement(InputHeader, {
666
486
  error
667
- }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Input.Label, null, label)), /* @__PURE__ */ import_react7.default.createElement("div", {
487
+ }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Label, null, label)), /* @__PURE__ */ import_react6.default.createElement("div", {
668
488
  role: "none"
669
- }, options && /* @__PURE__ */ import_react7.default.createElement(import_react_ui_list.List.Root, {
489
+ }, options && /* @__PURE__ */ import_react6.default.createElement(import_react_ui_list.List.Root, {
670
490
  items: options,
671
491
  isItem: (item) => true,
672
492
  onMove: handleMove
673
- }, ({ items }) => /* @__PURE__ */ import_react7.default.createElement("div", {
493
+ }, ({ items }) => /* @__PURE__ */ import_react6.default.createElement("div", {
674
494
  role: "list",
675
495
  className: "w-full overflow-auto"
676
- }, items?.map((item) => /* @__PURE__ */ import_react7.default.createElement("div", {
496
+ }, items?.map((item) => /* @__PURE__ */ import_react6.default.createElement("div", {
677
497
  key: item.id
678
- }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui_list.List.Item, {
498
+ }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui_list.List.Item, {
679
499
  role: "button",
680
500
  item,
681
501
  classNames: (0, import_react_ui_theme3.mx)("p-1 plb-2", "flex flex-col", "cursor-pointer", "hover:bg-hoverOverlay"),
682
502
  "aria-expanded": selected === item.id
683
- }, /* @__PURE__ */ import_react7.default.createElement("div", {
503
+ }, /* @__PURE__ */ import_react6.default.createElement("div", {
684
504
  className: "flex items-center"
685
- }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui_list.List.ItemDragHandle, null), /* @__PURE__ */ import_react7.default.createElement(import_react_ui_list.List.ItemTitle, {
505
+ }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui_list.List.ItemDragHandle, null), /* @__PURE__ */ import_react6.default.createElement(import_react_ui_list.List.ItemTitle, {
686
506
  onClick: () => handleClick(item.id),
687
507
  classNames: "flex-1"
688
- }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Tag, {
508
+ }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Tag, {
689
509
  palette: item.color
690
- }, item.title || "\u200B")), /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Icon, {
510
+ }, item.title || "\u200B")), /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Icon, {
691
511
  icon: selected === item.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
692
512
  onClick: () => handleClick(item.id)
693
- })), selected === item.id && /* @__PURE__ */ import_react7.default.createElement("div", {
513
+ })), selected === item.id && /* @__PURE__ */ import_react6.default.createElement("div", {
694
514
  className: "mis-4 mbs-2 flex flex-col gap-1"
695
- }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Input.Label, {
515
+ }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Label, {
696
516
  classNames: "text-xs"
697
- }, t("select option label")), /* @__PURE__ */ import_react7.default.createElement("div", {
517
+ }, t("select option label")), /* @__PURE__ */ import_react6.default.createElement("div", {
698
518
  className: "flex flex-row items-center gap-1"
699
- }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Input.TextInput, {
519
+ }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.TextInput, {
700
520
  placeholder: t("select option label placeholder"),
701
521
  ref: selected === item.id ? inputRef : void 0,
702
522
  value: item.title,
@@ -704,173 +524,437 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
704
524
  onKeyDown: handleKeyDown,
705
525
  classNames: "flex-1",
706
526
  "data-no-submit": true
707
- }), /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Toolbar.Root, {
527
+ }), /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Toolbar.Root, {
708
528
  classNames: "p-0 m-0 !is-auto"
709
- }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui_pickers.HuePicker, {
529
+ }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui_pickers.HuePicker, {
710
530
  value: item.color,
711
- onChange: handleColorChange(item.id)
712
- })), /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.IconButton, {
531
+ onChange: handleColorChange(item.id),
532
+ rootVariant: "toolbar-button"
533
+ })), /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.IconButton, {
713
534
  icon: "ph--trash--fill",
714
535
  iconOnly: true,
715
536
  label: t("select option delete"),
716
537
  onClick: () => handleDelete(item.id)
717
- })))))), /* @__PURE__ */ import_react7.default.createElement("div", {
538
+ })))))), /* @__PURE__ */ import_react6.default.createElement("div", {
718
539
  role: "listitem"
719
- }, /* @__PURE__ */ import_react7.default.createElement("div", {
540
+ }, /* @__PURE__ */ import_react6.default.createElement("div", {
720
541
  role: "button",
721
542
  className: (0, import_react_ui_theme3.mx)("p-1 plb-2", "flex flex-col", "cursor-pointer", "hover:bg-hoverOverlay"),
722
543
  onClick: handleAdd
723
- }, /* @__PURE__ */ import_react7.default.createElement("div", {
544
+ }, /* @__PURE__ */ import_react6.default.createElement("div", {
724
545
  className: "flex items-center gap-1"
725
- }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Icon, {
546
+ }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Icon, {
726
547
  icon: "ph--plus--regular"
727
- }), /* @__PURE__ */ import_react7.default.createElement("span", {
548
+ }), /* @__PURE__ */ import_react6.default.createElement("span", {
728
549
  className: "text-sm"
729
550
  }, t("select option add")))))))));
730
551
  };
731
- var gridCols = [
732
- "grid-cols-1",
733
- "grid-cols-2",
734
- "grid-cols-3",
735
- "grid-cols-4"
736
- ];
737
- var TupleInput = ({ binding, type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
738
- const { status, error } = getStatus();
739
- const values = getValue3() ?? {};
740
- return /* @__PURE__ */ import_react8.default.createElement(import_react_ui6.Input.Root, {
741
- validationValence: status
742
- }, /* @__PURE__ */ import_react8.default.createElement(InputHeader, {
743
- error
744
- }, /* @__PURE__ */ import_react8.default.createElement(import_react_ui6.Input.Label, null, label)), /* @__PURE__ */ import_react8.default.createElement("div", {
745
- className: (0, import_react_ui_theme4.mx)("grid gap-2", gridCols[binding.length - 1])
746
- }, binding.map((prop) => /* @__PURE__ */ import_react8.default.createElement(import_react_ui6.Input.TextInput, {
747
- key: prop,
748
- type: "number",
749
- disabled,
750
- value: values[prop],
751
- onChange: (event) => onValueChange(type, {
752
- ...values,
753
- [prop]: (0, import_util2.safeParseFloat)(event.target.value, 0)
754
- }),
755
- onBlur
756
- }))));
552
+ var gridCols = [
553
+ "grid-cols-1",
554
+ "grid-cols-2",
555
+ "grid-cols-3",
556
+ "grid-cols-4"
557
+ ];
558
+ var TupleInput = ({ binding, type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
559
+ const { status, error } = getStatus();
560
+ const values = getValue3() ?? {};
561
+ return /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Input.Root, {
562
+ validationValence: status
563
+ }, /* @__PURE__ */ import_react7.default.createElement(InputHeader, {
564
+ error
565
+ }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Input.Label, null, label)), /* @__PURE__ */ import_react7.default.createElement("div", {
566
+ className: (0, import_react_ui_theme4.mx)("grid gap-2", gridCols[binding.length - 1])
567
+ }, binding.map((prop) => /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Input.TextInput, {
568
+ key: prop,
569
+ type: "number",
570
+ disabled,
571
+ value: values[prop],
572
+ onChange: (event) => onValueChange(type, {
573
+ ...values,
574
+ [prop]: (0, import_util2.safeParseFloat)(event.target.value, 0)
575
+ }),
576
+ onBlur
577
+ }))));
578
+ };
579
+ var TextInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
580
+ const { status, error } = getStatus();
581
+ return /* @__PURE__ */ import_react8.default.createElement(import_react_ui8.Input.Root, {
582
+ validationValence: status
583
+ }, !inputOnly && /* @__PURE__ */ import_react8.default.createElement(InputHeader, {
584
+ error
585
+ }, /* @__PURE__ */ import_react8.default.createElement(import_react_ui8.Input.Label, null, label)), /* @__PURE__ */ import_react8.default.createElement(import_react_ui8.Input.TextInput, {
586
+ disabled,
587
+ placeholder,
588
+ value: getValue3() ?? "",
589
+ onChange: (event) => onValueChange(type, event.target.value),
590
+ onBlur
591
+ }), inputOnly && /* @__PURE__ */ import_react8.default.createElement(import_react_ui8.Input.Validation, null, error));
592
+ };
593
+ var NumberInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
594
+ const { status, error } = getStatus();
595
+ return /* @__PURE__ */ import_react8.default.createElement(import_react_ui8.Input.Root, {
596
+ validationValence: status
597
+ }, !inputOnly && /* @__PURE__ */ import_react8.default.createElement(InputHeader, {
598
+ error
599
+ }, /* @__PURE__ */ import_react8.default.createElement(import_react_ui8.Input.Label, null, label)), /* @__PURE__ */ import_react8.default.createElement(import_react_ui8.Input.TextInput, {
600
+ type: "number",
601
+ disabled,
602
+ placeholder,
603
+ value: getValue3() ?? 0,
604
+ onChange: (event) => onValueChange(type, event.target.value),
605
+ onBlur
606
+ }), inputOnly && /* @__PURE__ */ import_react8.default.createElement(import_react_ui8.Input.DescriptionAndValidation, null, error));
607
+ };
608
+ var BooleanInput = ({ type, label, inputOnly, getStatus, getValue: getValue3, onValueChange }) => {
609
+ const { status, error } = getStatus();
610
+ const checked = Boolean(getValue3());
611
+ return /* @__PURE__ */ import_react8.default.createElement(import_react_ui8.Input.Root, {
612
+ validationValence: status
613
+ }, !inputOnly && /* @__PURE__ */ import_react8.default.createElement(InputHeader, {
614
+ error
615
+ }, /* @__PURE__ */ import_react8.default.createElement(import_react_ui8.Input.Label, null, label)), /* @__PURE__ */ import_react8.default.createElement(import_react_ui8.Input.Switch, {
616
+ checked,
617
+ onCheckedChange: (value) => onValueChange(type, value)
618
+ }), inputOnly && /* @__PURE__ */ import_react8.default.createElement(import_react_ui8.Input.DescriptionAndValidation, null, error));
619
+ };
620
+ var SelectInput = ({ type, label, inputOnly, disabled, placeholder, options, getStatus, getValue: getValue3, onValueChange }) => {
621
+ const { status, error } = getStatus();
622
+ return /* @__PURE__ */ import_react8.default.createElement(import_react_ui8.Input.Root, {
623
+ validationValence: status
624
+ }, !inputOnly && /* @__PURE__ */ import_react8.default.createElement(InputHeader, {
625
+ error
626
+ }, /* @__PURE__ */ import_react8.default.createElement(import_react_ui8.Input.Label, null, label)), /* @__PURE__ */ import_react8.default.createElement(import_react_ui8.Select.Root, {
627
+ value: getValue3(),
628
+ onValueChange: (value) => onValueChange(type, value)
629
+ }, /* @__PURE__ */ import_react8.default.createElement(import_react_ui8.Select.TriggerButton, {
630
+ classNames: "is-full",
631
+ disabled,
632
+ placeholder
633
+ }), /* @__PURE__ */ import_react8.default.createElement(import_react_ui8.Select.Portal, null, /* @__PURE__ */ import_react8.default.createElement(import_react_ui8.Select.Content, null, /* @__PURE__ */ import_react8.default.createElement(import_react_ui8.Select.Viewport, null, options?.map(({ value, label: label2 }) => (
634
+ // NOTE: Numeric values are converted to and from strings.
635
+ /* @__PURE__ */ import_react8.default.createElement(import_react_ui8.Select.Option, {
636
+ key: String(value),
637
+ value: String(value)
638
+ }, label2 ?? String(value))
639
+ )))))), inputOnly && /* @__PURE__ */ import_react8.default.createElement(import_react_ui8.Input.DescriptionAndValidation, null, error));
640
+ };
641
+ var MarkdownInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
642
+ const { status, error } = getStatus();
643
+ const textareaRef = (0, import_react8.useRef)(null);
644
+ const adjustHeight = (0, import_react8.useCallback)(() => {
645
+ const textarea = textareaRef.current;
646
+ if (textarea) {
647
+ textarea.style.blockSize = "auto";
648
+ textarea.style.blockSize = `${textarea.scrollHeight + 2}px`;
649
+ }
650
+ }, []);
651
+ (0, import_react8.useEffect)(() => {
652
+ adjustHeight();
653
+ }, [
654
+ adjustHeight
655
+ ]);
656
+ (0, import_react8.useEffect)(() => {
657
+ adjustHeight();
658
+ }, [
659
+ getValue3(),
660
+ adjustHeight
661
+ ]);
662
+ return /* @__PURE__ */ import_react8.default.createElement(import_react_ui8.Input.Root, {
663
+ validationValence: status
664
+ }, !inputOnly && /* @__PURE__ */ import_react8.default.createElement(InputHeader, {
665
+ error
666
+ }, /* @__PURE__ */ import_react8.default.createElement(import_react_ui8.Input.Label, null, label)), /* @__PURE__ */ import_react8.default.createElement(import_react_ui8.Input.TextArea, {
667
+ ref: textareaRef,
668
+ disabled,
669
+ placeholder,
670
+ value: getValue3() ?? "",
671
+ classNames: "min-bs-auto max-h-40 overflow-auto",
672
+ onChange: (event) => onValueChange(type, event.target.value),
673
+ onBlur,
674
+ style: {
675
+ resize: "none"
676
+ },
677
+ spellCheck: false
678
+ }), inputOnly && /* @__PURE__ */ import_react8.default.createElement(import_react_ui8.Input.Validation, null, error));
679
+ };
680
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/hooks/useForm.ts";
681
+ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, onSave }) => {
682
+ (0, import_invariant.invariant)(import_effect2.SchemaAST.isTypeLiteral(schema.ast), void 0, {
683
+ F: __dxlog_file,
684
+ L: 93,
685
+ S: void 0,
686
+ A: [
687
+ "AST.isTypeLiteral(schema.ast)",
688
+ ""
689
+ ]
690
+ });
691
+ const [values, setValues] = (0, import_react12.useState)(initialValues);
692
+ (0, import_react12.useEffect)(() => {
693
+ setValues(initialValues);
694
+ }, [
695
+ initialValues
696
+ ]);
697
+ const [touched, setTouched] = (0, import_react12.useState)(createKeySet(initialValues, false));
698
+ const [changed, setChanged] = (0, import_react12.useState)(createKeySet(initialValues, false));
699
+ const [errors, setErrors] = (0, import_react12.useState)({});
700
+ const [saving, setSaving] = (0, import_react12.useState)(false);
701
+ const validate = (0, import_react12.useCallback)((values2) => {
702
+ let errors2 = (0, import_schema2.validateSchema)(schema, values2) ?? [];
703
+ if (errors2.length === 0 && onValidate) {
704
+ const validatedValues = values2;
705
+ errors2 = onValidate(validatedValues) ?? [];
706
+ }
707
+ setErrors(flatMap(errors2));
708
+ const valid = errors2.length === 0;
709
+ return valid;
710
+ }, [
711
+ schema,
712
+ onValidate
713
+ ]);
714
+ const [schemaDirty, setSchemaDirty] = (0, import_react12.useState)(false);
715
+ (0, import_react12.useEffect)(() => setSchemaDirty(true), [
716
+ schema
717
+ ]);
718
+ (0, import_react12.useEffect)(() => {
719
+ if (schemaDirty) {
720
+ validate(values);
721
+ setSchemaDirty(false);
722
+ }
723
+ }, [
724
+ values,
725
+ schemaDirty
726
+ ]);
727
+ const formIsValid = (0, import_react12.useMemo)(() => {
728
+ return Object.keys(errors).length === 0;
729
+ }, [
730
+ errors
731
+ ]);
732
+ const canSave = (0, import_react12.useMemo)(() => !saving && // Check if any error paths that are touched have errors.
733
+ !Object.entries(touched).some(([path, isTouched]) => isTouched && Object.keys(errors).some((errorPath) => errorPath === path || errorPath.startsWith(`${path}.`) || errorPath.startsWith(`${path}[`))), [
734
+ touched,
735
+ errors,
736
+ saving
737
+ ]);
738
+ const handleSave = (0, import_react12.useCallback)(async () => {
739
+ if (validate(values)) {
740
+ setSaving(true);
741
+ try {
742
+ await onSave?.(values, {
743
+ changed
744
+ });
745
+ } finally {
746
+ setSaving(false);
747
+ }
748
+ }
749
+ }, [
750
+ values,
751
+ validate,
752
+ onSave,
753
+ changed
754
+ ]);
755
+ const getStatus = (0, import_react12.useCallback)((path) => {
756
+ const jsonPath = Array.isArray(path) ? (0, import_effect3.createJsonPath)(path) : path;
757
+ const matchingError = Object.entries(errors).find(([errorPath]) => errorPath === jsonPath || errorPath.startsWith(`${jsonPath}.`) || errorPath.startsWith(`${jsonPath}[`));
758
+ const isTouched = touched[jsonPath];
759
+ if (!isTouched) {
760
+ return {
761
+ status: void 0,
762
+ error: void 0
763
+ };
764
+ }
765
+ return {
766
+ status: matchingError ? "error" : void 0,
767
+ error: matchingError ? matchingError[1] : void 0
768
+ };
769
+ }, [
770
+ errors,
771
+ touched
772
+ ]);
773
+ const getFormValue = (0, import_react12.useCallback)((path) => {
774
+ return (0, import_echo_schema4.getValue)(values, (0, import_effect3.createJsonPath)(path));
775
+ }, [
776
+ values
777
+ ]);
778
+ const onValueChange = (0, import_react12.useCallback)((path, type, value) => {
779
+ const jsonPath = (0, import_effect3.createJsonPath)(path);
780
+ let parsedValue = value;
781
+ try {
782
+ if (type === "number") {
783
+ parsedValue = parseFloat(value) || 0;
784
+ }
785
+ } catch (err) {
786
+ import_log2.log.catch(err, void 0, {
787
+ F: __dxlog_file,
788
+ L: 212,
789
+ S: void 0,
790
+ C: (f, a) => f(...a)
791
+ });
792
+ parsedValue = void 0;
793
+ }
794
+ const newValues = {
795
+ ...(0, import_echo_schema4.setValue)(values, jsonPath, parsedValue)
796
+ };
797
+ setValues(newValues);
798
+ setChanged((prev) => ({
799
+ ...prev,
800
+ [jsonPath]: true
801
+ }));
802
+ onValuesChanged?.(newValues);
803
+ const isValid = validate(newValues);
804
+ if (isValid && onValid) {
805
+ onValid(newValues, {
806
+ changed
807
+ });
808
+ }
809
+ }, [
810
+ values,
811
+ onValuesChanged,
812
+ validate,
813
+ onValid,
814
+ changed
815
+ ]);
816
+ const onTouched = (0, import_react12.useCallback)((path) => {
817
+ const jsonPath = (0, import_effect3.createJsonPath)(path);
818
+ setTouched((touched2) => ({
819
+ ...touched2,
820
+ [jsonPath]: true
821
+ }));
822
+ validate(values);
823
+ }, [
824
+ validate,
825
+ values
826
+ ]);
827
+ return (0, import_react12.useMemo)(() => ({
828
+ // State.
829
+ values,
830
+ errors,
831
+ touched,
832
+ changed,
833
+ canSave,
834
+ formIsValid,
835
+ // Actions.
836
+ handleSave,
837
+ // Field utils.
838
+ getStatus,
839
+ getValue: getFormValue,
840
+ onValueChange,
841
+ onTouched
842
+ }), [
843
+ values,
844
+ errors,
845
+ touched,
846
+ changed,
847
+ canSave,
848
+ formIsValid,
849
+ handleSave,
850
+ getStatus,
851
+ getFormValue,
852
+ onValueChange,
853
+ onTouched
854
+ ]);
855
+ };
856
+ var createKeySet = (obj, value) => {
857
+ (0, import_invariant.invariant)(obj, void 0, {
858
+ F: __dxlog_file,
859
+ L: 274,
860
+ S: void 0,
861
+ A: [
862
+ "obj",
863
+ ""
864
+ ]
865
+ });
866
+ return Object.keys(obj).reduce((acc, key) => ({
867
+ ...acc,
868
+ [key]: value
869
+ }), {});
757
870
  };
758
- var TextInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
759
- const { status, error } = getStatus();
760
- return /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Root, {
761
- validationValence: status
762
- }, !inputOnly && /* @__PURE__ */ import_react9.default.createElement(InputHeader, {
763
- error
764
- }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Label, null, label)), /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.TextInput, {
765
- disabled,
766
- placeholder,
767
- value: getValue3() ?? "",
768
- onChange: (event) => onValueChange(type, event.target.value),
769
- onBlur
770
- }), inputOnly && /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Validation, null, error));
871
+ var flatMap = (errors) => {
872
+ return errors.reduce((result, { path, message }) => {
873
+ const jsonPath = (0, import_effect3.fromEffectValidationPath)(path);
874
+ if (!(jsonPath in result)) {
875
+ result[jsonPath] = message;
876
+ }
877
+ return result;
878
+ }, {});
771
879
  };
772
- var NumberInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
773
- const { status, error } = getStatus();
774
- return /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Root, {
775
- validationValence: status
776
- }, !inputOnly && /* @__PURE__ */ import_react9.default.createElement(InputHeader, {
777
- error
778
- }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Label, null, label)), /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.TextInput, {
779
- type: "number",
780
- disabled,
781
- placeholder,
782
- value: getValue3() ?? 0,
783
- onChange: (event) => onValueChange(type, event.target.value),
784
- onBlur
785
- }), inputOnly && /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.DescriptionAndValidation, null, error));
880
+ var FormContext = /* @__PURE__ */ (0, import_react11.createContext)(void 0);
881
+ var useFormContext = () => {
882
+ return (0, import_react11.useContext)(FormContext) ?? (0, import_debug.raise)(new Error("Missing FormContext"));
786
883
  };
787
- var BooleanInput = ({ type, label, inputOnly, getStatus, getValue: getValue3, onValueChange }) => {
788
- const { status, error } = getStatus();
789
- const checked = Boolean(getValue3());
790
- return /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Root, {
791
- validationValence: status
792
- }, !inputOnly && /* @__PURE__ */ import_react9.default.createElement(InputHeader, {
793
- error
794
- }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Label, null, label)), /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Switch, {
795
- checked,
796
- onCheckedChange: (value) => onValueChange(type, value)
797
- }), inputOnly && /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.DescriptionAndValidation, null, error));
884
+ var useFormValues = (path = []) => {
885
+ const { values: formValues } = useFormContext();
886
+ const jsonPath = (0, import_effect.createJsonPath)(path);
887
+ return (0, import_echo_schema3.getValue)(formValues, jsonPath);
798
888
  };
799
- var SelectInput = ({ type, label, inputOnly, disabled, placeholder, options, getStatus, getValue: getValue3, onValueChange }) => {
800
- const { status, error } = getStatus();
801
- return /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Root, {
802
- validationValence: status
803
- }, !inputOnly && /* @__PURE__ */ import_react9.default.createElement(InputHeader, {
804
- error
805
- }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Label, null, label)), /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Select.Root, {
806
- value: getValue3(),
807
- onValueChange: (value) => onValueChange(type, value)
808
- }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Select.TriggerButton, {
809
- classNames: "is-full",
810
- disabled,
811
- placeholder
812
- }), /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Select.Portal, null, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Select.Content, null, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Select.Viewport, null, options?.map(({ value, label: label2 }) => (
813
- // NOTE: Numeric values are converted to and from strings.
814
- /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Select.Option, {
815
- key: String(value),
816
- value: String(value)
817
- }, label2 ?? String(value))
818
- )))))), inputOnly && /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.DescriptionAndValidation, null, error));
889
+ var useInputProps = (path = []) => {
890
+ const { getStatus, getValue: getFormValue, onValueChange, onTouched } = useFormContext();
891
+ const stablePath = (0, import_react11.useMemo)(() => path, [
892
+ Array.isArray(path) ? path.join(".") : path
893
+ ]);
894
+ return (0, import_react11.useMemo)(() => ({
895
+ getStatus: () => getStatus(stablePath),
896
+ getValue: () => getFormValue(stablePath),
897
+ onValueChange: (type, value) => onValueChange(stablePath, type, value),
898
+ onBlur: () => onTouched(stablePath)
899
+ }), [
900
+ getStatus,
901
+ getFormValue,
902
+ onValueChange,
903
+ onTouched,
904
+ stablePath
905
+ ]);
819
906
  };
820
- var MarkdownInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
821
- const { status, error } = getStatus();
822
- const textareaRef = (0, import_react9.useRef)(null);
823
- const adjustHeight = (0, import_react9.useCallback)(() => {
824
- const textarea = textareaRef.current;
825
- if (textarea) {
826
- textarea.style.blockSize = "auto";
827
- textarea.style.blockSize = `${textarea.scrollHeight + 2}px`;
907
+ var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
908
+ const form = useForm(formOptions);
909
+ (0, import_react11.useEffect)(() => {
910
+ if (!formRef?.current) {
911
+ return;
828
912
  }
829
- }, []);
830
- (0, import_react9.useEffect)(() => {
831
- adjustHeight();
832
- }, [
833
- adjustHeight
834
- ]);
835
- (0, import_react9.useEffect)(() => {
836
- adjustHeight();
913
+ const handleKeyDown = (event) => {
914
+ const keyIsEnter = event.key === "Enter";
915
+ const modifierUsed = event.ctrlKey || event.altKey || event.metaKey || event.shiftKey;
916
+ const inputIsTextarea = event.target.tagName.toLowerCase() === "textarea";
917
+ const inputOptOut = event.target.hasAttribute("data-no-submit");
918
+ const shouldSubmitRegularInput = !inputIsTextarea && keyIsEnter && !modifierUsed;
919
+ const shouldSubmitTextarea = inputIsTextarea && keyIsEnter && event.metaKey;
920
+ if ((shouldSubmitRegularInput || shouldSubmitTextarea) && !inputOptOut) {
921
+ if (!autoSave && form.canSave) {
922
+ form.handleSave();
923
+ }
924
+ if (autoSave && form.formIsValid) {
925
+ event.target.blur();
926
+ }
927
+ }
928
+ };
929
+ const formElement = formRef.current;
930
+ formElement.addEventListener("keydown", handleKeyDown);
931
+ return () => formElement.removeEventListener("keydown", handleKeyDown);
837
932
  }, [
838
- getValue3(),
839
- adjustHeight
933
+ formRef,
934
+ form.canSave,
935
+ form.formIsValid,
936
+ form.handleSave,
937
+ autoSave
840
938
  ]);
841
- return /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Root, {
842
- validationValence: status
843
- }, !inputOnly && /* @__PURE__ */ import_react9.default.createElement(InputHeader, {
844
- error
845
- }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Label, null, label)), /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.TextArea, {
846
- ref: textareaRef,
847
- disabled,
848
- placeholder,
849
- value: getValue3() ?? "",
850
- classNames: "min-bs-auto max-h-40 overflow-auto",
851
- onChange: (event) => onValueChange(type, event.target.value),
852
- onBlur,
853
- style: {
854
- resize: "none"
855
- },
856
- spellCheck: false
857
- }), inputOnly && /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Validation, null, error));
939
+ return /* @__PURE__ */ import_react11.default.createElement(FormContext.Provider, {
940
+ value: form
941
+ }, children);
858
942
  };
859
943
  var FormActions = ({ onCancel, readonly }) => {
860
- const { t } = (0, import_react_ui8.useTranslation)(translationKey);
944
+ const { t } = (0, import_react_ui9.useTranslation)(translationKey);
861
945
  const { canSave, handleSave } = useFormContext();
862
- return /* @__PURE__ */ import_react11.default.createElement("div", {
946
+ return /* @__PURE__ */ import_react10.default.createElement("div", {
863
947
  role: "none",
864
948
  className: "mt-2 flex justify-center"
865
- }, /* @__PURE__ */ import_react11.default.createElement("div", {
949
+ }, /* @__PURE__ */ import_react10.default.createElement("div", {
866
950
  role: "none",
867
951
  className: (0, import_react_ui_theme6.mx)(onCancel && !readonly && "grid grid-cols-2 gap-2")
868
- }, onCancel && !readonly && /* @__PURE__ */ import_react11.default.createElement(import_react_ui8.IconButton, {
952
+ }, onCancel && !readonly && /* @__PURE__ */ import_react10.default.createElement(import_react_ui9.IconButton, {
869
953
  "data-testid": "cancel-button",
870
954
  icon: "ph--x--regular",
871
955
  label: t("button cancel"),
872
956
  onClick: onCancel
873
- }), handleSave && /* @__PURE__ */ import_react11.default.createElement(import_react_ui8.IconButton, {
957
+ }), handleSave && /* @__PURE__ */ import_react10.default.createElement(import_react_ui9.IconButton, {
874
958
  type: "submit",
875
959
  "data-testid": "save-button",
876
960
  disabled: !canSave,
@@ -882,7 +966,7 @@ var FormActions = ({ onCancel, readonly }) => {
882
966
  var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/Form/ArrayField.tsx";
883
967
  var padding = "px-2";
884
968
  var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponent }) => {
885
- const { t } = (0, import_react_ui9.useTranslation)(translationKey);
969
+ const { t } = (0, import_react_ui10.useTranslation)(translationKey);
886
970
  const { ast, name, type, title } = property;
887
971
  const values = useFormValues(path ?? []);
888
972
  (0, import_invariant2.invariant)(Array.isArray(values), `Values at path ${path?.join(".")} must be an array.`, {
@@ -908,7 +992,7 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
908
992
  prop.defaultValue
909
993
  ]));
910
994
  };
911
- const newValue = (0, import_react13.useMemo)(() => {
995
+ const newValue = (0, import_react14.useMemo)(() => {
912
996
  if (type === "object" && elementType) {
913
997
  return getDefaultObjectValue(elementType);
914
998
  } else {
@@ -918,7 +1002,7 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
918
1002
  type,
919
1003
  elementType
920
1004
  ]);
921
- const handleAdd = (0, import_react13.useCallback)(() => {
1005
+ const handleAdd = (0, import_react14.useCallback)(() => {
922
1006
  inputProps.onValueChange(type, [
923
1007
  ...values,
924
1008
  newValue
@@ -930,7 +1014,7 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
930
1014
  newValue,
931
1015
  values
932
1016
  ]);
933
- const handleRemove = (0, import_react13.useCallback)((index) => {
1017
+ const handleRemove = (0, import_react14.useCallback)((index) => {
934
1018
  const newValues = values.filter((_, i) => i !== index);
935
1019
  inputProps.onValueChange(type, newValues);
936
1020
  }, [
@@ -941,20 +1025,20 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
941
1025
  if (!elementType) {
942
1026
  return null;
943
1027
  }
944
- return /* @__PURE__ */ import_react13.default.createElement("div", {
1028
+ return /* @__PURE__ */ import_react14.default.createElement("div", {
945
1029
  role: "none",
946
1030
  className: (0, import_react_ui_theme8.mx)(padding)
947
- }, /* @__PURE__ */ import_react13.default.createElement(InputHeader, null, label), /* @__PURE__ */ import_react13.default.createElement("div", {
1031
+ }, /* @__PURE__ */ import_react14.default.createElement(InputHeader, null, label), /* @__PURE__ */ import_react14.default.createElement("div", {
948
1032
  role: "none",
949
1033
  className: "flex flex-col gap-1"
950
- }, values.map((_value, index) => /* @__PURE__ */ import_react13.default.createElement("div", {
1034
+ }, values.map((_value, index) => /* @__PURE__ */ import_react14.default.createElement("div", {
951
1035
  key: index,
952
1036
  role: "none",
953
1037
  className: "flex items-center gap-1"
954
- }, /* @__PURE__ */ import_react13.default.createElement("div", {
1038
+ }, /* @__PURE__ */ import_react14.default.createElement("div", {
955
1039
  role: "none",
956
1040
  className: "flex-1"
957
- }, /* @__PURE__ */ import_react13.default.createElement(FormField, {
1041
+ }, /* @__PURE__ */ import_react14.default.createElement(FormField, {
958
1042
  property: {
959
1043
  ...property,
960
1044
  array: false,
@@ -968,15 +1052,15 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
968
1052
  inline: true,
969
1053
  Custom,
970
1054
  lookupComponent
971
- })), /* @__PURE__ */ import_react13.default.createElement(import_react_ui9.IconButton, {
1055
+ })), /* @__PURE__ */ import_react14.default.createElement(import_react_ui10.IconButton, {
972
1056
  icon: "ph--trash--regular",
973
1057
  iconOnly: true,
974
1058
  label: t("button remove"),
975
1059
  onClick: () => handleRemove(index)
976
- })))), /* @__PURE__ */ import_react13.default.createElement("div", {
1060
+ })))), /* @__PURE__ */ import_react14.default.createElement("div", {
977
1061
  role: "none",
978
1062
  className: "flex justify-between items-center plb-1"
979
- }, /* @__PURE__ */ import_react13.default.createElement(import_react_ui9.IconButton, {
1063
+ }, /* @__PURE__ */ import_react14.default.createElement(import_react_ui10.IconButton, {
980
1064
  icon: "ph--plus--regular",
981
1065
  iconOnly: true,
982
1066
  label: t("button add"),
@@ -1002,11 +1086,11 @@ var getInputComponent = (type, format) => {
1002
1086
  var FormField = ({ property, path, readonly, inline, lookupComponent, Custom }) => {
1003
1087
  const inputProps = useInputProps(path);
1004
1088
  const { ast, name, type, format, title, description, options, examples, array } = property;
1005
- const label = (0, import_react12.useMemo)(() => title ?? (0, import_effect4.pipe)(name, import_String.capitalize), [
1089
+ const label = (0, import_react13.useMemo)(() => title ?? (0, import_effect4.pipe)(name, import_String.capitalize), [
1006
1090
  title,
1007
1091
  name
1008
1092
  ]);
1009
- const placeholder = (0, import_react12.useMemo)(() => examples?.length ? `Example: "${examples[0]}"` : description, [
1093
+ const placeholder = (0, import_react13.useMemo)(() => examples?.length ? `Example: "${examples[0]}"` : description, [
1010
1094
  examples,
1011
1095
  description
1012
1096
  ]);
@@ -1023,14 +1107,14 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
1023
1107
  }
1024
1108
  });
1025
1109
  if (FoundComponent) {
1026
- return /* @__PURE__ */ import_react12.default.createElement("div", {
1110
+ return /* @__PURE__ */ import_react13.default.createElement("div", {
1027
1111
  role: "none"
1028
1112
  }, FoundComponent);
1029
1113
  }
1030
1114
  const jsonPath = (0, import_effect5.createJsonPath)(path ?? []);
1031
1115
  const CustomComponent = Custom?.[jsonPath];
1032
1116
  if (CustomComponent) {
1033
- return /* @__PURE__ */ import_react12.default.createElement(CustomComponent, {
1117
+ return /* @__PURE__ */ import_react13.default.createElement(CustomComponent, {
1034
1118
  type,
1035
1119
  format,
1036
1120
  label,
@@ -1041,7 +1125,7 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
1041
1125
  });
1042
1126
  }
1043
1127
  if (array) {
1044
- return /* @__PURE__ */ import_react12.default.createElement(ArrayField, {
1128
+ return /* @__PURE__ */ import_react13.default.createElement(ArrayField, {
1045
1129
  property,
1046
1130
  path,
1047
1131
  inputProps,
@@ -1051,9 +1135,9 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
1051
1135
  }
1052
1136
  const InputComponent = getInputComponent(type, format);
1053
1137
  if (InputComponent) {
1054
- return /* @__PURE__ */ import_react12.default.createElement("div", {
1138
+ return /* @__PURE__ */ import_react13.default.createElement("div", {
1055
1139
  role: "none"
1056
- }, /* @__PURE__ */ import_react12.default.createElement(InputComponent, {
1140
+ }, /* @__PURE__ */ import_react13.default.createElement(InputComponent, {
1057
1141
  type,
1058
1142
  format,
1059
1143
  label,
@@ -1064,9 +1148,9 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
1064
1148
  }));
1065
1149
  }
1066
1150
  if (options) {
1067
- return /* @__PURE__ */ import_react12.default.createElement("div", {
1151
+ return /* @__PURE__ */ import_react13.default.createElement("div", {
1068
1152
  role: "none"
1069
- }, /* @__PURE__ */ import_react12.default.createElement(SelectInput, {
1153
+ }, /* @__PURE__ */ import_react13.default.createElement(SelectInput, {
1070
1154
  type,
1071
1155
  format,
1072
1156
  disabled: readonly,
@@ -1084,9 +1168,9 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
1084
1168
  const baseNode = (0, import_effect5.findNode)(ast, import_effect5.isDiscriminatedUnion);
1085
1169
  const typeLiteral = baseNode ? (0, import_effect5.getDiscriminatedType)(baseNode, inputProps.getValue()) : (0, import_effect5.findNode)(ast, import_echo_schema5.AST.isTypeLiteral);
1086
1170
  if (typeLiteral) {
1087
- return /* @__PURE__ */ import_react12.default.createElement("div", {
1171
+ return /* @__PURE__ */ import_react13.default.createElement("div", {
1088
1172
  role: "none"
1089
- }, !inline && /* @__PURE__ */ import_react12.default.createElement("div", null, label), /* @__PURE__ */ import_react12.default.createElement(FormFields, {
1173
+ }, !inline && /* @__PURE__ */ import_react13.default.createElement("div", null, label), /* @__PURE__ */ import_react13.default.createElement(FormFields, {
1090
1174
  schema: import_echo_schema5.S.make(typeLiteral),
1091
1175
  path,
1092
1176
  readonly,
@@ -1098,7 +1182,7 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
1098
1182
  };
1099
1183
  var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custom }) => {
1100
1184
  const values = useFormValues(path);
1101
- const properties = (0, import_react12.useMemo)(() => {
1185
+ const properties = (0, import_react13.useMemo)(() => {
1102
1186
  const props = (0, import_schema3.getSchemaProperties)(schema.ast, values);
1103
1187
  const filtered = filter ? filter(props) : props;
1104
1188
  return sort ? filtered.sort((a, b) => sort.indexOf(a.name) - sort.indexOf(b.name)) : filtered;
@@ -1108,11 +1192,11 @@ var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custo
1108
1192
  filter,
1109
1193
  sort
1110
1194
  ]);
1111
- return /* @__PURE__ */ import_react12.default.createElement("div", {
1195
+ return /* @__PURE__ */ import_react13.default.createElement("div", {
1112
1196
  role: "form",
1113
1197
  className: (0, import_react_ui_theme7.mx)("flex flex-col w-full gap-2")
1114
1198
  }, properties.map((property) => {
1115
- return /* @__PURE__ */ import_react12.default.createElement(FormField, {
1199
+ return /* @__PURE__ */ import_react13.default.createElement(FormField, {
1116
1200
  key: property.name,
1117
1201
  property,
1118
1202
  path: [
@@ -1126,12 +1210,12 @@ var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custo
1126
1210
  }).filter(import_util3.isNotFalsy));
1127
1211
  };
1128
1212
  var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, lookupComponent, Custom }) => {
1129
- const formRef = (0, import_react10.useRef)(null);
1130
- const onValid = (0, import_react10.useMemo)(() => autoSave ? onSave : void 0, [
1213
+ const formRef = (0, import_react9.useRef)(null);
1214
+ const onValid = (0, import_react9.useMemo)(() => autoSave ? onSave : void 0, [
1131
1215
  autoSave,
1132
1216
  onSave
1133
1217
  ]);
1134
- (0, import_react10.useEffect)(() => {
1218
+ (0, import_react9.useEffect)(() => {
1135
1219
  if (autoFocus && formRef.current) {
1136
1220
  const input = formRef.current.querySelector("input");
1137
1221
  if (input) {
@@ -1141,7 +1225,7 @@ var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, r
1141
1225
  }, [
1142
1226
  autoFocus
1143
1227
  ]);
1144
- return /* @__PURE__ */ import_react10.default.createElement(FormProvider, {
1228
+ return /* @__PURE__ */ import_react9.default.createElement(FormProvider, {
1145
1229
  formRef,
1146
1230
  schema,
1147
1231
  autoSave,
@@ -1150,12 +1234,12 @@ var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, r
1150
1234
  onValidate,
1151
1235
  onValid,
1152
1236
  onSave
1153
- }, /* @__PURE__ */ import_react10.default.createElement("div", {
1237
+ }, /* @__PURE__ */ import_react9.default.createElement("div", {
1154
1238
  ref: formRef,
1155
1239
  role: "none",
1156
1240
  className: (0, import_react_ui_theme5.mx)("p-2", classNames),
1157
1241
  "data-testid": testId
1158
- }, /* @__PURE__ */ import_react10.default.createElement(FormFields, {
1242
+ }, /* @__PURE__ */ import_react9.default.createElement(FormFields, {
1159
1243
  schema,
1160
1244
  path,
1161
1245
  readonly,
@@ -1163,21 +1247,21 @@ var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, r
1163
1247
  sort,
1164
1248
  lookupComponent,
1165
1249
  Custom
1166
- }), (onCancel || onSave) && !autoSave && /* @__PURE__ */ import_react10.default.createElement(FormActions, {
1250
+ }), (onCancel || onSave) && !autoSave && /* @__PURE__ */ import_react9.default.createElement(FormActions, {
1167
1251
  onCancel,
1168
1252
  readonly
1169
1253
  })));
1170
1254
  };
1171
1255
  var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
1172
1256
  var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1173
- const { t } = (0, import_react_ui2.useTranslation)(translationKey);
1174
- const [props, setProps] = (0, import_react2.useState)(projection.getFieldProjection(field.id).props);
1175
- (0, import_react2.useEffect)(() => setProps(projection.getFieldProjection(field.id).props), [
1257
+ const { t } = (0, import_react_ui3.useTranslation)(translationKey);
1258
+ const [props, setProps] = (0, import_react3.useState)(projection.getFieldProjection(field.id).props);
1259
+ (0, import_react3.useEffect)(() => setProps(projection.getFieldProjection(field.id).props), [
1176
1260
  field,
1177
1261
  projection
1178
1262
  ]);
1179
- const [schemas, setSchemas] = (0, import_react2.useState)([]);
1180
- (0, import_react2.useEffect)(() => {
1263
+ const [schemas, setSchemas] = (0, import_react3.useState)([]);
1264
+ (0, import_react3.useEffect)(() => {
1181
1265
  if (!registry) {
1182
1266
  return;
1183
1267
  }
@@ -1195,17 +1279,17 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1195
1279
  }, [
1196
1280
  registry
1197
1281
  ]);
1198
- const [referenceSchema, setReferenceSchema] = (0, import_react2.useState)();
1199
- (0, import_react2.useEffect)(() => {
1282
+ const [referenceSchema, setReferenceSchema] = (0, import_react3.useState)();
1283
+ (0, import_react3.useEffect)(() => {
1200
1284
  setReferenceSchema(schemas.find((schema) => schema.typename === props?.referenceSchema));
1201
1285
  }, [
1202
1286
  schemas,
1203
1287
  props?.referenceSchema
1204
1288
  ]);
1205
- const [{ fieldSchema }, setFieldSchema] = (0, import_react2.useState)({
1289
+ const [{ fieldSchema }, setFieldSchema] = (0, import_react3.useState)({
1206
1290
  fieldSchema: (0, import_schema.getFormatSchema)(props?.format)
1207
1291
  });
1208
- const handleValuesChanged = (0, import_react2.useCallback)((_props) => {
1292
+ const handleValuesChanged = (0, import_react3.useCallback)((_props) => {
1209
1293
  setFieldSchema((prev) => {
1210
1294
  const fieldSchema2 = (0, import_schema.getFormatSchema)(_props.format);
1211
1295
  if (prev.fieldSchema === fieldSchema2) {
@@ -1240,7 +1324,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1240
1324
  props.format,
1241
1325
  props.referenceSchema
1242
1326
  ]);
1243
- const handleValidate = (0, import_react2.useCallback)(({ property }) => {
1327
+ const handleValidate = (0, import_react3.useCallback)(({ property }) => {
1244
1328
  if (property && view.fields.find((f) => f.path === property && f.path !== field.path)) {
1245
1329
  return [
1246
1330
  {
@@ -1253,7 +1337,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1253
1337
  view.fields,
1254
1338
  field
1255
1339
  ]);
1256
- const handleSave = (0, import_react2.useCallback)((props2) => {
1340
+ const handleSave = (0, import_react3.useCallback)((props2) => {
1257
1341
  projection.setFieldProjection({
1258
1342
  field,
1259
1343
  props: props2
@@ -1264,39 +1348,39 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1264
1348
  field,
1265
1349
  onSave
1266
1350
  ]);
1267
- const handleCancel = (0, import_react2.useCallback)(() => {
1351
+ const handleCancel = (0, import_react3.useCallback)(() => {
1268
1352
  requestAnimationFrame(() => onCancel?.());
1269
1353
  onSave();
1270
1354
  }, [
1271
1355
  onSave
1272
1356
  ]);
1273
- const Custom = (0, import_react2.useMemo)(() => ({
1274
- ["format"]: (props2) => /* @__PURE__ */ import_react2.default.createElement(SelectInput, {
1357
+ const Custom = (0, import_react3.useMemo)(() => ({
1358
+ ["format"]: (props2) => /* @__PURE__ */ import_react3.default.createElement(SelectInput, {
1275
1359
  ...props2,
1276
1360
  options: import_echo_schema.FormatEnums.filter((value) => value !== import_echo_schema.FormatEnum.None).map((value) => ({
1277
1361
  value,
1278
1362
  label: t(`format ${value}`)
1279
1363
  }))
1280
1364
  }),
1281
- ["referenceSchema"]: (props2) => /* @__PURE__ */ import_react2.default.createElement(SelectInput, {
1365
+ ["referenceSchema"]: (props2) => /* @__PURE__ */ import_react3.default.createElement(SelectInput, {
1282
1366
  ...props2,
1283
1367
  options: schemas.map((schema) => ({
1284
1368
  value: schema.typename
1285
1369
  }))
1286
1370
  }),
1287
- ["referencePath"]: (props2) => /* @__PURE__ */ import_react2.default.createElement(SelectInput, {
1371
+ ["referencePath"]: (props2) => /* @__PURE__ */ import_react3.default.createElement(SelectInput, {
1288
1372
  ...props2,
1289
1373
  options: referenceSchema ? (0, import_schema.getSchemaProperties)(referenceSchema.ast).sort(import_schema.sortProperties).map((p) => ({
1290
1374
  value: p.name
1291
1375
  })) : []
1292
1376
  }),
1293
- ["options"]: (props2) => /* @__PURE__ */ import_react2.default.createElement(SelectOptionInput, props2)
1377
+ ["options"]: (props2) => /* @__PURE__ */ import_react3.default.createElement(SelectOptionInput, props2)
1294
1378
  }), [
1295
1379
  t,
1296
1380
  schemas,
1297
1381
  referenceSchema
1298
1382
  ]);
1299
- const propIsNotType = (0, import_react2.useCallback)((props2) => props2.filter((p) => p.name !== "type"), []);
1383
+ const propIsNotType = (0, import_react3.useCallback)((props2) => props2.filter((p) => p.name !== "type"), []);
1300
1384
  if (!fieldSchema) {
1301
1385
  import_log.log.warn("invalid format", {
1302
1386
  props
@@ -1308,7 +1392,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1308
1392
  });
1309
1393
  return null;
1310
1394
  }
1311
- return /* @__PURE__ */ import_react2.default.createElement(Form, {
1395
+ return /* @__PURE__ */ import_react3.default.createElement(Form, {
1312
1396
  key: field.id,
1313
1397
  autoFocus: true,
1314
1398
  values: props,
@@ -1325,6 +1409,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1325
1409
  Custom
1326
1410
  });
1327
1411
  };
1412
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx";
1328
1413
  var grid = "grid grid-cols-[32px_1fr_32px] min-bs-[2.5rem]";
1329
1414
  var ViewMetaSchema = import_echo_schema8.S.Struct({
1330
1415
  name: import_echo_schema8.S.String.annotations({
@@ -1335,13 +1420,13 @@ var ViewMetaSchema = import_echo_schema8.S.Struct({
1335
1420
  })
1336
1421
  }).pipe(import_echo_schema8.S.mutable);
1337
1422
  var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading = false, onTypenameChanged, onDelete }) => {
1338
- const { t } = (0, import_react_ui10.useTranslation)(translationKey);
1339
- const projection = (0, import_react14.useMemo)(() => new import_schema5.ViewProjection(schema, view), [
1423
+ const { t } = (0, import_react_ui11.useTranslation)(translationKey);
1424
+ const projection = (0, import_react15.useMemo)(() => new import_schema5.ViewProjection(schema.jsonSchema, view), [
1340
1425
  schema,
1341
1426
  view
1342
1427
  ]);
1343
- const [field, setField] = (0, import_react14.useState)();
1344
- const viewValues = (0, import_react14.useMemo)(() => {
1428
+ const [field, setField] = (0, import_react15.useState)();
1429
+ const viewValues = (0, import_react15.useMemo)(() => {
1345
1430
  return {
1346
1431
  name: view.name,
1347
1432
  // TODO(burdon): Need to warn user of possible consequences of editing.
@@ -1351,30 +1436,77 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1351
1436
  }, [
1352
1437
  view
1353
1438
  ]);
1354
- const handleViewUpdate = (0, import_react14.useCallback)(({ name, typename }) => {
1439
+ const handleSelect = (0, import_react15.useCallback)((field2) => {
1440
+ setField((f) => f === field2 ? void 0 : field2);
1441
+ }, []);
1442
+ const handleAdd = (0, import_react15.useCallback)(() => {
1443
+ (0, import_invariant3.invariant)(!schema.readonly, void 0, {
1444
+ F: __dxlog_file4,
1445
+ L: 76,
1446
+ S: void 0,
1447
+ A: [
1448
+ "!schema.readonly",
1449
+ ""
1450
+ ]
1451
+ });
1452
+ const field2 = projection.createFieldProjection();
1453
+ setField(field2);
1454
+ }, [
1455
+ schema,
1456
+ view
1457
+ ]);
1458
+ const handleUpdate = (0, import_react15.useCallback)(({ name, typename }) => {
1459
+ (0, import_invariant3.invariant)(!schema.readonly, void 0, {
1460
+ F: __dxlog_file4,
1461
+ L: 83,
1462
+ S: void 0,
1463
+ A: [
1464
+ "!schema.readonly",
1465
+ ""
1466
+ ]
1467
+ });
1355
1468
  requestAnimationFrame(() => {
1356
1469
  if (view.name !== name) {
1357
1470
  view.name = name;
1358
1471
  }
1359
1472
  if (view.query.typename !== typename) {
1360
- onTypenameChanged(typename);
1473
+ onTypenameChanged?.(typename);
1361
1474
  }
1362
1475
  });
1363
1476
  }, [
1364
- view,
1365
1477
  schema,
1478
+ view,
1366
1479
  onTypenameChanged
1367
1480
  ]);
1368
- const handleSelect = (0, import_react14.useCallback)((field2) => {
1369
- setField((f) => f === field2 ? void 0 : field2);
1370
- }, []);
1371
- const handleAdd = (0, import_react14.useCallback)(() => {
1372
- const field2 = projection.createFieldProjection();
1373
- setField(field2);
1481
+ const handleDelete = (0, import_react15.useCallback)((fieldId) => {
1482
+ (0, import_invariant3.invariant)(!schema.readonly, void 0, {
1483
+ F: __dxlog_file4,
1484
+ L: 99,
1485
+ S: void 0,
1486
+ A: [
1487
+ "!schema.readonly",
1488
+ ""
1489
+ ]
1490
+ });
1491
+ if (fieldId === field?.id) {
1492
+ setField(void 0);
1493
+ }
1494
+ onDelete?.(fieldId);
1374
1495
  }, [
1375
- view
1496
+ schema,
1497
+ field,
1498
+ onDelete
1376
1499
  ]);
1377
- const handleMove = (0, import_react14.useCallback)((fromIndex, toIndex) => {
1500
+ const handleMove = (0, import_react15.useCallback)((fromIndex, toIndex) => {
1501
+ (0, import_invariant3.invariant)(!schema.readonly, void 0, {
1502
+ F: __dxlog_file4,
1503
+ L: 111,
1504
+ S: void 0,
1505
+ A: [
1506
+ "!schema.readonly",
1507
+ ""
1508
+ ]
1509
+ });
1378
1510
  const fields = [
1379
1511
  ...view.fields
1380
1512
  ];
@@ -1382,57 +1514,97 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1382
1514
  fields.splice(toIndex, 0, moved);
1383
1515
  view.fields = fields;
1384
1516
  }, [
1517
+ schema,
1385
1518
  view.fields
1386
1519
  ]);
1387
- const handleClose = (0, import_react14.useCallback)(() => setField(void 0), []);
1388
- return /* @__PURE__ */ import_react14.default.createElement("div", {
1520
+ const handleClose = (0, import_react15.useCallback)(() => setField(void 0), []);
1521
+ const hiddenProperties = projection.getHiddenProperties();
1522
+ const handleHide = (0, import_react15.useCallback)((fieldId) => {
1523
+ setField(void 0);
1524
+ projection.hideFieldProjection(fieldId);
1525
+ }, [
1526
+ projection
1527
+ ]);
1528
+ const handleShow = (0, import_react15.useCallback)((property) => {
1529
+ setField(void 0);
1530
+ projection.showFieldProjection(property);
1531
+ }, [
1532
+ projection
1533
+ ]);
1534
+ return /* @__PURE__ */ import_react15.default.createElement("div", {
1389
1535
  role: "none",
1390
1536
  className: (0, import_react_ui_theme9.mx)("flex flex-col w-full divide-y divide-separator", classNames)
1391
- }, /* @__PURE__ */ import_react14.default.createElement(Form, {
1537
+ }, /* @__PURE__ */ import_react15.default.createElement(Form, {
1392
1538
  autoSave: true,
1393
1539
  schema: ViewMetaSchema,
1394
1540
  values: viewValues,
1395
- onSave: handleViewUpdate
1396
- }), /* @__PURE__ */ import_react14.default.createElement("div", null, /* @__PURE__ */ import_react14.default.createElement("div", {
1541
+ onSave: schema.readonly ? void 0 : handleUpdate
1542
+ }), /* @__PURE__ */ import_react15.default.createElement("div", null, /* @__PURE__ */ import_react15.default.createElement("div", {
1397
1543
  role: "none",
1398
1544
  className: "p-2"
1399
- }, /* @__PURE__ */ import_react14.default.createElement("label", {
1545
+ }, /* @__PURE__ */ import_react15.default.createElement("label", {
1400
1546
  className: (0, import_react_ui_theme9.mx)(import_react_ui_theme9.inputTextLabel)
1401
- }, t("fields label"))), /* @__PURE__ */ import_react14.default.createElement(import_react_ui_list2.List.Root, {
1547
+ }, t("fields label"))), /* @__PURE__ */ import_react15.default.createElement(import_react_ui_list2.List.Root, {
1402
1548
  items: view.fields,
1403
1549
  isItem: import_echo_schema8.S.is(import_schema5.FieldSchema),
1404
1550
  getId: (field2) => field2.id,
1405
- onMove: handleMove
1406
- }, ({ items: fields }) => /* @__PURE__ */ import_react14.default.createElement(import_react14.default.Fragment, null, showHeading && /* @__PURE__ */ import_react14.default.createElement("div", {
1551
+ onMove: schema.readonly ? void 0 : handleMove
1552
+ }, ({ items: fields }) => /* @__PURE__ */ import_react15.default.createElement(import_react15.default.Fragment, null, showHeading && /* @__PURE__ */ import_react15.default.createElement("div", {
1407
1553
  role: "heading",
1408
1554
  className: grid
1409
- }, /* @__PURE__ */ import_react14.default.createElement("div", null), /* @__PURE__ */ import_react14.default.createElement("div", {
1555
+ }, /* @__PURE__ */ import_react15.default.createElement("div", null), /* @__PURE__ */ import_react15.default.createElement("div", {
1410
1556
  className: "flex items-center text-sm"
1411
- }, t("field path label"))), /* @__PURE__ */ import_react14.default.createElement("div", {
1557
+ }, t("field path label"))), /* @__PURE__ */ import_react15.default.createElement("div", {
1412
1558
  role: "list",
1413
1559
  className: "flex flex-col w-full"
1414
- }, fields?.map((field2) => /* @__PURE__ */ import_react14.default.createElement(import_react_ui_list2.List.Item, {
1560
+ }, fields?.map((field2) => /* @__PURE__ */ import_react15.default.createElement(import_react_ui_list2.List.Item, {
1415
1561
  key: field2.id,
1416
1562
  item: field2,
1417
1563
  classNames: (0, import_react_ui_theme9.mx)(grid, import_react_ui_theme9.ghostHover, "cursor-pointer")
1418
- }, /* @__PURE__ */ import_react14.default.createElement(import_react_ui_list2.List.ItemDragHandle, null), /* @__PURE__ */ import_react14.default.createElement(import_react_ui_list2.List.ItemTitle, {
1564
+ }, /* @__PURE__ */ import_react15.default.createElement(import_react_ui_list2.List.ItemDragHandle, null), /* @__PURE__ */ import_react15.default.createElement(import_react_ui_list2.List.ItemTitle, {
1419
1565
  onClick: () => handleSelect(field2)
1420
- }, field2.path), /* @__PURE__ */ import_react14.default.createElement(import_react_ui_list2.List.ItemDeleteButton, {
1566
+ }, field2.path), /* @__PURE__ */ import_react15.default.createElement("div", {
1567
+ className: "flex items-center gap-2 -ml-4"
1568
+ }, /* @__PURE__ */ import_react15.default.createElement(import_react_ui_list2.List.ItemButton, {
1569
+ icon: "ph--eye-slash--regular",
1570
+ disabled: view.fields.length <= 1,
1571
+ onClick: () => handleHide(field2.id)
1572
+ }), !schema.readonly && /* @__PURE__ */ import_react15.default.createElement(import_react_ui_list2.List.ItemDeleteButton, {
1573
+ icon: "ph--trash--regular",
1421
1574
  disabled: view.fields.length <= 1,
1422
- onClick: () => onDelete(field2.id)
1423
- }))))))), field && /* @__PURE__ */ import_react14.default.createElement(FieldEditor, {
1575
+ onClick: () => handleDelete(field2.id)
1576
+ }))))))), hiddenProperties.length > 0 && /* @__PURE__ */ import_react15.default.createElement("div", null, /* @__PURE__ */ import_react15.default.createElement("div", {
1577
+ role: "none",
1578
+ className: "p-2"
1579
+ }, /* @__PURE__ */ import_react15.default.createElement("label", {
1580
+ className: (0, import_react_ui_theme9.mx)(import_react_ui_theme9.inputTextLabel)
1581
+ }, t("hidden fields label"))), /* @__PURE__ */ import_react15.default.createElement(import_react_ui_list2.List.Root, {
1582
+ items: hiddenProperties,
1583
+ isItem: (item) => typeof item === "string",
1584
+ getId: (property) => property
1585
+ }, ({ items: properties }) => /* @__PURE__ */ import_react15.default.createElement("div", {
1586
+ role: "list",
1587
+ className: "flex flex-col w-full"
1588
+ }, properties?.map((property) => /* @__PURE__ */ import_react15.default.createElement(import_react_ui_list2.List.Item, {
1589
+ key: property,
1590
+ item: property,
1591
+ classNames: (0, import_react_ui_theme9.mx)(grid, import_react_ui_theme9.ghostHover, "cursor-pointer")
1592
+ }, /* @__PURE__ */ import_react15.default.createElement("div", null), /* @__PURE__ */ import_react15.default.createElement(import_react_ui_list2.List.ItemTitle, null, property), /* @__PURE__ */ import_react15.default.createElement(import_react_ui_list2.List.ItemButton, {
1593
+ icon: "ph--eye--regular",
1594
+ onClick: () => handleShow(property)
1595
+ }))))))), field && /* @__PURE__ */ import_react15.default.createElement(FieldEditor, {
1424
1596
  key: field.id,
1425
1597
  view,
1426
1598
  projection,
1427
1599
  field,
1428
1600
  registry,
1429
1601
  onSave: handleClose
1430
- }), !readonly && !field && /* @__PURE__ */ import_react14.default.createElement("div", {
1602
+ }), !readonly && !field && /* @__PURE__ */ import_react15.default.createElement("div", {
1431
1603
  className: "flex p-2 justify-center"
1432
- }, /* @__PURE__ */ import_react14.default.createElement(import_react_ui10.IconButton, {
1604
+ }, /* @__PURE__ */ import_react15.default.createElement(import_react_ui11.IconButton, {
1433
1605
  icon: "ph--plus--regular",
1434
1606
  label: t("button add property"),
1435
- onClick: handleAdd,
1607
+ onClick: schema.readonly ? void 0 : handleAdd,
1436
1608
  // TODO(burdon): Show field limit in ux (not tooltip).
1437
1609
  disabled: view.fields.length >= import_schema5.VIEW_FIELD_LIMIT
1438
1610
  })));
@@ -1540,18 +1712,21 @@ var cellClassesForFieldType = ({ type, format }) => {
1540
1712
  switch (format) {
1541
1713
  case import_echo_schema9.FormatEnum.Markdown:
1542
1714
  return void 0;
1715
+ case import_echo_schema9.FormatEnum.Time:
1543
1716
  case import_echo_schema9.FormatEnum.Timestamp:
1544
1717
  case import_echo_schema9.FormatEnum.DateTime:
1545
1718
  case import_echo_schema9.FormatEnum.Date:
1546
- case import_echo_schema9.FormatEnum.Time:
1719
+ case import_echo_schema9.FormatEnum.Duration:
1547
1720
  return [
1548
- "font-mono"
1721
+ "font-mono",
1722
+ "text-right"
1549
1723
  ];
1550
1724
  case import_echo_schema9.FormatEnum.Currency:
1551
1725
  return [
1552
1726
  "text-right"
1553
1727
  ];
1554
1728
  case import_echo_schema9.FormatEnum.JSON:
1729
+ case import_echo_schema9.FormatEnum.DID:
1555
1730
  return [
1556
1731
  "font-mono"
1557
1732
  ];
@@ -1559,9 +1734,6 @@ var cellClassesForFieldType = ({ type, format }) => {
1559
1734
  return void 0;
1560
1735
  }
1561
1736
  };
1562
- var cellClassesForRowSelection = (selected) => selected ? [
1563
- "!bg-gridCellSelected"
1564
- ] : void 0;
1565
1737
  var pathNotUniqueError = (path) => ({
1566
1738
  path: "path",
1567
1739
  message: `'${path}' is already present`
@@ -1606,17 +1778,14 @@ var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
1606
1778
  maximumFractionDigits: 2
1607
1779
  });
1608
1780
  }
1609
- case import_echo_schema10.FormatEnum.DateTime:
1610
- case import_echo_schema10.FormatEnum.Date:
1781
+ case import_echo_schema10.FormatEnum.Date: {
1782
+ return (0, import_format.format)(new Date(value), "yyyy-MM-dd");
1783
+ }
1611
1784
  case import_echo_schema10.FormatEnum.Time: {
1612
- const date = new Date(value);
1613
- if (format === import_echo_schema10.FormatEnum.DateTime) {
1614
- return date.toLocaleString(locale);
1615
- } else if (format === import_echo_schema10.FormatEnum.Date) {
1616
- return date.toLocaleDateString(locale);
1617
- } else {
1618
- return date.toLocaleTimeString(locale);
1619
- }
1785
+ return (0, import_format.format)(new Date(value), "HH:mm:ss");
1786
+ }
1787
+ case import_echo_schema10.FormatEnum.DateTime: {
1788
+ return (0, import_format.format)(new Date(value), "yyyy-MM-dd HH:mm:ss");
1620
1789
  }
1621
1790
  case import_echo_schema10.FormatEnum.GeoPoint: {
1622
1791
  if (value === null || value === void 0) {
@@ -1694,10 +1863,18 @@ var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1694
1863
  // Annotate the CommonJS export names for ESM import in node:
1695
1864
  0 && (module.exports = {
1696
1865
  BooleanInput,
1866
+ ControlFrame,
1867
+ ControlFrameItem,
1868
+ ControlGroup,
1869
+ ControlItem,
1870
+ ControlItemInput,
1871
+ ControlSection,
1872
+ ControlSectionHeading,
1697
1873
  DeprecatedFormContainer,
1698
1874
  DeprecatedFormInput,
1699
1875
  FieldEditor,
1700
1876
  Form,
1877
+ FormProvider,
1701
1878
  GeoPointInput,
1702
1879
  InputHeader,
1703
1880
  MarkdownInput,
@@ -1708,13 +1885,15 @@ var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1708
1885
  TupleInput,
1709
1886
  ViewEditor,
1710
1887
  cellClassesForFieldType,
1711
- cellClassesForRowSelection,
1888
+ controlItemClasses,
1712
1889
  formatForDisplay,
1713
1890
  formatForEditing,
1714
1891
  parseValue,
1715
1892
  pathNotUniqueError,
1716
1893
  translations,
1717
1894
  useForm,
1718
- useFormValues
1895
+ useFormContext,
1896
+ useFormValues,
1897
+ useInputProps
1719
1898
  });
1720
1899
  //# sourceMappingURL=index.cjs.map