@dxos/react-ui-form 0.7.5-labs.a279d8c → 0.7.5-labs.ea4b4c2

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 (45) hide show
  1. package/dist/lib/browser/index.mjs +519 -277
  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 +512 -267
  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 +519 -277
  8. package/dist/lib/node-esm/index.mjs.map +4 -4
  9. package/dist/lib/node-esm/meta.json +1 -1
  10. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
  11. package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
  12. package/dist/types/src/components/Form/Form.d.ts +3 -2
  13. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  14. package/dist/types/src/components/Form/FormContent.d.ts.map +1 -1
  15. package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts +4 -0
  16. package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts.map +1 -0
  17. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts +7 -0
  18. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts.map +1 -0
  19. package/dist/types/src/components/Form/custom/index.d.ts +1 -0
  20. package/dist/types/src/components/Form/custom/index.d.ts.map +1 -1
  21. package/dist/types/src/components/Form/index.d.ts +2 -0
  22. package/dist/types/src/components/Form/index.d.ts.map +1 -1
  23. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
  24. package/dist/types/src/components/deprecated/FormInput.d.ts +5 -0
  25. package/dist/types/src/components/deprecated/FormInput.d.ts.map +1 -1
  26. package/dist/types/src/hooks/useForm.d.ts.map +1 -1
  27. package/dist/types/src/translations.d.ts +6 -0
  28. package/dist/types/src/translations.d.ts.map +1 -1
  29. package/dist/types/tsconfig.tsbuildinfo +1 -1
  30. package/package.json +25 -24
  31. package/src/components/FieldEditor/FieldEditor.stories.tsx +1 -1
  32. package/src/components/FieldEditor/FieldEditor.tsx +3 -2
  33. package/src/components/Form/ArrayField.tsx +1 -1
  34. package/src/components/Form/Defaults.tsx +2 -1
  35. package/src/components/Form/Form.tsx +16 -2
  36. package/src/components/Form/FormActions.tsx +1 -1
  37. package/src/components/Form/FormContent.tsx +27 -9
  38. package/src/components/Form/custom/SelectOptionsInput.stories.tsx +58 -0
  39. package/src/components/Form/custom/SelectOptionsInput.tsx +192 -0
  40. package/src/components/Form/custom/index.ts +1 -0
  41. package/src/components/Form/index.ts +3 -0
  42. package/src/components/ViewEditor/ViewEditor.tsx +5 -2
  43. package/src/components/deprecated/FormInput.tsx +20 -7
  44. package/src/hooks/useForm.ts +0 -1
  45. package/src/translations.ts +8 -0
@@ -29,6 +29,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
29
29
  var node_exports = {};
30
30
  __export(node_exports, {
31
31
  BooleanInput: () => BooleanInput,
32
+ DeprecatedFormContainer: () => DeprecatedFormContainer,
32
33
  DeprecatedFormInput: () => DeprecatedFormInput,
33
34
  FieldEditor: () => FieldEditor,
34
35
  Form: () => Form,
@@ -36,6 +37,7 @@ __export(node_exports, {
36
37
  InputHeader: () => InputHeader,
37
38
  NumberInput: () => NumberInput,
38
39
  SelectInput: () => SelectInput,
40
+ SelectOptionInput: () => SelectOptionInput,
39
41
  TextInput: () => TextInput,
40
42
  TupleInput: () => TupleInput,
41
43
  ViewEditor: () => ViewEditor,
@@ -46,68 +48,75 @@ __export(node_exports, {
46
48
  parseValue: () => parseValue,
47
49
  pathNotUniqueError: () => pathNotUniqueError,
48
50
  translations: () => translations_default,
49
- useForm: () => useForm
51
+ useForm: () => useForm,
52
+ useFormValues: () => useFormValues
50
53
  });
51
54
  module.exports = __toCommonJS(node_exports);
52
55
  var import_react = __toESM(require("react"));
53
56
  var import_react_ui = require("@dxos/react-ui");
57
+ var import_react_ui_theme = require("@dxos/react-ui-theme");
54
58
  var import_react2 = __toESM(require("react"));
55
59
  var import_echo_schema = require("@dxos/echo-schema");
56
60
  var import_log = require("@dxos/log");
57
61
  var import_react_ui2 = require("@dxos/react-ui");
58
62
  var import_schema = require("@dxos/schema");
59
63
  var import_react3 = __toESM(require("react"));
64
+ var import_debug = require("@dxos/debug");
65
+ var import_echo_schema2 = require("@dxos/echo-schema");
66
+ var import_effect = require("@dxos/effect");
67
+ var import_react4 = require("react");
68
+ var import_echo_schema3 = require("@dxos/echo-schema");
69
+ var import_effect2 = require("@dxos/effect");
70
+ var import_invariant = require("@dxos/invariant");
71
+ var import_log2 = require("@dxos/log");
72
+ var import_schema2 = require("@dxos/schema");
73
+ var import_react5 = __toESM(require("react"));
60
74
  var import_react_ui3 = require("@dxos/react-ui");
61
75
  var import_util = require("@dxos/util");
62
- var import_react4 = __toESM(require("react"));
76
+ var import_react6 = __toESM(require("react"));
63
77
  var import_react_ui4 = require("@dxos/react-ui");
64
- var import_react_ui_theme = require("@dxos/react-ui-theme");
65
- var import_react5 = __toESM(require("react"));
66
- var import_react_ui5 = require("@dxos/react-ui");
67
78
  var import_react_ui_theme2 = require("@dxos/react-ui-theme");
68
- var import_util2 = require("@dxos/util");
69
- var import_react6 = __toESM(require("react"));
70
- var import_react_ui6 = require("@dxos/react-ui");
71
79
  var import_react7 = __toESM(require("react"));
80
+ var import_keys = require("@dxos/keys");
81
+ var import_react_ui5 = require("@dxos/react-ui");
82
+ var import_react_ui_list = require("@dxos/react-ui-list");
83
+ var import_react_ui_pickers = require("@dxos/react-ui-pickers");
72
84
  var import_react_ui_theme3 = require("@dxos/react-ui-theme");
73
85
  var import_react8 = __toESM(require("react"));
74
- var import_react_ui7 = require("@dxos/react-ui");
86
+ var import_react_ui6 = require("@dxos/react-ui");
75
87
  var import_react_ui_theme4 = require("@dxos/react-ui-theme");
88
+ var import_util2 = require("@dxos/util");
76
89
  var import_react9 = __toESM(require("react"));
77
- var import_debug = require("@dxos/debug");
78
- var import_echo_schema2 = require("@dxos/echo-schema");
79
- var import_effect = require("@dxos/effect");
80
- var import_react10 = require("react");
81
- var import_echo_schema3 = require("@dxos/echo-schema");
82
- var import_effect2 = require("@dxos/effect");
83
- var import_invariant = require("@dxos/invariant");
84
- var import_log2 = require("@dxos/log");
85
- var import_schema2 = require("@dxos/schema");
90
+ var import_react_ui7 = require("@dxos/react-ui");
91
+ var import_react10 = __toESM(require("react"));
92
+ var import_react_ui_theme5 = require("@dxos/react-ui-theme");
93
+ var import_react11 = __toESM(require("react"));
94
+ var import_react_ui8 = require("@dxos/react-ui");
95
+ var import_react_ui_theme6 = require("@dxos/react-ui-theme");
86
96
  var import_effect3 = require("effect");
87
97
  var import_String = require("effect/String");
88
- var import_react11 = __toESM(require("react"));
98
+ var import_react12 = __toESM(require("react"));
89
99
  var import_echo_schema4 = require("@dxos/echo-schema");
90
100
  var import_effect4 = require("@dxos/effect");
91
- var import_react_ui_theme5 = require("@dxos/react-ui-theme");
101
+ var import_react_ui_theme7 = require("@dxos/react-ui-theme");
92
102
  var import_schema3 = require("@dxos/schema");
93
103
  var import_util3 = require("@dxos/util");
94
104
  var import_effect5 = require("effect");
95
105
  var import_String2 = require("effect/String");
96
- var import_react12 = __toESM(require("react"));
106
+ var import_react13 = __toESM(require("react"));
97
107
  var import_echo_schema5 = require("@dxos/echo-schema");
98
108
  var import_effect6 = require("@dxos/effect");
99
109
  var import_invariant2 = require("@dxos/invariant");
100
- var import_react_ui8 = require("@dxos/react-ui");
101
- var import_react_ui_theme6 = require("@dxos/react-ui-theme");
110
+ var import_react_ui9 = require("@dxos/react-ui");
111
+ var import_react_ui_theme8 = require("@dxos/react-ui-theme");
102
112
  var import_schema4 = require("@dxos/schema");
103
113
  var import_echo_schema6 = require("@dxos/echo-schema");
104
- var import_react13 = __toESM(require("react"));
114
+ var import_react14 = __toESM(require("react"));
105
115
  var import_echo_schema7 = require("@dxos/echo-schema");
106
- var import_react_ui9 = require("@dxos/react-ui");
107
- var import_react_ui_list = require("@dxos/react-ui-list");
108
- var import_react_ui_theme7 = require("@dxos/react-ui-theme");
116
+ var import_react_ui10 = require("@dxos/react-ui");
117
+ var import_react_ui_list2 = require("@dxos/react-ui-list");
118
+ var import_react_ui_theme9 = require("@dxos/react-ui-theme");
109
119
  var import_schema5 = require("@dxos/schema");
110
- var import_util4 = require("@dxos/util");
111
120
  var import_echo_schema8 = require("@dxos/echo-schema");
112
121
  var import_echo_schema9 = require("@dxos/echo-schema");
113
122
  var translationKey = "react-ui-form";
@@ -146,6 +155,7 @@ var translations_default = [
146
155
  "format ref": "Reference",
147
156
  "format regex": "RegExp",
148
157
  "format string": "String",
158
+ "format single-select": "Select",
149
159
  "format text": "Long text",
150
160
  "format time": "Time",
151
161
  "format timestamp": "Timestamp",
@@ -155,11 +165,26 @@ var translations_default = [
155
165
  "format uuid": "UUID",
156
166
  // Placeholders
157
167
  "placeholder latitude": "Latitude",
158
- "placeholder longitude": "Longitude"
168
+ "placeholder longitude": "Longitude",
169
+ // SelectOptionsInput
170
+ "select option label": "Label",
171
+ "select option label placeholder": "Option label",
172
+ "select option color": "Color",
173
+ "select option delete": "Delete",
174
+ "select option add": "Add option"
159
175
  }
160
176
  }
161
177
  }
162
178
  ];
179
+ var DeprecatedFormContainer = ({ children, classNames }) => {
180
+ return /* @__PURE__ */ import_react.default.createElement("div", {
181
+ role: "none",
182
+ className: "w-full p-4 justify-center overflow-x-hidden overflow-y-auto"
183
+ }, /* @__PURE__ */ import_react.default.createElement("div", {
184
+ role: "form",
185
+ className: (0, import_react_ui_theme.mx)("flex flex-col", import_react_ui_theme.textBlockWidth, classNames)
186
+ }, children));
187
+ };
163
188
  var DeprecatedFormInput = ({ label, description, secondary, children }) => {
164
189
  const primary = /* @__PURE__ */ import_react.default.createElement("div", {
165
190
  role: "none",
@@ -168,157 +193,25 @@ var DeprecatedFormInput = ({ label, description, secondary, children }) => {
168
193
  role: "none",
169
194
  className: "flex flex-col w-full"
170
195
  }, /* @__PURE__ */ import_react.default.createElement(import_react_ui.Input.Label, {
171
- classNames: "flex min-h-[40px] items-center"
196
+ classNames: "flex min-bs-[--rail-action] items-center",
197
+ style: {
198
+ fontSize: "unset"
199
+ }
172
200
  }, label), description && /* @__PURE__ */ import_react.default.createElement(import_react_ui.Input.DescriptionAndValidation, {
173
201
  classNames: "mbs-0.5"
174
202
  }, /* @__PURE__ */ import_react.default.createElement(import_react_ui.Input.Description, null, description))), /* @__PURE__ */ import_react.default.createElement("div", {
175
203
  role: "none"
176
204
  }, /* @__PURE__ */ import_react.default.createElement("div", {
177
205
  role: "none",
178
- className: "flex min-h-[40px] items-center"
206
+ className: "flex min-bs-[--rail-action] items-center"
179
207
  }, children))));
180
208
  if (secondary) {
181
209
  return /* @__PURE__ */ import_react.default.createElement("div", {
182
- role: "none",
183
- className: "flex flex-col w-full"
210
+ role: "none"
184
211
  }, primary, secondary);
185
212
  }
186
213
  return primary;
187
214
  };
188
- var InputHeader = ({ children, error }) => {
189
- return /* @__PURE__ */ import_react4.default.createElement("div", {
190
- role: "none",
191
- className: "flex justify-between items-center mb-1"
192
- }, children, error && /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Tooltip.Root, null, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Tooltip.Trigger, {
193
- asChild: true
194
- }, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Icon, {
195
- icon: "ph--warning--regular",
196
- size: 4,
197
- classNames: import_react_ui_theme.errorText
198
- })), /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Tooltip.Content, {
199
- side: "bottom"
200
- }, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Tooltip.Arrow, null), error)));
201
- };
202
- var GeoPointInput = ({ type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
203
- const { t } = (0, import_react_ui3.useTranslation)(translationKey);
204
- const { status, error } = getStatus();
205
- const [lng = 0, lat = 0] = getValue3() ?? [];
206
- return /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.Input.Root, {
207
- validationValence: status
208
- }, /* @__PURE__ */ import_react3.default.createElement(InputHeader, {
209
- error
210
- }, /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.Input.Label, null, label)), /* @__PURE__ */ import_react3.default.createElement("div", {
211
- className: "grid grid-cols-2 gap-2"
212
- }, /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.Input.TextInput, {
213
- type: "number",
214
- disabled,
215
- placeholder: t("placeholder longitude"),
216
- value: lng,
217
- onChange: (event) => onValueChange(type, [
218
- lat,
219
- (0, import_util.safeParseFloat)(event.target.value, 0)
220
- ]),
221
- onBlur
222
- }), /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.Input.TextInput, {
223
- type: "number",
224
- disabled,
225
- placeholder: t("placeholder latitude"),
226
- value: lat,
227
- onChange: (event) => onValueChange(type, [
228
- (0, import_util.safeParseFloat)(event.target.value, 0),
229
- lng
230
- ]),
231
- onBlur
232
- })));
233
- };
234
- var gridCols = [
235
- "grid-cols-1",
236
- "grid-cols-2",
237
- "grid-cols-3",
238
- "grid-cols-4"
239
- ];
240
- var TupleInput = ({ binding, type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
241
- const { status, error } = getStatus();
242
- const values = getValue3() ?? {};
243
- return /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Input.Root, {
244
- validationValence: status
245
- }, /* @__PURE__ */ import_react5.default.createElement(InputHeader, {
246
- error
247
- }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Input.Label, null, label)), /* @__PURE__ */ import_react5.default.createElement("div", {
248
- className: (0, import_react_ui_theme2.mx)("grid gap-2", gridCols[binding.length - 1])
249
- }, binding.map((prop) => /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Input.TextInput, {
250
- key: prop,
251
- type: "number",
252
- disabled,
253
- value: values[prop],
254
- onChange: (event) => onValueChange(type, {
255
- ...values,
256
- [prop]: (0, import_util2.safeParseFloat)(event.target.value, 0)
257
- }),
258
- onBlur
259
- }))));
260
- };
261
- var TextInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
262
- const { status, error } = getStatus();
263
- return /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Root, {
264
- validationValence: status
265
- }, !inputOnly && /* @__PURE__ */ import_react6.default.createElement(InputHeader, {
266
- error
267
- }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Label, null, label)), /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.TextInput, {
268
- disabled,
269
- placeholder,
270
- value: getValue3() ?? "",
271
- onChange: (event) => onValueChange(type, event.target.value),
272
- onBlur
273
- }), inputOnly && /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Validation, null, error));
274
- };
275
- var NumberInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
276
- const { status, error } = getStatus();
277
- return /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Root, {
278
- validationValence: status
279
- }, !inputOnly && /* @__PURE__ */ import_react6.default.createElement(InputHeader, {
280
- error
281
- }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Label, null, label)), /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.TextInput, {
282
- type: "number",
283
- disabled,
284
- placeholder,
285
- value: getValue3() ?? 0,
286
- onChange: (event) => onValueChange(type, event.target.value),
287
- onBlur
288
- }), inputOnly && /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.DescriptionAndValidation, null, error));
289
- };
290
- var BooleanInput = ({ type, label, inputOnly, getStatus, getValue: getValue3, onValueChange }) => {
291
- const { status, error } = getStatus();
292
- return /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Root, {
293
- validationValence: status
294
- }, !inputOnly && /* @__PURE__ */ import_react6.default.createElement(InputHeader, {
295
- error
296
- }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Label, null, label)), /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Switch, {
297
- checked: getValue3(),
298
- onCheckedChange: (value) => onValueChange(type, value)
299
- }), inputOnly && /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.DescriptionAndValidation, null, error));
300
- };
301
- var SelectInput = ({ type, label, inputOnly, disabled, placeholder, options, getStatus, getValue: getValue3, onValueChange }) => {
302
- const { status, error } = getStatus();
303
- return /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Root, {
304
- validationValence: status
305
- }, !inputOnly && /* @__PURE__ */ import_react6.default.createElement(InputHeader, {
306
- error
307
- }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Label, null, label)), /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Select.Root, {
308
- value: getValue3(),
309
- onValueChange: (value) => onValueChange(type, value)
310
- }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Select.TriggerButton, {
311
- classNames: "is-full",
312
- disabled,
313
- placeholder
314
- }), /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Select.Portal, null, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Select.Content, null, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Select.Viewport, null, options?.map(({ value, label: label2 }) => (
315
- // NOTE: Numeric values are converted to and from strings.
316
- /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Select.Option, {
317
- key: String(value),
318
- value: String(value)
319
- }, label2 ?? String(value))
320
- )))))), inputOnly && /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.DescriptionAndValidation, null, error));
321
- };
322
215
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/hooks/useForm.ts";
323
216
  var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, onSave }) => {
324
217
  (0, import_invariant.invariant)(import_effect2.AST.isTypeLiteral(schema.ast), void 0, {
@@ -330,17 +223,17 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
330
223
  ""
331
224
  ]
332
225
  });
333
- const [values, setValues] = (0, import_react10.useState)(initialValues);
334
- (0, import_react10.useEffect)(() => {
226
+ const [values, setValues] = (0, import_react4.useState)(initialValues);
227
+ (0, import_react4.useEffect)(() => {
335
228
  setValues(initialValues);
336
229
  }, [
337
230
  initialValues
338
231
  ]);
339
- const [touched, setTouched] = (0, import_react10.useState)(createKeySet(initialValues, false));
340
- const [changed, setChanged] = (0, import_react10.useState)(createKeySet(initialValues, false));
341
- const [errors, setErrors] = (0, import_react10.useState)({});
342
- const [saving, setSaving] = (0, import_react10.useState)(false);
343
- const validate = (0, import_react10.useCallback)((values2) => {
232
+ const [touched, setTouched] = (0, import_react4.useState)(createKeySet(initialValues, false));
233
+ const [changed, setChanged] = (0, import_react4.useState)(createKeySet(initialValues, false));
234
+ const [errors, setErrors] = (0, import_react4.useState)({});
235
+ const [saving, setSaving] = (0, import_react4.useState)(false);
236
+ const validate = (0, import_react4.useCallback)((values2) => {
344
237
  let errors2 = (0, import_schema2.validateSchema)(schema, values2) ?? [];
345
238
  if (errors2.length === 0 && onValidate) {
346
239
  const validatedValues = values2;
@@ -353,11 +246,11 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
353
246
  schema,
354
247
  onValidate
355
248
  ]);
356
- const [schemaDirty, setSchemaDirty] = (0, import_react10.useState)(false);
357
- (0, import_react10.useEffect)(() => setSchemaDirty(true), [
249
+ const [schemaDirty, setSchemaDirty] = (0, import_react4.useState)(false);
250
+ (0, import_react4.useEffect)(() => setSchemaDirty(true), [
358
251
  schema
359
252
  ]);
360
- (0, import_react10.useEffect)(() => {
253
+ (0, import_react4.useEffect)(() => {
361
254
  if (schemaDirty) {
362
255
  validate(values);
363
256
  setSchemaDirty(false);
@@ -366,13 +259,13 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
366
259
  values,
367
260
  schemaDirty
368
261
  ]);
369
- const canSave = (0, import_react10.useMemo)(() => !saving && // Check if any error paths that are touched have errors
262
+ const canSave = (0, import_react4.useMemo)(() => !saving && // Check if any error paths that are touched have errors
370
263
  !Object.entries(touched).some(([path, isTouched]) => isTouched && Object.keys(errors).some((errorPath) => errorPath === path || errorPath.startsWith(`${path}.`) || errorPath.startsWith(`${path}[`))), [
371
264
  touched,
372
265
  errors,
373
266
  saving
374
267
  ]);
375
- const handleSave = (0, import_react10.useCallback)(async () => {
268
+ const handleSave = (0, import_react4.useCallback)(async () => {
376
269
  if (validate(values)) {
377
270
  setSaving(true);
378
271
  try {
@@ -389,7 +282,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
389
282
  onSave,
390
283
  changed
391
284
  ]);
392
- const getStatus = (0, import_react10.useCallback)((path) => {
285
+ const getStatus = (0, import_react4.useCallback)((path) => {
393
286
  const jsonPath = Array.isArray(path) ? (0, import_effect2.createJsonPath)(path) : path;
394
287
  const matchingError = Object.entries(errors).find(([errorPath]) => errorPath === jsonPath || errorPath.startsWith(`${jsonPath}.`) || errorPath.startsWith(`${jsonPath}[`));
395
288
  return {
@@ -412,7 +305,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
412
305
  } catch (err) {
413
306
  import_log2.log.catch(err, void 0, {
414
307
  F: __dxlog_file,
415
- L: 194,
308
+ L: 193,
416
309
  S: void 0,
417
310
  C: (f, a) => f(...a)
418
311
  });
@@ -434,7 +327,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
434
327
  });
435
328
  }
436
329
  };
437
- const onTouched = (0, import_react10.useCallback)((path) => {
330
+ const onTouched = (0, import_react4.useCallback)((path) => {
438
331
  const jsonPath = (0, import_effect2.createJsonPath)(path);
439
332
  setTouched((touched2) => ({
440
333
  ...touched2,
@@ -463,7 +356,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
463
356
  var createKeySet = (obj, value) => {
464
357
  (0, import_invariant.invariant)(obj, void 0, {
465
358
  F: __dxlog_file,
466
- L: 236,
359
+ L: 235,
467
360
  S: void 0,
468
361
  A: [
469
362
  "obj",
@@ -484,9 +377,9 @@ var flatMap = (errors) => {
484
377
  return result;
485
378
  }, {});
486
379
  };
487
- var FormContext = /* @__PURE__ */ (0, import_react9.createContext)(void 0);
380
+ var FormContext = /* @__PURE__ */ (0, import_react3.createContext)(void 0);
488
381
  var useFormContext = () => {
489
- return (0, import_react9.useContext)(FormContext) ?? (0, import_debug.raise)(new Error("Missing FormContext"));
382
+ return (0, import_react3.useContext)(FormContext) ?? (0, import_debug.raise)(new Error("Missing FormContext"));
490
383
  };
491
384
  var useFormValues = (path = []) => {
492
385
  const { values: formValues } = useFormContext();
@@ -504,25 +397,335 @@ var useInputProps = (path = []) => {
504
397
  };
505
398
  var FormProvider = ({ children, ...formOptions }) => {
506
399
  const formHandler = useForm(formOptions);
507
- return /* @__PURE__ */ import_react9.default.createElement(FormContext.Provider, {
400
+ return /* @__PURE__ */ import_react3.default.createElement(FormContext.Provider, {
508
401
  value: formHandler
509
402
  }, children);
510
403
  };
404
+ var InputHeader = ({ children, error }) => {
405
+ return /* @__PURE__ */ import_react6.default.createElement("div", {
406
+ role: "none",
407
+ className: "flex justify-between items-center mb-1"
408
+ }, children, error && /* @__PURE__ */ import_react6.default.createElement(import_react_ui4.Tooltip.Root, null, /* @__PURE__ */ import_react6.default.createElement(import_react_ui4.Tooltip.Trigger, {
409
+ asChild: true
410
+ }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui4.Icon, {
411
+ icon: "ph--warning--regular",
412
+ size: 4,
413
+ classNames: import_react_ui_theme2.errorText
414
+ })), /* @__PURE__ */ import_react6.default.createElement(import_react_ui4.Tooltip.Content, {
415
+ side: "bottom"
416
+ }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui4.Tooltip.Arrow, null), error)));
417
+ };
418
+ var GeoPointInput = ({ type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
419
+ const { t } = (0, import_react_ui3.useTranslation)(translationKey);
420
+ const { status, error } = getStatus();
421
+ const [lng = 0, lat = 0] = getValue3() ?? [];
422
+ return /* @__PURE__ */ import_react5.default.createElement(import_react_ui3.Input.Root, {
423
+ validationValence: status
424
+ }, /* @__PURE__ */ import_react5.default.createElement(InputHeader, {
425
+ error
426
+ }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui3.Input.Label, null, label)), /* @__PURE__ */ import_react5.default.createElement("div", {
427
+ className: "grid grid-cols-2 gap-2"
428
+ }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui3.Input.TextInput, {
429
+ type: "number",
430
+ disabled,
431
+ placeholder: t("placeholder longitude"),
432
+ value: lng,
433
+ onChange: (event) => onValueChange(type, [
434
+ lat,
435
+ (0, import_util.safeParseFloat)(event.target.value, 0)
436
+ ]),
437
+ onBlur
438
+ }), /* @__PURE__ */ import_react5.default.createElement(import_react_ui3.Input.TextInput, {
439
+ type: "number",
440
+ disabled,
441
+ placeholder: t("placeholder latitude"),
442
+ value: lat,
443
+ onChange: (event) => onValueChange(type, [
444
+ (0, import_util.safeParseFloat)(event.target.value, 0),
445
+ lng
446
+ ]),
447
+ onBlur
448
+ })));
449
+ };
450
+ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3, onValueChange }) => {
451
+ const [selected, setSelectedId] = (0, import_react7.useState)(null);
452
+ const [isNewOption, setIsNewOption] = (0, import_react7.useState)(false);
453
+ const inputRef = (0, import_react7.useRef)(null);
454
+ const { t } = (0, import_react_ui5.useTranslation)(translationKey);
455
+ const { status, error } = getStatus();
456
+ const options = getValue3();
457
+ (0, import_react7.useEffect)(() => {
458
+ if (options === void 0) {
459
+ onValueChange(type, []);
460
+ }
461
+ }, [
462
+ options,
463
+ onValueChange,
464
+ type
465
+ ]);
466
+ const randomHue = () => {
467
+ const usedHues = new Set(options?.map((option) => option.color) ?? []);
468
+ const hueKeys = Object.keys(import_react_ui_theme3.hueTokenThemes);
469
+ const unusedHues = hueKeys.filter((hue) => !usedHues.has(hue));
470
+ if (unusedHues.length > 0) {
471
+ return unusedHues[Math.floor(Math.random() * unusedHues.length)];
472
+ }
473
+ const lastThree = new Set(options?.slice(-3).map((option) => option.color) ?? []);
474
+ const availableHues = hueKeys.filter((hue) => !lastThree.has(hue));
475
+ return availableHues[Math.floor(Math.random() * availableHues.length)] ?? hueKeys[Math.floor(Math.random() * hueKeys.length)];
476
+ };
477
+ const handleAdd = (0, import_react7.useCallback)(() => {
478
+ const newId = import_keys.PublicKey.random().truncate();
479
+ const newOption = {
480
+ id: newId,
481
+ title: "",
482
+ color: randomHue()
483
+ };
484
+ onValueChange(type, [
485
+ ...options ?? [],
486
+ newOption
487
+ ]);
488
+ setSelectedId(newId);
489
+ setIsNewOption(true);
490
+ }, [
491
+ options,
492
+ type,
493
+ onValueChange
494
+ ]);
495
+ const handleDelete = (0, import_react7.useCallback)((id) => {
496
+ const newOptions = options?.filter((option) => option.id !== id) ?? [];
497
+ onValueChange(type, newOptions);
498
+ setSelectedId(null);
499
+ }, [
500
+ options,
501
+ type,
502
+ onValueChange
503
+ ]);
504
+ const handleMove = (0, import_react7.useCallback)((from, to) => {
505
+ if (!options) {
506
+ return;
507
+ }
508
+ const newOptions = [
509
+ ...options
510
+ ];
511
+ const [removed] = newOptions.splice(from, 1);
512
+ newOptions.splice(to, 0, removed);
513
+ onValueChange(type, newOptions);
514
+ }, [
515
+ options,
516
+ type,
517
+ onValueChange
518
+ ]);
519
+ const handleClick = (0, import_react7.useCallback)((id) => {
520
+ setSelectedId((current) => current === id ? null : id);
521
+ }, []);
522
+ const handleTitleChange = (0, import_react7.useCallback)((id) => (e) => {
523
+ const newOptions = options?.map((o) => o.id === id ? {
524
+ ...o,
525
+ title: e.target.value
526
+ } : o);
527
+ onValueChange(type, newOptions ?? []);
528
+ }, [
529
+ options,
530
+ type,
531
+ onValueChange
532
+ ]);
533
+ const handleKeyDown = (0, import_react7.useCallback)((e) => {
534
+ if (e.key === "Enter") {
535
+ setSelectedId(null);
536
+ }
537
+ }, []);
538
+ const handleColorChange = (0, import_react7.useCallback)((id) => (hue) => {
539
+ const newOptions = options?.map((o) => o.id === id ? {
540
+ ...o,
541
+ color: hue
542
+ } : o);
543
+ onValueChange(type, newOptions ?? []);
544
+ }, [
545
+ options,
546
+ type,
547
+ onValueChange
548
+ ]);
549
+ (0, import_react7.useEffect)(() => {
550
+ if (selected && isNewOption && inputRef.current) {
551
+ inputRef.current.focus();
552
+ setIsNewOption(false);
553
+ }
554
+ }, [
555
+ selected,
556
+ isNewOption
557
+ ]);
558
+ return /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Input.Root, {
559
+ validationValence: status
560
+ }, /* @__PURE__ */ import_react7.default.createElement(InputHeader, {
561
+ error
562
+ }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Input.Label, null, label)), /* @__PURE__ */ import_react7.default.createElement("div", {
563
+ role: "none"
564
+ }, options && /* @__PURE__ */ import_react7.default.createElement(import_react_ui_list.List.Root, {
565
+ items: options,
566
+ isItem: (item) => true,
567
+ onMove: handleMove
568
+ }, ({ items }) => /* @__PURE__ */ import_react7.default.createElement("div", {
569
+ role: "list",
570
+ className: "w-full overflow-auto"
571
+ }, items?.map((item) => /* @__PURE__ */ import_react7.default.createElement("div", {
572
+ key: item.id
573
+ }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui_list.List.Item, {
574
+ role: "button",
575
+ item,
576
+ classNames: (0, import_react_ui_theme3.mx)("p-1 plb-2", "flex flex-col", "cursor-pointer", "hover:bg-hoverOverlay"),
577
+ "aria-expanded": selected === item.id
578
+ }, /* @__PURE__ */ import_react7.default.createElement("div", {
579
+ className: "flex items-center"
580
+ }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui_list.List.ItemDragHandle, null), /* @__PURE__ */ import_react7.default.createElement(import_react_ui_list.List.ItemTitle, {
581
+ onClick: () => handleClick(item.id),
582
+ classNames: "flex-1"
583
+ }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Tag, {
584
+ palette: item.color
585
+ }, item.title || "\u200B")), /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Icon, {
586
+ icon: selected === item.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
587
+ onClick: () => handleClick(item.id)
588
+ })), selected === item.id && /* @__PURE__ */ import_react7.default.createElement("div", {
589
+ className: "mis-4 mbs-2 flex flex-col gap-1"
590
+ }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Input.Label, {
591
+ classNames: "text-xs"
592
+ }, t("select option label")), /* @__PURE__ */ import_react7.default.createElement("div", {
593
+ className: "flex flex-row items-center gap-1"
594
+ }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Input.TextInput, {
595
+ placeholder: t("select option label placeholder"),
596
+ ref: selected === item.id ? inputRef : void 0,
597
+ value: item.title,
598
+ onChange: handleTitleChange(item.id),
599
+ onKeyDown: handleKeyDown,
600
+ classNames: "flex-1"
601
+ }), /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Toolbar.Root, {
602
+ classNames: "p-0 m-0 !is-auto"
603
+ }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui_pickers.HuePickerToolbarButton, {
604
+ hue: item.color,
605
+ onChangeHue: handleColorChange(item.id)
606
+ })), /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.IconButton, {
607
+ icon: "ph--trash--fill",
608
+ iconOnly: true,
609
+ label: t("select option delete"),
610
+ onClick: () => handleDelete(item.id)
611
+ })))))), /* @__PURE__ */ import_react7.default.createElement("div", {
612
+ role: "listitem"
613
+ }, /* @__PURE__ */ import_react7.default.createElement("div", {
614
+ role: "button",
615
+ className: (0, import_react_ui_theme3.mx)("p-1 plb-2", "flex flex-col", "cursor-pointer", "hover:bg-hoverOverlay"),
616
+ onClick: handleAdd
617
+ }, /* @__PURE__ */ import_react7.default.createElement("div", {
618
+ className: "flex items-center gap-1"
619
+ }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Icon, {
620
+ icon: "ph--plus--regular"
621
+ }), /* @__PURE__ */ import_react7.default.createElement("span", {
622
+ className: "text-sm"
623
+ }, t("select option add")))))))));
624
+ };
625
+ var gridCols = [
626
+ "grid-cols-1",
627
+ "grid-cols-2",
628
+ "grid-cols-3",
629
+ "grid-cols-4"
630
+ ];
631
+ var TupleInput = ({ binding, type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
632
+ const { status, error } = getStatus();
633
+ const values = getValue3() ?? {};
634
+ return /* @__PURE__ */ import_react8.default.createElement(import_react_ui6.Input.Root, {
635
+ validationValence: status
636
+ }, /* @__PURE__ */ import_react8.default.createElement(InputHeader, {
637
+ error
638
+ }, /* @__PURE__ */ import_react8.default.createElement(import_react_ui6.Input.Label, null, label)), /* @__PURE__ */ import_react8.default.createElement("div", {
639
+ className: (0, import_react_ui_theme4.mx)("grid gap-2", gridCols[binding.length - 1])
640
+ }, binding.map((prop) => /* @__PURE__ */ import_react8.default.createElement(import_react_ui6.Input.TextInput, {
641
+ key: prop,
642
+ type: "number",
643
+ disabled,
644
+ value: values[prop],
645
+ onChange: (event) => onValueChange(type, {
646
+ ...values,
647
+ [prop]: (0, import_util2.safeParseFloat)(event.target.value, 0)
648
+ }),
649
+ onBlur
650
+ }))));
651
+ };
652
+ var TextInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
653
+ const { status, error } = getStatus();
654
+ return /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Root, {
655
+ validationValence: status
656
+ }, !inputOnly && /* @__PURE__ */ import_react9.default.createElement(InputHeader, {
657
+ error
658
+ }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Label, null, label)), /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.TextInput, {
659
+ disabled,
660
+ placeholder,
661
+ value: getValue3() ?? "",
662
+ onChange: (event) => onValueChange(type, event.target.value),
663
+ onBlur
664
+ }), inputOnly && /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Validation, null, error));
665
+ };
666
+ var NumberInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
667
+ const { status, error } = getStatus();
668
+ return /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Root, {
669
+ validationValence: status
670
+ }, !inputOnly && /* @__PURE__ */ import_react9.default.createElement(InputHeader, {
671
+ error
672
+ }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Label, null, label)), /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.TextInput, {
673
+ type: "number",
674
+ disabled,
675
+ placeholder,
676
+ value: getValue3() ?? 0,
677
+ onChange: (event) => onValueChange(type, event.target.value),
678
+ onBlur
679
+ }), inputOnly && /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.DescriptionAndValidation, null, error));
680
+ };
681
+ var BooleanInput = ({ type, label, inputOnly, getStatus, getValue: getValue3, onValueChange }) => {
682
+ const { status, error } = getStatus();
683
+ const checked = Boolean(getValue3());
684
+ return /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Root, {
685
+ validationValence: status
686
+ }, !inputOnly && /* @__PURE__ */ import_react9.default.createElement(InputHeader, {
687
+ error
688
+ }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Label, null, label)), /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Switch, {
689
+ checked,
690
+ onCheckedChange: (value) => onValueChange(type, value)
691
+ }), inputOnly && /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.DescriptionAndValidation, null, error));
692
+ };
693
+ var SelectInput = ({ type, label, inputOnly, disabled, placeholder, options, getStatus, getValue: getValue3, onValueChange }) => {
694
+ const { status, error } = getStatus();
695
+ return /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Root, {
696
+ validationValence: status
697
+ }, !inputOnly && /* @__PURE__ */ import_react9.default.createElement(InputHeader, {
698
+ error
699
+ }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Label, null, label)), /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Select.Root, {
700
+ value: getValue3(),
701
+ onValueChange: (value) => onValueChange(type, value)
702
+ }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Select.TriggerButton, {
703
+ classNames: "is-full",
704
+ disabled,
705
+ placeholder
706
+ }), /* @__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 }) => (
707
+ // NOTE: Numeric values are converted to and from strings.
708
+ /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Select.Option, {
709
+ key: String(value),
710
+ value: String(value)
711
+ }, label2 ?? String(value))
712
+ )))))), inputOnly && /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.DescriptionAndValidation, null, error));
713
+ };
511
714
  var FormActions = ({ onCancel, readonly }) => {
512
- const { t } = (0, import_react_ui7.useTranslation)(translationKey);
715
+ const { t } = (0, import_react_ui8.useTranslation)(translationKey);
513
716
  const { canSave, handleSave } = useFormContext();
514
- return /* @__PURE__ */ import_react8.default.createElement("div", {
717
+ return /* @__PURE__ */ import_react11.default.createElement("div", {
515
718
  role: "none",
516
- className: "flex justify-center"
517
- }, /* @__PURE__ */ import_react8.default.createElement("div", {
719
+ className: "mt-2 flex justify-center"
720
+ }, /* @__PURE__ */ import_react11.default.createElement("div", {
518
721
  role: "none",
519
- className: (0, import_react_ui_theme4.mx)(onCancel && !readonly && "grid grid-cols-2 gap-2")
520
- }, onCancel && !readonly && /* @__PURE__ */ import_react8.default.createElement(import_react_ui7.IconButton, {
722
+ className: (0, import_react_ui_theme6.mx)(onCancel && !readonly && "grid grid-cols-2 gap-2")
723
+ }, onCancel && !readonly && /* @__PURE__ */ import_react11.default.createElement(import_react_ui8.IconButton, {
521
724
  "data-testid": "cancel-button",
522
725
  icon: "ph--x--regular",
523
726
  label: t("button cancel"),
524
727
  onClick: onCancel
525
- }), handleSave && /* @__PURE__ */ import_react8.default.createElement(import_react_ui7.IconButton, {
728
+ }), handleSave && /* @__PURE__ */ import_react11.default.createElement(import_react_ui8.IconButton, {
526
729
  type: "submit",
527
730
  "data-testid": "save-button",
528
731
  disabled: !canSave,
@@ -534,16 +737,16 @@ var FormActions = ({ onCancel, readonly }) => {
534
737
  var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/Form/ArrayField.tsx";
535
738
  var padding = "px-2";
536
739
  var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponent }) => {
537
- const { t } = (0, import_react_ui8.useTranslation)(translationKey);
740
+ const { t } = (0, import_react_ui9.useTranslation)(translationKey);
538
741
  const { ast, name, type, title } = property;
539
742
  const values = useFormValues(path ?? []);
540
- (0, import_invariant2.invariant)(Array.isArray(values), void 0, {
743
+ (0, import_invariant2.invariant)(Array.isArray(values), `Values at path ${path?.join(".")} must be an array.`, {
541
744
  F: __dxlog_file2,
542
745
  L: 37,
543
746
  S: void 0,
544
747
  A: [
545
748
  "Array.isArray(values)",
546
- ""
749
+ "`Values at path ${path?.join('.')} must be an array.`"
547
750
  ]
548
751
  });
549
752
  const label = title ?? (0, import_effect5.pipe)(name, import_String2.capitalize);
@@ -560,7 +763,7 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
560
763
  prop.defaultValue
561
764
  ]));
562
765
  };
563
- const newValue = (0, import_react12.useMemo)(() => {
766
+ const newValue = (0, import_react13.useMemo)(() => {
564
767
  if (type === "object" && elementType) {
565
768
  return getDefaultObjectValue(elementType);
566
769
  } else {
@@ -570,7 +773,7 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
570
773
  type,
571
774
  elementType
572
775
  ]);
573
- const handleAdd = (0, import_react12.useCallback)(() => {
776
+ const handleAdd = (0, import_react13.useCallback)(() => {
574
777
  inputProps.onValueChange(type, [
575
778
  ...values,
576
779
  newValue
@@ -582,7 +785,7 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
582
785
  newValue,
583
786
  values
584
787
  ]);
585
- const handleRemove = (0, import_react12.useCallback)((index) => {
788
+ const handleRemove = (0, import_react13.useCallback)((index) => {
586
789
  const newValues = values.filter((_, i) => i !== index);
587
790
  inputProps.onValueChange(type, newValues);
588
791
  }, [
@@ -593,20 +796,20 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
593
796
  if (!elementType) {
594
797
  return null;
595
798
  }
596
- return /* @__PURE__ */ import_react12.default.createElement("div", {
799
+ return /* @__PURE__ */ import_react13.default.createElement("div", {
597
800
  role: "none",
598
- className: (0, import_react_ui_theme6.mx)(padding)
599
- }, /* @__PURE__ */ import_react12.default.createElement(InputHeader, null, label), /* @__PURE__ */ import_react12.default.createElement("div", {
801
+ className: (0, import_react_ui_theme8.mx)(padding)
802
+ }, /* @__PURE__ */ import_react13.default.createElement(InputHeader, null, label), /* @__PURE__ */ import_react13.default.createElement("div", {
600
803
  role: "none",
601
804
  className: "flex flex-col gap-1"
602
- }, values.map((_value, index) => /* @__PURE__ */ import_react12.default.createElement("div", {
805
+ }, values.map((_value, index) => /* @__PURE__ */ import_react13.default.createElement("div", {
603
806
  key: index,
604
807
  role: "none",
605
808
  className: "flex items-center gap-1"
606
- }, /* @__PURE__ */ import_react12.default.createElement("div", {
809
+ }, /* @__PURE__ */ import_react13.default.createElement("div", {
607
810
  role: "none",
608
811
  className: "flex-1"
609
- }, /* @__PURE__ */ import_react12.default.createElement(FormField, {
812
+ }, /* @__PURE__ */ import_react13.default.createElement(FormField, {
610
813
  property: {
611
814
  ...property,
612
815
  array: false,
@@ -620,15 +823,15 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
620
823
  inline: true,
621
824
  Custom,
622
825
  lookupComponent
623
- })), /* @__PURE__ */ import_react12.default.createElement(import_react_ui8.IconButton, {
826
+ })), /* @__PURE__ */ import_react13.default.createElement(import_react_ui9.IconButton, {
624
827
  icon: "ph--trash--regular",
625
828
  iconOnly: true,
626
829
  label: t("button remove"),
627
830
  onClick: () => handleRemove(index)
628
- })))), /* @__PURE__ */ import_react12.default.createElement("div", {
831
+ })))), /* @__PURE__ */ import_react13.default.createElement("div", {
629
832
  role: "none",
630
833
  className: "flex justify-between items-center plb-1"
631
- }, /* @__PURE__ */ import_react12.default.createElement(import_react_ui8.IconButton, {
834
+ }, /* @__PURE__ */ import_react13.default.createElement(import_react_ui9.IconButton, {
632
835
  icon: "ph--plus--regular",
633
836
  iconOnly: true,
634
837
  label: t("button add"),
@@ -652,23 +855,14 @@ var getInputComponent = (type, format) => {
652
855
  var FormField = ({ property, path, readonly, inline, lookupComponent, Custom }) => {
653
856
  const inputProps = useInputProps(path);
654
857
  const { ast, name, type, format, title, description, options, examples, array } = property;
655
- const label = (0, import_react11.useMemo)(() => title ?? (0, import_effect3.pipe)(name, import_String.capitalize), [
858
+ const label = (0, import_react12.useMemo)(() => title ?? (0, import_effect3.pipe)(name, import_String.capitalize), [
656
859
  title,
657
860
  name
658
861
  ]);
659
- const placeholder = (0, import_react11.useMemo)(() => examples?.length ? `Example: "${examples[0]}"` : description, [
862
+ const placeholder = (0, import_react12.useMemo)(() => examples?.length ? `Example: "${examples[0]}"` : description, [
660
863
  examples,
661
864
  description
662
865
  ]);
663
- if (array) {
664
- return /* @__PURE__ */ import_react11.default.createElement(ArrayField, {
665
- property,
666
- path,
667
- inputProps,
668
- readonly,
669
- Custom
670
- });
671
- }
672
866
  const FoundComponent = lookupComponent?.({
673
867
  prop: name,
674
868
  schema: import_echo_schema4.S.make(ast),
@@ -682,12 +876,42 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
682
876
  }
683
877
  });
684
878
  if (FoundComponent) {
685
- return /* @__PURE__ */ import_react11.default.createElement("div", null, FoundComponent);
879
+ return /* @__PURE__ */ import_react12.default.createElement("div", {
880
+ role: "none"
881
+ }, FoundComponent);
686
882
  }
687
883
  const jsonPath = (0, import_effect4.createJsonPath)(path ?? []);
688
- const InputComponent = Custom?.[jsonPath] || getInputComponent(type, format);
884
+ const CustomComponent = Custom?.[jsonPath];
885
+ if (CustomComponent) {
886
+ return (
887
+ // TODO(ZaymonFC): We should try to remove this div wrapper.
888
+ /* @__PURE__ */ import_react12.default.createElement("div", {
889
+ role: "none"
890
+ }, /* @__PURE__ */ import_react12.default.createElement(CustomComponent, {
891
+ type,
892
+ format,
893
+ label,
894
+ inputOnly: inline,
895
+ placeholder,
896
+ disabled: readonly,
897
+ ...inputProps
898
+ }))
899
+ );
900
+ }
901
+ if (array) {
902
+ return /* @__PURE__ */ import_react12.default.createElement(ArrayField, {
903
+ property,
904
+ path,
905
+ inputProps,
906
+ readonly,
907
+ Custom
908
+ });
909
+ }
910
+ const InputComponent = getInputComponent(type, format);
689
911
  if (InputComponent) {
690
- return /* @__PURE__ */ import_react11.default.createElement("div", null, /* @__PURE__ */ import_react11.default.createElement(InputComponent, {
912
+ return /* @__PURE__ */ import_react12.default.createElement("div", {
913
+ role: "none"
914
+ }, /* @__PURE__ */ import_react12.default.createElement(InputComponent, {
691
915
  type,
692
916
  format,
693
917
  label,
@@ -698,9 +922,9 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
698
922
  }));
699
923
  }
700
924
  if (options) {
701
- return /* @__PURE__ */ import_react11.default.createElement("div", {
925
+ return /* @__PURE__ */ import_react12.default.createElement("div", {
702
926
  role: "none"
703
- }, /* @__PURE__ */ import_react11.default.createElement(SelectInput, {
927
+ }, /* @__PURE__ */ import_react12.default.createElement(SelectInput, {
704
928
  type,
705
929
  format,
706
930
  disabled: readonly,
@@ -718,7 +942,9 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
718
942
  const baseNode = (0, import_effect4.findNode)(ast, import_effect4.isDiscriminatedUnion);
719
943
  const typeLiteral = baseNode ? (0, import_effect4.getDiscriminatedType)(baseNode, inputProps.getValue()) : (0, import_effect4.findNode)(ast, import_echo_schema4.AST.isTypeLiteral);
720
944
  if (typeLiteral) {
721
- return /* @__PURE__ */ import_react11.default.createElement("div", null, !inline && /* @__PURE__ */ import_react11.default.createElement("div", null, label), /* @__PURE__ */ import_react11.default.createElement(FormFields, {
945
+ return /* @__PURE__ */ import_react12.default.createElement("div", {
946
+ role: "none"
947
+ }, !inline && /* @__PURE__ */ import_react12.default.createElement("div", null, label), /* @__PURE__ */ import_react12.default.createElement(FormFields, {
722
948
  schema: import_echo_schema4.S.make(typeLiteral),
723
949
  path,
724
950
  readonly,
@@ -730,7 +956,7 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
730
956
  };
731
957
  var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custom }) => {
732
958
  const values = useFormValues(path);
733
- const properties = (0, import_react11.useMemo)(() => {
959
+ const properties = (0, import_react12.useMemo)(() => {
734
960
  const props = (0, import_schema3.getSchemaProperties)(schema.ast, values);
735
961
  const filtered = filter ? filter(props) : props;
736
962
  return sort ? filtered.sort((a, b) => sort.indexOf(a.name) - sort.indexOf(b.name)) : filtered;
@@ -740,11 +966,11 @@ var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custo
740
966
  filter,
741
967
  sort
742
968
  ]);
743
- return /* @__PURE__ */ import_react11.default.createElement("div", {
969
+ return /* @__PURE__ */ import_react12.default.createElement("div", {
744
970
  role: "form",
745
- className: (0, import_react_ui_theme5.mx)("flex flex-col w-full gap-2 py-2")
971
+ className: (0, import_react_ui_theme7.mx)("flex flex-col w-full gap-2")
746
972
  }, properties.map((property) => {
747
- return /* @__PURE__ */ import_react11.default.createElement(FormField, {
973
+ return /* @__PURE__ */ import_react12.default.createElement(FormField, {
748
974
  key: property.name,
749
975
  property,
750
976
  path: [
@@ -757,23 +983,33 @@ var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custo
757
983
  });
758
984
  }).filter(import_util3.isNotFalsy));
759
985
  };
760
- var Form = ({ classNames, schema, values: initialValues, path = [], readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, lookupComponent, Custom }) => {
761
- const onValid = (0, import_react7.useMemo)(() => autoSave ? onSave : void 0, [
986
+ var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, lookupComponent, Custom }) => {
987
+ const onValid = (0, import_react10.useMemo)(() => autoSave ? onSave : void 0, [
762
988
  autoSave,
763
989
  onSave
764
990
  ]);
765
- return /* @__PURE__ */ import_react7.default.createElement(FormProvider, {
991
+ (0, import_react10.useEffect)(() => {
992
+ if (autoFocus) {
993
+ const input = document.querySelector("input");
994
+ if (input) {
995
+ input.focus();
996
+ }
997
+ }
998
+ }, [
999
+ autoFocus
1000
+ ]);
1001
+ return /* @__PURE__ */ import_react10.default.createElement(FormProvider, {
766
1002
  schema,
767
1003
  initialValues,
768
1004
  onValuesChanged,
769
1005
  onValidate,
770
1006
  onValid,
771
1007
  onSave
772
- }, /* @__PURE__ */ import_react7.default.createElement("div", {
1008
+ }, /* @__PURE__ */ import_react10.default.createElement("div", {
773
1009
  role: "none",
774
- className: (0, import_react_ui_theme3.mx)("p-2", classNames),
1010
+ className: (0, import_react_ui_theme5.mx)("p-2", classNames),
775
1011
  "data-testid": testId
776
- }, /* @__PURE__ */ import_react7.default.createElement(FormFields, {
1012
+ }, /* @__PURE__ */ import_react10.default.createElement(FormFields, {
777
1013
  schema,
778
1014
  path,
779
1015
  readonly,
@@ -781,7 +1017,7 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
781
1017
  sort,
782
1018
  lookupComponent,
783
1019
  Custom
784
- }), (onCancel || onSave) && !autoSave && /* @__PURE__ */ import_react7.default.createElement(FormActions, {
1020
+ }), (onCancel || onSave) && !autoSave && /* @__PURE__ */ import_react10.default.createElement(FormActions, {
785
1021
  onCancel,
786
1022
  readonly
787
1023
  })));
@@ -851,7 +1087,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
851
1087
  type
852
1088
  };
853
1089
  }
854
- return props2;
1090
+ return _props;
855
1091
  });
856
1092
  }, [
857
1093
  schemas,
@@ -907,7 +1143,8 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
907
1143
  options: referenceSchema ? (0, import_schema.getSchemaProperties)(referenceSchema.ast).sort(import_schema.sortProperties).map((p) => ({
908
1144
  value: p.name
909
1145
  })) : []
910
- })
1146
+ }),
1147
+ ["options"]: (props2) => /* @__PURE__ */ import_react2.default.createElement(SelectOptionInput, props2)
911
1148
  }), [
912
1149
  t,
913
1150
  schemas,
@@ -919,7 +1156,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
919
1156
  props
920
1157
  }, {
921
1158
  F: __dxlog_file3,
922
- L: 173,
1159
+ L: 174,
923
1160
  S: void 0,
924
1161
  C: (f, a) => f(...a)
925
1162
  });
@@ -952,13 +1189,13 @@ var ViewMetaSchema = import_echo_schema7.S.Struct({
952
1189
  })
953
1190
  }).pipe(import_echo_schema7.S.mutable);
954
1191
  var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading = false, onTypenameChanged, onDelete }) => {
955
- const { t } = (0, import_react_ui9.useTranslation)(translationKey);
956
- const projection = (0, import_react13.useMemo)(() => new import_schema5.ViewProjection(schema, view), [
1192
+ const { t } = (0, import_react_ui10.useTranslation)(translationKey);
1193
+ const projection = (0, import_react14.useMemo)(() => new import_schema5.ViewProjection(schema, view), [
957
1194
  schema,
958
1195
  view
959
1196
  ]);
960
- const [field, setField] = (0, import_react13.useState)();
961
- const viewValues = (0, import_react13.useMemo)(() => {
1197
+ const [field, setField] = (0, import_react14.useState)();
1198
+ const viewValues = (0, import_react14.useMemo)(() => {
962
1199
  return {
963
1200
  name: view.name,
964
1201
  // TODO(burdon): Need to warn user of possible consequences of editing.
@@ -968,7 +1205,7 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
968
1205
  }, [
969
1206
  view
970
1207
  ]);
971
- const handleViewUpdate = (0, import_react13.useCallback)(({ name, typename }) => {
1208
+ const handleViewUpdate = (0, import_react14.useCallback)(({ name, typename }) => {
972
1209
  requestAnimationFrame(() => {
973
1210
  if (view.name !== name) {
974
1211
  view.name = name;
@@ -982,67 +1219,72 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
982
1219
  schema,
983
1220
  onTypenameChanged
984
1221
  ]);
985
- const handleSelect = (0, import_react13.useCallback)((field2) => {
1222
+ const handleSelect = (0, import_react14.useCallback)((field2) => {
986
1223
  setField((f) => f === field2 ? void 0 : field2);
987
1224
  }, []);
988
- const handleAdd = (0, import_react13.useCallback)(() => {
1225
+ const handleAdd = (0, import_react14.useCallback)(() => {
989
1226
  const field2 = projection.createFieldProjection();
990
1227
  setField(field2);
991
1228
  }, [
992
1229
  view
993
1230
  ]);
994
- const handleMove = (0, import_react13.useCallback)((fromIndex, toIndex) => {
995
- (0, import_util4.arrayMove)(view.fields, fromIndex, toIndex);
1231
+ const handleMove = (0, import_react14.useCallback)((fromIndex, toIndex) => {
1232
+ const fields = [
1233
+ ...view.fields
1234
+ ];
1235
+ const [moved] = fields.splice(fromIndex, 1);
1236
+ fields.splice(toIndex, 0, moved);
1237
+ view.fields = fields;
996
1238
  }, [
997
1239
  view.fields
998
1240
  ]);
999
- const handleClose = (0, import_react13.useCallback)(() => setField(void 0), []);
1000
- return /* @__PURE__ */ import_react13.default.createElement("div", {
1241
+ const handleClose = (0, import_react14.useCallback)(() => setField(void 0), []);
1242
+ return /* @__PURE__ */ import_react14.default.createElement("div", {
1001
1243
  role: "none",
1002
- className: (0, import_react_ui_theme7.mx)("flex flex-col w-full divide-y divide-separator", classNames)
1003
- }, /* @__PURE__ */ import_react13.default.createElement(Form, {
1244
+ className: (0, import_react_ui_theme9.mx)("flex flex-col w-full divide-y divide-separator", classNames)
1245
+ }, /* @__PURE__ */ import_react14.default.createElement(Form, {
1004
1246
  autoFocus: true,
1005
1247
  autoSave: true,
1006
1248
  schema: ViewMetaSchema,
1007
1249
  values: viewValues,
1008
1250
  onSave: handleViewUpdate
1009
- }), /* @__PURE__ */ import_react13.default.createElement("div", null, /* @__PURE__ */ import_react13.default.createElement("div", {
1251
+ }), /* @__PURE__ */ import_react14.default.createElement("div", null, /* @__PURE__ */ import_react14.default.createElement("div", {
1010
1252
  role: "none",
1011
1253
  className: "p-2"
1012
- }, /* @__PURE__ */ import_react13.default.createElement("label", {
1013
- className: (0, import_react_ui_theme7.mx)(import_react_ui_theme7.inputTextLabel)
1014
- }, t("fields label"))), /* @__PURE__ */ import_react13.default.createElement(import_react_ui_list.List.Root, {
1254
+ }, /* @__PURE__ */ import_react14.default.createElement("label", {
1255
+ className: (0, import_react_ui_theme9.mx)(import_react_ui_theme9.inputTextLabel)
1256
+ }, t("fields label"))), /* @__PURE__ */ import_react14.default.createElement(import_react_ui_list2.List.Root, {
1015
1257
  items: view.fields,
1016
1258
  isItem: import_echo_schema7.S.is(import_schema5.FieldSchema),
1017
1259
  getId: (field2) => field2.id,
1018
1260
  onMove: handleMove
1019
- }, ({ items: fields }) => /* @__PURE__ */ import_react13.default.createElement(import_react13.default.Fragment, null, showHeading && /* @__PURE__ */ import_react13.default.createElement("div", {
1261
+ }, ({ items: fields }) => /* @__PURE__ */ import_react14.default.createElement(import_react14.default.Fragment, null, showHeading && /* @__PURE__ */ import_react14.default.createElement("div", {
1020
1262
  role: "heading",
1021
1263
  className: grid
1022
- }, /* @__PURE__ */ import_react13.default.createElement("div", null), /* @__PURE__ */ import_react13.default.createElement("div", {
1264
+ }, /* @__PURE__ */ import_react14.default.createElement("div", null), /* @__PURE__ */ import_react14.default.createElement("div", {
1023
1265
  className: "flex items-center text-sm"
1024
- }, t("field path label"))), /* @__PURE__ */ import_react13.default.createElement("div", {
1266
+ }, t("field path label"))), /* @__PURE__ */ import_react14.default.createElement("div", {
1025
1267
  role: "list",
1026
1268
  className: "flex flex-col w-full"
1027
- }, fields?.map((field2) => /* @__PURE__ */ import_react13.default.createElement(import_react_ui_list.List.Item, {
1269
+ }, fields?.map((field2) => /* @__PURE__ */ import_react14.default.createElement(import_react_ui_list2.List.Item, {
1028
1270
  key: field2.id,
1029
1271
  item: field2,
1030
- classNames: (0, import_react_ui_theme7.mx)(grid, import_react_ui_theme7.ghostHover, "cursor-pointer")
1031
- }, /* @__PURE__ */ import_react13.default.createElement(import_react_ui_list.List.ItemDragHandle, null), /* @__PURE__ */ import_react13.default.createElement(import_react_ui_list.List.ItemTitle, {
1272
+ classNames: (0, import_react_ui_theme9.mx)(grid, import_react_ui_theme9.ghostHover, "cursor-pointer")
1273
+ }, /* @__PURE__ */ import_react14.default.createElement(import_react_ui_list2.List.ItemDragHandle, null), /* @__PURE__ */ import_react14.default.createElement(import_react_ui_list2.List.ItemTitle, {
1032
1274
  onClick: () => handleSelect(field2)
1033
- }, field2.path), /* @__PURE__ */ import_react13.default.createElement(import_react_ui_list.List.ItemDeleteButton, {
1275
+ }, field2.path), /* @__PURE__ */ import_react14.default.createElement(import_react_ui_list2.List.ItemDeleteButton, {
1034
1276
  disabled: view.fields.length <= 1,
1035
1277
  onClick: () => onDelete(field2.id)
1036
- }))))))), field && /* @__PURE__ */ import_react13.default.createElement(FieldEditor, {
1278
+ }))))))), field && /* @__PURE__ */ import_react14.default.createElement(FieldEditor, {
1037
1279
  key: field.id,
1038
1280
  view,
1039
1281
  projection,
1040
1282
  field,
1041
1283
  registry,
1042
1284
  onSave: handleClose
1043
- }), !readonly && !field && /* @__PURE__ */ import_react13.default.createElement("div", {
1285
+ }), !readonly && !field && /* @__PURE__ */ import_react14.default.createElement("div", {
1044
1286
  className: "flex p-2 justify-center"
1045
- }, /* @__PURE__ */ import_react13.default.createElement(import_react_ui9.IconButton, {
1287
+ }, /* @__PURE__ */ import_react14.default.createElement(import_react_ui10.IconButton, {
1046
1288
  icon: "ph--plus--regular",
1047
1289
  label: t("button add property"),
1048
1290
  onClick: handleAdd,
@@ -1267,6 +1509,7 @@ var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1267
1509
  // Annotate the CommonJS export names for ESM import in node:
1268
1510
  0 && (module.exports = {
1269
1511
  BooleanInput,
1512
+ DeprecatedFormContainer,
1270
1513
  DeprecatedFormInput,
1271
1514
  FieldEditor,
1272
1515
  Form,
@@ -1274,6 +1517,7 @@ var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1274
1517
  InputHeader,
1275
1518
  NumberInput,
1276
1519
  SelectInput,
1520
+ SelectOptionInput,
1277
1521
  TextInput,
1278
1522
  TupleInput,
1279
1523
  ViewEditor,
@@ -1284,6 +1528,7 @@ var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1284
1528
  parseValue,
1285
1529
  pathNotUniqueError,
1286
1530
  translations,
1287
- useForm
1531
+ useForm,
1532
+ useFormValues
1288
1533
  });
1289
1534
  //# sourceMappingURL=index.cjs.map