@dxos/react-ui-form 0.7.5-main.9d2a38b → 0.7.5-main.e94eead

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 (83) hide show
  1. package/dist/lib/browser/index.mjs +1014 -571
  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 +1031 -599
  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 +1014 -571
  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 +1 -2
  11. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
  12. package/dist/types/src/components/Form/ArrayField.d.ts +15 -0
  13. package/dist/types/src/components/Form/ArrayField.d.ts.map +1 -0
  14. package/dist/types/src/components/Form/Defaults.d.ts +6 -7
  15. package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
  16. package/dist/types/src/components/Form/Form.d.ts +12 -21
  17. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  18. package/dist/types/src/components/Form/Form.stories.d.ts +2 -1
  19. package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
  20. package/dist/types/src/components/Form/FormActions.d.ts +6 -0
  21. package/dist/types/src/components/Form/FormActions.d.ts.map +1 -0
  22. package/dist/types/src/components/Form/FormContent.d.ts +25 -0
  23. package/dist/types/src/components/Form/FormContent.d.ts.map +1 -0
  24. package/dist/types/src/components/Form/FormContext.d.ts +23 -0
  25. package/dist/types/src/components/Form/FormContext.d.ts.map +1 -0
  26. package/dist/types/src/components/Form/Input.d.ts +7 -8
  27. package/dist/types/src/components/Form/Input.d.ts.map +1 -1
  28. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts +1 -3
  29. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts.map +1 -1
  30. package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts +3 -0
  31. package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts.map +1 -0
  32. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts +7 -0
  33. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts.map +1 -0
  34. package/dist/types/src/components/Form/custom/TupleInput.d.ts +2 -4
  35. package/dist/types/src/components/Form/custom/TupleInput.d.ts.map +1 -1
  36. package/dist/types/src/components/Form/custom/index.d.ts +1 -0
  37. package/dist/types/src/components/Form/custom/index.d.ts.map +1 -1
  38. package/dist/types/src/components/Form/factory.d.ts +2 -2
  39. package/dist/types/src/components/Form/factory.d.ts.map +1 -1
  40. package/dist/types/src/components/Form/index.d.ts +2 -0
  41. package/dist/types/src/components/Form/index.d.ts.map +1 -1
  42. package/dist/types/src/components/ViewEditor/Test.stories.d.ts +1 -2
  43. package/dist/types/src/components/ViewEditor/Test.stories.d.ts.map +1 -1
  44. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +1 -2
  45. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
  46. package/dist/types/src/components/deprecated/Form.d.ts +1 -2
  47. package/dist/types/src/components/deprecated/Form.d.ts.map +1 -1
  48. package/dist/types/src/components/deprecated/Form.stories.d.ts +1 -2
  49. package/dist/types/src/components/deprecated/Form.stories.d.ts.map +1 -1
  50. package/dist/types/src/components/deprecated/FormInput.d.ts +6 -1
  51. package/dist/types/src/components/deprecated/FormInput.d.ts.map +1 -1
  52. package/dist/types/src/components/testing.d.ts +3 -3
  53. package/dist/types/src/components/testing.d.ts.map +1 -1
  54. package/dist/types/src/hooks/useForm.d.ts +11 -11
  55. package/dist/types/src/hooks/useForm.d.ts.map +1 -1
  56. package/dist/types/src/translations.d.ts +6 -0
  57. package/dist/types/src/translations.d.ts.map +1 -1
  58. package/dist/types/src/util/field.d.ts.map +1 -1
  59. package/dist/types/src/util/formatting.d.ts.map +1 -1
  60. package/package.json +29 -27
  61. package/src/components/FieldEditor/FieldEditor.stories.tsx +1 -1
  62. package/src/components/FieldEditor/FieldEditor.tsx +7 -6
  63. package/src/components/Form/ArrayField.tsx +111 -0
  64. package/src/components/Form/Defaults.tsx +78 -34
  65. package/src/components/Form/Form.stories.tsx +15 -5
  66. package/src/components/Form/Form.tsx +50 -355
  67. package/src/components/Form/FormActions.tsx +41 -0
  68. package/src/components/Form/FormContent.tsx +170 -0
  69. package/src/components/Form/FormContext.tsx +96 -0
  70. package/src/components/Form/Input.tsx +5 -6
  71. package/src/components/Form/custom/GeoPointInput.tsx +44 -23
  72. package/src/components/Form/custom/SelectOptionsInput.stories.tsx +58 -0
  73. package/src/components/Form/custom/SelectOptionsInput.tsx +190 -0
  74. package/src/components/Form/custom/TupleInput.tsx +5 -9
  75. package/src/components/Form/custom/index.ts +1 -0
  76. package/src/components/Form/factory.tsx +6 -7
  77. package/src/components/Form/index.ts +3 -0
  78. package/src/components/ViewEditor/ViewEditor.tsx +7 -4
  79. package/src/components/deprecated/FormInput.tsx +20 -7
  80. package/src/hooks/useForm.ts +116 -79
  81. package/src/translations.ts +9 -1
  82. package/src/util/field.ts +19 -1
  83. package/src/util/formatting.ts +29 -1
@@ -29,14 +29,16 @@ 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,
35
- FormActions: () => FormActions,
36
36
  GeoPointInput: () => GeoPointInput,
37
37
  InputHeader: () => InputHeader,
38
+ MarkdownInput: () => MarkdownInput,
38
39
  NumberInput: () => NumberInput,
39
40
  SelectInput: () => SelectInput,
41
+ SelectOptionInput: () => SelectOptionInput,
40
42
  TextInput: () => TextInput,
41
43
  TupleInput: () => TupleInput,
42
44
  ViewEditor: () => ViewEditor,
@@ -47,53 +49,78 @@ __export(node_exports, {
47
49
  parseValue: () => parseValue,
48
50
  pathNotUniqueError: () => pathNotUniqueError,
49
51
  translations: () => translations_default,
50
- useForm: () => useForm
52
+ useForm: () => useForm,
53
+ useFormValues: () => useFormValues
51
54
  });
52
55
  module.exports = __toCommonJS(node_exports);
53
56
  var import_react = __toESM(require("react"));
54
57
  var import_react_ui = require("@dxos/react-ui");
58
+ var import_react_ui_theme = require("@dxos/react-ui-theme");
55
59
  var import_react2 = __toESM(require("react"));
56
60
  var import_echo_schema = require("@dxos/echo-schema");
57
61
  var import_log = require("@dxos/log");
58
62
  var import_react_ui2 = require("@dxos/react-ui");
59
63
  var import_schema = require("@dxos/schema");
60
64
  var import_react3 = __toESM(require("react"));
65
+ var import_debug = require("@dxos/debug");
66
+ var import_echo_schema2 = require("@dxos/echo-schema");
67
+ var import_effect = require("@dxos/effect");
68
+ var import_react4 = require("react");
69
+ var import_echo_schema3 = require("@dxos/echo-schema");
70
+ var import_effect2 = require("@dxos/effect");
71
+ var import_invariant = require("@dxos/invariant");
72
+ var import_log2 = require("@dxos/log");
73
+ var import_schema2 = require("@dxos/schema");
74
+ var import_react5 = __toESM(require("react"));
75
+ var import_echo_schema4 = require("@dxos/echo-schema");
61
76
  var import_react_ui3 = require("@dxos/react-ui");
62
77
  var import_util = require("@dxos/util");
63
- var import_react4 = __toESM(require("react"));
78
+ var import_react6 = __toESM(require("react"));
64
79
  var import_react_ui4 = require("@dxos/react-ui");
65
- var import_react_ui_theme = require("@dxos/react-ui-theme");
66
- var import_react5 = __toESM(require("react"));
67
- var import_react_ui5 = require("@dxos/react-ui");
68
80
  var import_react_ui_theme2 = require("@dxos/react-ui-theme");
69
- var import_util2 = require("@dxos/util");
70
- var import_react6 = __toESM(require("react"));
71
- var import_react_ui6 = require("@dxos/react-ui");
72
- var import_effect = require("effect");
73
- var import_String = require("effect/String");
74
81
  var import_react7 = __toESM(require("react"));
75
- var import_echo_schema2 = require("@dxos/echo-schema");
76
- var import_effect2 = require("@dxos/effect");
77
- var import_log2 = require("@dxos/log");
78
- var import_react_ui7 = require("@dxos/react-ui");
82
+ var import_keys = require("@dxos/keys");
83
+ var import_react_ui5 = require("@dxos/react-ui");
84
+ var import_react_ui_list = require("@dxos/react-ui-list");
85
+ var import_react_ui_pickers = require("@dxos/react-ui-pickers");
79
86
  var import_react_ui_theme3 = require("@dxos/react-ui-theme");
80
- var import_schema2 = require("@dxos/schema");
81
- var import_util3 = require("@dxos/util");
82
- var import_echo_schema3 = require("@dxos/echo-schema");
83
- var import_react8 = require("react");
84
- var import_echo_schema4 = require("@dxos/echo-schema");
85
- var import_invariant = require("@dxos/invariant");
86
- var import_log3 = require("@dxos/log");
87
- var import_schema3 = require("@dxos/schema");
87
+ var import_react8 = __toESM(require("react"));
88
+ var import_react_ui6 = require("@dxos/react-ui");
89
+ var import_react_ui_theme4 = require("@dxos/react-ui-theme");
90
+ var import_util2 = require("@dxos/util");
88
91
  var import_react9 = __toESM(require("react"));
89
- var import_echo_schema5 = require("@dxos/echo-schema");
92
+ var import_react_ui7 = require("@dxos/react-ui");
93
+ var import_react10 = __toESM(require("react"));
94
+ var import_react_ui_theme5 = require("@dxos/react-ui-theme");
95
+ var import_react11 = __toESM(require("react"));
90
96
  var import_react_ui8 = require("@dxos/react-ui");
91
- var import_react_ui_list = require("@dxos/react-ui-list");
92
- var import_react_ui_theme4 = require("@dxos/react-ui-theme");
93
- var import_schema4 = require("@dxos/schema");
94
- var import_util4 = require("@dxos/util");
97
+ var import_react_ui_theme6 = require("@dxos/react-ui-theme");
98
+ var import_effect3 = require("effect");
99
+ var import_String = require("effect/String");
100
+ var import_react12 = __toESM(require("react"));
101
+ var import_echo_schema5 = require("@dxos/echo-schema");
102
+ var import_effect4 = require("@dxos/effect");
103
+ var import_react_ui_theme7 = require("@dxos/react-ui-theme");
104
+ var import_schema3 = require("@dxos/schema");
105
+ var import_util3 = require("@dxos/util");
106
+ var import_effect5 = require("effect");
107
+ var import_String2 = require("effect/String");
108
+ var import_react13 = __toESM(require("react"));
95
109
  var import_echo_schema6 = require("@dxos/echo-schema");
110
+ var import_effect6 = require("@dxos/effect");
111
+ var import_invariant2 = require("@dxos/invariant");
112
+ var import_react_ui9 = require("@dxos/react-ui");
113
+ var import_react_ui_theme8 = require("@dxos/react-ui-theme");
114
+ var import_schema4 = require("@dxos/schema");
96
115
  var import_echo_schema7 = require("@dxos/echo-schema");
116
+ var import_react14 = __toESM(require("react"));
117
+ var import_echo_schema8 = require("@dxos/echo-schema");
118
+ var import_react_ui10 = require("@dxos/react-ui");
119
+ var import_react_ui_list2 = require("@dxos/react-ui-list");
120
+ var import_react_ui_theme9 = require("@dxos/react-ui-theme");
121
+ var import_schema5 = require("@dxos/schema");
122
+ var import_echo_schema9 = require("@dxos/echo-schema");
123
+ var import_echo_schema10 = require("@dxos/echo-schema");
97
124
  var translationKey = "react-ui-form";
98
125
  var translations_default = [
99
126
  {
@@ -124,12 +151,13 @@ var translations_default = [
124
151
  "format hostname": "Hostname",
125
152
  "format integer": "Integer",
126
153
  "format json": "JSON",
127
- "format latlng": "LatLng",
154
+ "format latlng": "Geopoint",
128
155
  "format markdown": "Markdown",
129
156
  "format percent": "Percent",
130
157
  "format ref": "Reference",
131
158
  "format regex": "RegExp",
132
159
  "format string": "String",
160
+ "format single-select": "Select",
133
161
  "format text": "Long text",
134
162
  "format time": "Time",
135
163
  "format timestamp": "Timestamp",
@@ -139,11 +167,26 @@ var translations_default = [
139
167
  "format uuid": "UUID",
140
168
  // Placeholders
141
169
  "placeholder latitude": "Latitude",
142
- "placeholder longitude": "Longitude"
170
+ "placeholder longitude": "Longitude",
171
+ // SelectOptionsInput
172
+ "select option label": "Label",
173
+ "select option label placeholder": "Option label",
174
+ "select option color": "Color",
175
+ "select option delete": "Delete",
176
+ "select option add": "Add option"
143
177
  }
144
178
  }
145
179
  }
146
180
  ];
181
+ var DeprecatedFormContainer = ({ children, classNames }) => {
182
+ return /* @__PURE__ */ import_react.default.createElement("div", {
183
+ role: "none",
184
+ className: "w-full p-4 justify-center overflow-x-hidden overflow-y-auto"
185
+ }, /* @__PURE__ */ import_react.default.createElement("div", {
186
+ role: "form",
187
+ className: (0, import_react_ui_theme.mx)("flex flex-col", import_react_ui_theme.textBlockWidth, classNames)
188
+ }, children));
189
+ };
147
190
  var DeprecatedFormInput = ({ label, description, secondary, children }) => {
148
191
  const primary = /* @__PURE__ */ import_react.default.createElement("div", {
149
192
  role: "none",
@@ -152,185 +195,48 @@ var DeprecatedFormInput = ({ label, description, secondary, children }) => {
152
195
  role: "none",
153
196
  className: "flex flex-col w-full"
154
197
  }, /* @__PURE__ */ import_react.default.createElement(import_react_ui.Input.Label, {
155
- classNames: "flex min-h-[40px] items-center"
198
+ classNames: "flex min-bs-[--rail-action] items-center",
199
+ style: {
200
+ fontSize: "unset"
201
+ }
156
202
  }, label), description && /* @__PURE__ */ import_react.default.createElement(import_react_ui.Input.DescriptionAndValidation, {
157
203
  classNames: "mbs-0.5"
158
204
  }, /* @__PURE__ */ import_react.default.createElement(import_react_ui.Input.Description, null, description))), /* @__PURE__ */ import_react.default.createElement("div", {
159
205
  role: "none"
160
206
  }, /* @__PURE__ */ import_react.default.createElement("div", {
161
207
  role: "none",
162
- className: "flex min-h-[40px] items-center"
208
+ className: "flex min-bs-[--rail-action] items-center"
163
209
  }, children))));
164
210
  if (secondary) {
165
211
  return /* @__PURE__ */ import_react.default.createElement("div", {
166
- role: "none",
167
- className: "flex flex-col w-full"
212
+ role: "none"
168
213
  }, primary, secondary);
169
214
  }
170
215
  return primary;
171
216
  };
172
- var InputHeader = ({ children, error }) => {
173
- return /* @__PURE__ */ import_react4.default.createElement("div", {
174
- role: "none",
175
- className: "flex justify-between items-center mb-1"
176
- }, children, error && /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Tooltip.Root, null, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Tooltip.Trigger, {
177
- asChild: true
178
- }, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Icon, {
179
- icon: "ph--warning--regular",
180
- size: 4,
181
- classNames: import_react_ui_theme.errorText
182
- })), /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Tooltip.Content, {
183
- side: "bottom"
184
- }, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Tooltip.Arrow, null), error)));
185
- };
186
- var GeoPointInput = ({ property, type, label, disabled, getStatus, getValue: getValue2, onValueChange, onBlur }) => {
187
- const { t } = (0, import_react_ui3.useTranslation)(translationKey);
188
- const { status, error } = getStatus?.(property);
189
- const [lng = 0, lat = 0] = getValue2(property) ?? [];
190
- return /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.Input.Root, {
191
- validationValence: status
192
- }, /* @__PURE__ */ import_react3.default.createElement(InputHeader, {
193
- error
194
- }, /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.Input.Label, null, label)), /* @__PURE__ */ import_react3.default.createElement("div", {
195
- className: "grid grid-cols-2 gap-2"
196
- }, /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.Input.TextInput, {
197
- type: "number",
198
- disabled,
199
- placeholder: t("placeholder longitude"),
200
- value: lng,
201
- onChange: (event) => onValueChange(property, type, [
202
- lat,
203
- (0, import_util.safeParseFloat)(event.target.value, 0)
204
- ]),
205
- onBlur
206
- }), /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.Input.TextInput, {
207
- type: "number",
208
- disabled,
209
- placeholder: t("placeholder latitude"),
210
- value: lat,
211
- onChange: (event) => onValueChange(property, type, [
212
- (0, import_util.safeParseFloat)(event.target.value, 0),
213
- lng
214
- ]),
215
- onBlur
216
- })));
217
- };
218
- var gridCols = [
219
- "grid-cols-1",
220
- "grid-cols-2",
221
- "grid-cols-3",
222
- "grid-cols-4"
223
- ];
224
- var TupleInput = ({ binding, property, type, label, disabled, getStatus, getValue: getValue2, onValueChange, onBlur }) => {
225
- const { status, error } = getStatus?.(property);
226
- const values = getValue2(property) ?? {};
227
- return /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Input.Root, {
228
- validationValence: status
229
- }, /* @__PURE__ */ import_react5.default.createElement(InputHeader, {
230
- error
231
- }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Input.Label, null, label)), /* @__PURE__ */ import_react5.default.createElement("div", {
232
- className: (0, import_react_ui_theme2.mx)("grid gap-2", gridCols[binding.length - 1])
233
- }, binding.map((prop) => /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Input.TextInput, {
234
- key: prop,
235
- type: "number",
236
- disabled,
237
- value: values[prop],
238
- onChange: (event) => onValueChange(property, type, {
239
- ...values,
240
- [prop]: (0, import_util2.safeParseFloat)(event.target.value, 0)
241
- }),
242
- onBlur
243
- }))));
244
- };
245
- var TextInput = ({ property, type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue2, onValueChange, onBlur }) => {
246
- const { status, error } = getStatus?.(property);
247
- return /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Root, {
248
- validationValence: status
249
- }, !inputOnly && /* @__PURE__ */ import_react6.default.createElement(InputHeader, {
250
- error
251
- }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Label, null, label)), /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.TextInput, {
252
- disabled,
253
- placeholder,
254
- value: getValue2(property) ?? "",
255
- onChange: (event) => onValueChange(property, type, event.target.value),
256
- onBlur
257
- }), inputOnly && /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Validation, null, error));
258
- };
259
- var NumberInput = ({ property, type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue2, onValueChange, onBlur }) => {
260
- const { status, error } = getStatus?.(property);
261
- return /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Root, {
262
- validationValence: status
263
- }, !inputOnly && /* @__PURE__ */ import_react6.default.createElement(InputHeader, {
264
- error
265
- }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Label, null, label)), /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.TextInput, {
266
- type: "number",
267
- disabled,
268
- placeholder,
269
- value: getValue2(property) ?? 0,
270
- onChange: (event) => onValueChange(property, type, event.target.value),
271
- onBlur
272
- }), inputOnly && /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.DescriptionAndValidation, null, error));
273
- };
274
- var BooleanInput = ({ property, type, label, inputOnly, getStatus, getValue: getValue2, onValueChange }) => {
275
- const { status, error } = getStatus?.(property);
276
- return /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Root, {
277
- validationValence: status
278
- }, !inputOnly && /* @__PURE__ */ import_react6.default.createElement(InputHeader, {
279
- error
280
- }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Label, null, label)), /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Switch, {
281
- checked: getValue2(property),
282
- onCheckedChange: (value) => onValueChange(property, type, value)
283
- }), inputOnly && /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.DescriptionAndValidation, null, error));
284
- };
285
- var SelectInput = ({ property, type, label, inputOnly, disabled, placeholder, options, getStatus, getValue: getValue2, onValueChange }) => {
286
- const { status, error } = getStatus?.(property);
287
- return /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Root, {
288
- validationValence: status
289
- }, !inputOnly && /* @__PURE__ */ import_react6.default.createElement(InputHeader, {
290
- error
291
- }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Label, null, label)), /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Select.Root, {
292
- value: getValue2(property),
293
- onValueChange: (value) => onValueChange(property, type, value)
294
- }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Select.TriggerButton, {
295
- classNames: "is-full",
296
- disabled,
297
- placeholder
298
- }), /* @__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 }) => (
299
- // NOTE: Numeric values are converted to and from strings.
300
- /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Select.Option, {
301
- key: String(value),
302
- value: String(value)
303
- }, label2 ?? String(value))
304
- )))))), inputOnly && /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.DescriptionAndValidation, null, error));
305
- };
306
- var getInputComponent = (type, format) => {
307
- switch (format) {
308
- case import_echo_schema3.FormatEnum.LatLng:
309
- return GeoPointInput;
310
- }
311
- switch (type) {
312
- case "string":
313
- return TextInput;
314
- case "number":
315
- return NumberInput;
316
- case "boolean":
317
- return BooleanInput;
318
- }
319
- };
320
217
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/hooks/useForm.ts";
321
218
  var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, onSave }) => {
322
- const [values, setValues] = (0, import_react8.useState)(initialValues);
323
- (0, import_react8.useEffect)(() => {
219
+ (0, import_invariant.invariant)(import_effect2.AST.isTypeLiteral(schema.ast), void 0, {
220
+ F: __dxlog_file,
221
+ L: 92,
222
+ S: void 0,
223
+ A: [
224
+ "AST.isTypeLiteral(schema.ast)",
225
+ ""
226
+ ]
227
+ });
228
+ const [values, setValues] = (0, import_react4.useState)(initialValues);
229
+ (0, import_react4.useEffect)(() => {
324
230
  setValues(initialValues);
325
231
  }, [
326
232
  initialValues
327
233
  ]);
328
- const [touched, setTouched] = (0, import_react8.useState)(createKeySet(initialValues, false));
329
- const [changed, setChanged] = (0, import_react8.useState)(createKeySet(initialValues, false));
330
- const [errors, setErrors] = (0, import_react8.useState)({});
331
- const [saving, setSaving] = (0, import_react8.useState)(false);
332
- const validate = (0, import_react8.useCallback)((values2) => {
333
- let errors2 = (0, import_schema3.validateSchema)(schema, values2) ?? [];
234
+ const [touched, setTouched] = (0, import_react4.useState)(createKeySet(initialValues, false));
235
+ const [changed, setChanged] = (0, import_react4.useState)(createKeySet(initialValues, false));
236
+ const [errors, setErrors] = (0, import_react4.useState)({});
237
+ const [saving, setSaving] = (0, import_react4.useState)(false);
238
+ const validate = (0, import_react4.useCallback)((values2) => {
239
+ let errors2 = (0, import_schema2.validateSchema)(schema, values2) ?? [];
334
240
  if (errors2.length === 0 && onValidate) {
335
241
  const validatedValues = values2;
336
242
  errors2 = onValidate(validatedValues) ?? [];
@@ -342,11 +248,11 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
342
248
  schema,
343
249
  onValidate
344
250
  ]);
345
- const [schemaDirty, setSchemaDirty] = (0, import_react8.useState)(false);
346
- (0, import_react8.useEffect)(() => setSchemaDirty(true), [
251
+ const [schemaDirty, setSchemaDirty] = (0, import_react4.useState)(false);
252
+ (0, import_react4.useEffect)(() => setSchemaDirty(true), [
347
253
  schema
348
254
  ]);
349
- (0, import_react8.useEffect)(() => {
255
+ (0, import_react4.useEffect)(() => {
350
256
  if (schemaDirty) {
351
257
  validate(values);
352
258
  setSchemaDirty(false);
@@ -355,13 +261,18 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
355
261
  values,
356
262
  schemaDirty
357
263
  ]);
358
- const canSave = (0, import_react8.useMemo)(() => !saving && Object.keys(values).every((property) => touched[property] === false || !errors[property]), [
359
- values,
264
+ const formIsValid = (0, import_react4.useMemo)(() => {
265
+ return Object.keys(errors).length === 0;
266
+ }, [
267
+ errors
268
+ ]);
269
+ const canSave = (0, import_react4.useMemo)(() => !saving && // Check if any error paths that are touched have errors.
270
+ !Object.entries(touched).some(([path, isTouched]) => isTouched && Object.keys(errors).some((errorPath) => errorPath === path || errorPath.startsWith(`${path}.`) || errorPath.startsWith(`${path}[`))), [
360
271
  touched,
361
272
  errors,
362
273
  saving
363
274
  ]);
364
- const handleSave = (0, import_react8.useCallback)(async () => {
275
+ const handleSave = (0, import_react4.useCallback)(async () => {
365
276
  if (validate(values)) {
366
277
  setSaving(true);
367
278
  try {
@@ -378,38 +289,44 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
378
289
  onSave,
379
290
  changed
380
291
  ]);
381
- const getStatus = (0, import_react8.useCallback)((property) => ({
382
- status: errors[property] ? "error" : void 0,
383
- error: errors[property] ? errors[property] : void 0
384
- }), [
385
- touched,
292
+ const getStatus = (0, import_react4.useCallback)((path) => {
293
+ const jsonPath = Array.isArray(path) ? (0, import_effect2.createJsonPath)(path) : path;
294
+ const matchingError = Object.entries(errors).find(([errorPath]) => errorPath === jsonPath || errorPath.startsWith(`${jsonPath}.`) || errorPath.startsWith(`${jsonPath}[`));
295
+ return {
296
+ status: matchingError ? "error" : void 0,
297
+ error: matchingError ? matchingError[1] : void 0
298
+ };
299
+ }, [
386
300
  errors
387
301
  ]);
388
- const getFormValue = (property) => {
389
- return (0, import_echo_schema4.getValue)(values, property);
390
- };
391
- const onValueChange = (property, type, value) => {
302
+ const getFormValue = (0, import_react4.useCallback)((path) => {
303
+ return (0, import_echo_schema3.getValue)(values, (0, import_effect2.createJsonPath)(path));
304
+ }, [
305
+ values
306
+ ]);
307
+ const onValueChange = (0, import_react4.useCallback)((path, type, value) => {
308
+ const jsonPath = (0, import_effect2.createJsonPath)(path);
392
309
  let parsedValue = value;
393
310
  try {
394
311
  if (type === "number") {
395
312
  parsedValue = parseFloat(value) || 0;
396
313
  }
397
314
  } catch (err) {
398
- import_log3.log.catch(err, void 0, {
315
+ import_log2.log.catch(err, void 0, {
399
316
  F: __dxlog_file,
400
- L: 178,
317
+ L: 202,
401
318
  S: void 0,
402
319
  C: (f, a) => f(...a)
403
320
  });
404
321
  parsedValue = void 0;
405
322
  }
406
323
  const newValues = {
407
- ...(0, import_echo_schema4.setValue)(values, property, parsedValue)
324
+ ...(0, import_echo_schema3.setValue)(values, jsonPath, parsedValue)
408
325
  };
409
326
  setValues(newValues);
410
327
  setChanged((prev) => ({
411
328
  ...prev,
412
- [property]: true
329
+ [jsonPath]: true
413
330
  }));
414
331
  onValuesChanged?.(newValues);
415
332
  const isValid = validate(newValues);
@@ -418,40 +335,57 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
418
335
  changed
419
336
  });
420
337
  }
421
- };
422
- const onBlur = (0, import_react8.useCallback)((event) => {
423
- const { name } = event.target;
338
+ }, [
339
+ values,
340
+ onValuesChanged,
341
+ validate,
342
+ onValid,
343
+ changed
344
+ ]);
345
+ const onTouched = (0, import_react4.useCallback)((path) => {
346
+ const jsonPath = (0, import_effect2.createJsonPath)(path);
424
347
  setTouched((touched2) => ({
425
348
  ...touched2,
426
- [name]: true
349
+ [jsonPath]: true
427
350
  }));
428
- if (event.relatedTarget?.getAttribute("type") === "submit") {
429
- setTouched(createKeySet(values, true));
430
- }
431
351
  validate(values);
432
352
  }, [
433
353
  validate,
434
354
  values
435
355
  ]);
436
- return {
356
+ return (0, import_react4.useMemo)(() => ({
437
357
  // State.
438
358
  values,
439
359
  errors,
440
360
  touched,
441
361
  changed,
442
362
  canSave,
363
+ formIsValid,
364
+ // Actions.
443
365
  handleSave,
444
366
  // Field utils.
445
367
  getStatus,
446
368
  getValue: getFormValue,
447
369
  onValueChange,
448
- onBlur
449
- };
370
+ onTouched
371
+ }), [
372
+ values,
373
+ errors,
374
+ touched,
375
+ changed,
376
+ canSave,
377
+ formIsValid,
378
+ handleSave,
379
+ getStatus,
380
+ getFormValue,
381
+ onValueChange,
382
+ onTouched
383
+ ]);
450
384
  };
451
385
  var createKeySet = (obj, value) => {
452
386
  (0, import_invariant.invariant)(obj, void 0, {
453
387
  F: __dxlog_file,
454
- L: 229,
388
+ L: 264,
455
389
  S: void 0,
456
390
  A: [
457
391
  "obj",
@@ -465,322 +399,772 @@ var createKeySet = (obj, value) => {
465
399
  };
466
400
  var flatMap = (errors) => {
467
401
  return errors.reduce((result, { path, message }) => {
468
- if (!(path in result)) {
469
- result[path] = message;
402
+ const jsonPath = (0, import_effect2.fromEffectValidationPath)(path);
403
+ if (!(jsonPath in result)) {
404
+ result[jsonPath] = message;
470
405
  }
471
406
  return result;
472
407
  }, {});
473
408
  };
474
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/Form/Form.tsx";
475
- var padding = "px-2";
476
- var Form = ({ classNames, schema, values: initialValues, path = [], readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, lookupComponent, Custom }) => {
477
- const onValid = (0, import_react7.useMemo)(() => autoSave ? onSave : void 0, [
478
- autoSave,
479
- onSave
409
+ var FormContext = /* @__PURE__ */ (0, import_react3.createContext)(void 0);
410
+ var useFormContext = () => {
411
+ return (0, import_react3.useContext)(FormContext) ?? (0, import_debug.raise)(new Error("Missing FormContext"));
412
+ };
413
+ var useFormValues = (path = []) => {
414
+ const { values: formValues } = useFormContext();
415
+ const jsonPath = (0, import_effect.createJsonPath)(path);
416
+ return (0, import_echo_schema2.getValue)(formValues, jsonPath);
417
+ };
418
+ var useInputProps = (path = []) => {
419
+ const { getStatus, getValue: getFormValue, onValueChange, onTouched } = useFormContext();
420
+ const stablePath = (0, import_react3.useMemo)(() => path, [
421
+ Array.isArray(path) ? path.join(".") : path
480
422
  ]);
481
- const { canSave, values, errors, handleSave, ...inputProps } = useForm({
482
- schema,
483
- initialValues,
484
- onValuesChanged,
485
- onValidate,
486
- onValid,
487
- onSave
488
- });
489
- const properties = (0, import_react7.useMemo)(() => {
490
- const props = (0, import_schema2.getSchemaProperties)(schema.ast, values);
491
- const filtered = filter ? filter(props) : props;
492
- const findIndex = (props2, prop) => {
493
- const idx = props2.findIndex((p) => p === prop);
494
- return idx === -1 ? Infinity : idx;
423
+ return (0, import_react3.useMemo)(() => ({
424
+ getStatus: () => getStatus(stablePath),
425
+ getValue: () => getFormValue(stablePath),
426
+ onValueChange: (type, value) => onValueChange(stablePath, type, value),
427
+ onBlur: () => onTouched(stablePath)
428
+ }), [
429
+ getStatus,
430
+ getFormValue,
431
+ onValueChange,
432
+ onTouched,
433
+ stablePath
434
+ ]);
435
+ };
436
+ var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
437
+ const form = useForm(formOptions);
438
+ (0, import_react3.useEffect)(() => {
439
+ if (!formRef?.current) {
440
+ return;
441
+ }
442
+ const handleKeyDown = (event) => {
443
+ const keyIsEnter = event.key === "Enter";
444
+ const modifierUsed = event.ctrlKey || event.altKey || event.metaKey || event.shiftKey;
445
+ const inputIsTextarea = event.target.tagName.toLowerCase() === "textarea";
446
+ const inputOptOut = event.target.hasAttribute("data-no-submit");
447
+ const shouldSubmitRegularInput = !inputIsTextarea && keyIsEnter && !modifierUsed;
448
+ const shouldSubmitTextarea = inputIsTextarea && keyIsEnter && event.metaKey;
449
+ if ((shouldSubmitRegularInput || shouldSubmitTextarea) && !inputOptOut) {
450
+ if (!autoSave && form.canSave) {
451
+ form.handleSave();
452
+ }
453
+ if (autoSave && form.formIsValid) {
454
+ event.target.blur();
455
+ }
456
+ }
495
457
  };
496
- return sort ? filtered.sort(({ name: a }, { name: b }) => findIndex(sort, a) - findIndex(sort, b)) : filtered;
458
+ const formElement = formRef.current;
459
+ formElement.addEventListener("keydown", handleKeyDown);
460
+ return () => formElement.removeEventListener("keydown", handleKeyDown);
497
461
  }, [
498
- schema,
499
- filter,
500
- values
462
+ formRef,
463
+ form.canSave,
464
+ form.formIsValid,
465
+ form.handleSave,
466
+ autoSave
467
+ ]);
468
+ return /* @__PURE__ */ import_react3.default.createElement(FormContext.Provider, {
469
+ value: form
470
+ }, children);
471
+ };
472
+ var InputHeader = ({ children, error }) => {
473
+ return /* @__PURE__ */ import_react6.default.createElement("div", {
474
+ role: "none",
475
+ className: "flex justify-between items-center mb-1"
476
+ }, children, error && /* @__PURE__ */ import_react6.default.createElement(import_react_ui4.Tooltip.Root, null, /* @__PURE__ */ import_react6.default.createElement(import_react_ui4.Tooltip.Trigger, {
477
+ asChild: true
478
+ }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui4.Icon, {
479
+ icon: "ph--warning--regular",
480
+ size: 4,
481
+ classNames: import_react_ui_theme2.errorText
482
+ })), /* @__PURE__ */ import_react6.default.createElement(import_react_ui4.Tooltip.Content, {
483
+ side: "bottom"
484
+ }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui4.Tooltip.Arrow, null), error)));
485
+ };
486
+ var GeoPointInput = ({ type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
487
+ const { t } = (0, import_react_ui3.useTranslation)(translationKey);
488
+ const { status, error } = getStatus();
489
+ const geoPoint = (0, import_react5.useMemo)(() => getValue3() ?? [
490
+ 0,
491
+ 0
492
+ ], [
493
+ getValue3
494
+ ]);
495
+ const geoLocation = (0, import_react5.useMemo)(() => import_echo_schema4.GeoLocation.fromGeoPoint(geoPoint), [
496
+ geoPoint
497
+ ]);
498
+ const [longitudeText, setLongitudeText] = (0, import_react5.useState)(geoLocation.longitude?.toString());
499
+ const [latitudeText, setLatitudeText] = (0, import_react5.useState)(geoLocation.latitude?.toString());
500
+ (0, import_react5.useEffect)(() => {
501
+ const location = import_echo_schema4.GeoLocation.fromGeoPoint(geoPoint);
502
+ setLongitudeText(location.longitude.toString());
503
+ setLatitudeText(location.latitude.toString());
504
+ }, [
505
+ geoPoint
506
+ ]);
507
+ const handleCoordinateChange = (0, import_react5.useCallback)((coordinateType, setText) => (event) => {
508
+ const inputText = event.target.value;
509
+ setText(inputText);
510
+ if (inputText !== "" && inputText !== "-") {
511
+ const coord = (0, import_util.safeParseFloat)(inputText);
512
+ if (coord !== void 0 && !isNaN(coord)) {
513
+ const currentLocation = import_echo_schema4.GeoLocation.fromGeoPoint(getValue3() ?? [
514
+ 0,
515
+ 0
516
+ ]);
517
+ const newLocation = {
518
+ ...currentLocation,
519
+ [coordinateType]: coord
520
+ };
521
+ const newValue = import_echo_schema4.GeoLocation.toGeoPoint(newLocation);
522
+ onValueChange(type, newValue);
523
+ }
524
+ }
525
+ }, [
526
+ getValue3,
527
+ onValueChange,
528
+ type
501
529
  ]);
530
+ return /* @__PURE__ */ import_react5.default.createElement(import_react_ui3.Input.Root, {
531
+ validationValence: status
532
+ }, /* @__PURE__ */ import_react5.default.createElement(InputHeader, {
533
+ error
534
+ }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui3.Input.Label, null, label)), /* @__PURE__ */ import_react5.default.createElement("div", {
535
+ role: "none",
536
+ className: "grid grid-cols-2 gap-2"
537
+ }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui3.Input.TextInput, {
538
+ type: "text",
539
+ pattern: "^-?[0-9]*\\.?[0-9]*$",
540
+ disabled,
541
+ placeholder: t("placeholder latitude"),
542
+ value: latitudeText,
543
+ onChange: handleCoordinateChange("latitude", setLatitudeText),
544
+ onBlur
545
+ }), /* @__PURE__ */ import_react5.default.createElement(import_react_ui3.Input.TextInput, {
546
+ type: "text",
547
+ pattern: "^-?[0-9]*\\.?[0-9]*$",
548
+ disabled,
549
+ placeholder: t("placeholder longitude"),
550
+ value: longitudeText,
551
+ onChange: handleCoordinateChange("longitude", setLongitudeText),
552
+ onBlur
553
+ })));
554
+ };
555
+ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3, onValueChange }) => {
556
+ const [selected, setSelectedId] = (0, import_react7.useState)(null);
557
+ const [isNewOption, setIsNewOption] = (0, import_react7.useState)(false);
558
+ const inputRef = (0, import_react7.useRef)(null);
559
+ const { t } = (0, import_react_ui5.useTranslation)(translationKey);
560
+ const { status, error } = getStatus();
561
+ const options = getValue3();
502
562
  (0, import_react7.useEffect)(() => {
503
- if (errors && Object.keys(errors).length) {
504
- import_log2.log.warn("validation", {
505
- errors
506
- }, {
507
- F: __dxlog_file2,
508
- L: 106,
509
- S: void 0,
510
- C: (f, a) => f(...a)
511
- });
563
+ if (options === void 0) {
564
+ onValueChange(type, []);
512
565
  }
513
566
  }, [
514
- errors
567
+ options,
568
+ onValueChange,
569
+ type
515
570
  ]);
516
- return /* @__PURE__ */ import_react7.default.createElement("div", {
517
- role: "form",
518
- className: (0, import_react_ui_theme3.mx)("flex flex-col w-full gap-2 py-2", classNames),
519
- "data-testid": testId
520
- }, properties.map((property) => {
521
- const { ast, name, type, format, title, description, examples, options, array } = property;
522
- const key = [
523
- ...path,
524
- name
571
+ const randomHue = () => {
572
+ const usedHues = new Set(options?.map((option) => option.color) ?? []);
573
+ const unusedHues = import_react_ui_theme3.hues.filter((hue) => !usedHues.has(hue));
574
+ if (unusedHues.length > 0) {
575
+ return unusedHues[Math.floor(Math.random() * unusedHues.length)];
576
+ }
577
+ const lastThree = new Set(options?.slice(-3).map((option) => option.color) ?? []);
578
+ const availableHues = import_react_ui_theme3.hues.filter((hue) => !lastThree.has(hue));
579
+ return availableHues[Math.floor(Math.random() * availableHues.length)] ?? import_react_ui_theme3.hues[Math.floor(Math.random() * import_react_ui_theme3.hues.length)];
580
+ };
581
+ const handleAdd = (0, import_react7.useCallback)(() => {
582
+ const newId = import_keys.PublicKey.random().truncate();
583
+ const newOption = {
584
+ id: newId,
585
+ title: "",
586
+ color: randomHue()
587
+ };
588
+ onValueChange(type, [
589
+ ...options ?? [],
590
+ newOption
591
+ ]);
592
+ setSelectedId(newId);
593
+ setIsNewOption(true);
594
+ }, [
595
+ options,
596
+ type,
597
+ onValueChange
598
+ ]);
599
+ const handleDelete = (0, import_react7.useCallback)((id) => {
600
+ const newOptions = options?.filter((option) => option.id !== id) ?? [];
601
+ onValueChange(type, newOptions);
602
+ setSelectedId(null);
603
+ }, [
604
+ options,
605
+ type,
606
+ onValueChange
607
+ ]);
608
+ const handleMove = (0, import_react7.useCallback)((from, to) => {
609
+ if (!options) {
610
+ return;
611
+ }
612
+ const newOptions = [
613
+ ...options
525
614
  ];
526
- const label = title ?? (0, import_effect.pipe)(name, import_String.capitalize);
527
- const placeholder = examples?.length ? `Example: "${examples[0]}"` : description;
528
- const FoundComponent = lookupComponent?.({
529
- prop: name,
530
- schema: import_echo_schema2.S.make(ast),
531
- inputProps: {
532
- property: name,
533
- type,
534
- format,
535
- label,
536
- disabled: readonly,
537
- placeholder,
538
- ...inputProps
539
- }
540
- });
541
- if (FoundComponent) {
542
- return /* @__PURE__ */ import_react7.default.createElement("div", {
543
- key: name,
544
- role: "none",
545
- className: padding
546
- }, FoundComponent);
615
+ const [removed] = newOptions.splice(from, 1);
616
+ newOptions.splice(to, 0, removed);
617
+ onValueChange(type, newOptions);
618
+ }, [
619
+ options,
620
+ type,
621
+ onValueChange
622
+ ]);
623
+ const handleClick = (0, import_react7.useCallback)((id) => {
624
+ setSelectedId((current) => current === id ? null : id);
625
+ }, []);
626
+ const handleTitleChange = (0, import_react7.useCallback)((id) => (e) => {
627
+ const newOptions = options?.map((o) => o.id === id ? {
628
+ ...o,
629
+ title: e.target.value
630
+ } : o);
631
+ onValueChange(type, newOptions ?? []);
632
+ }, [
633
+ options,
634
+ type,
635
+ onValueChange
636
+ ]);
637
+ const handleKeyDown = (0, import_react7.useCallback)((e) => {
638
+ if (e.key === "Enter") {
639
+ setSelectedId(null);
547
640
  }
548
- let InputComponent = Custom?.[key.join(".")];
549
- if (!InputComponent) {
550
- if (options) {
551
- return /* @__PURE__ */ import_react7.default.createElement("div", {
552
- key: name,
553
- role: "none",
554
- className: padding
555
- }, /* @__PURE__ */ import_react7.default.createElement(SelectInput, {
556
- type,
557
- format,
558
- property: name,
559
- disabled: readonly,
560
- label,
561
- options: options.map((option) => ({
562
- value: option,
563
- label: String(option)
564
- })),
565
- placeholder,
566
- ...inputProps
567
- }));
568
- }
569
- InputComponent = getInputComponent(type, format);
570
- if (array) {
571
- return /* @__PURE__ */ import_react7.default.createElement(ArrayField, {
572
- key: name,
573
- name,
574
- type,
575
- array: true,
576
- label,
577
- ast,
578
- values,
579
- format,
580
- readonly,
581
- placeholder,
582
- inputProps,
583
- Custom
584
- });
585
- }
641
+ }, []);
642
+ const handleColorChange = (0, import_react7.useCallback)((id) => (hue) => {
643
+ const newOptions = options?.map((o) => o.id === id ? {
644
+ ...o,
645
+ color: hue
646
+ } : o);
647
+ onValueChange(type, newOptions ?? []);
648
+ }, [
649
+ options,
650
+ type,
651
+ onValueChange
652
+ ]);
653
+ (0, import_react7.useEffect)(() => {
654
+ if (selected && isNewOption && inputRef.current) {
655
+ inputRef.current.focus();
656
+ setIsNewOption(false);
586
657
  }
587
- if (!InputComponent) {
588
- if (type === "object") {
589
- const baseNode = (0, import_effect2.findNode)(ast, import_effect2.isDiscriminatedUnion);
590
- const typeLiteral = baseNode ? (0, import_effect2.getDiscriminatedType)(baseNode, values[name]) : (0, import_effect2.findNode)(ast, import_echo_schema2.AST.isTypeLiteral);
591
- if (typeLiteral) {
592
- const schema2 = import_echo_schema2.S.make(typeLiteral);
593
- return /* @__PURE__ */ import_react7.default.createElement("div", {
594
- key: name,
595
- role: "none"
596
- }, /* @__PURE__ */ import_react7.default.createElement("div", {
597
- className: padding
598
- }, label), /* @__PURE__ */ import_react7.default.createElement(Form, {
599
- schema: schema2,
600
- path: key,
601
- values: values[name] ?? {},
602
- onValuesChanged: (childValues) => {
603
- inputProps.onValueChange(name, "object", childValues);
604
- },
605
- Custom
606
- }));
607
- }
608
- }
609
- (0, import_log2.log)("no renderer for property", {
610
- name,
611
- type
612
- }, {
613
- F: __dxlog_file2,
614
- L: 213,
615
- S: void 0,
616
- C: (f, a) => f(...a)
617
- });
618
- return null;
658
+ }, [
659
+ selected,
660
+ isNewOption
661
+ ]);
662
+ return /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Input.Root, {
663
+ validationValence: status
664
+ }, /* @__PURE__ */ import_react7.default.createElement(InputHeader, {
665
+ error
666
+ }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Input.Label, null, label)), /* @__PURE__ */ import_react7.default.createElement("div", {
667
+ role: "none"
668
+ }, options && /* @__PURE__ */ import_react7.default.createElement(import_react_ui_list.List.Root, {
669
+ items: options,
670
+ isItem: (item) => true,
671
+ onMove: handleMove
672
+ }, ({ items }) => /* @__PURE__ */ import_react7.default.createElement("div", {
673
+ role: "list",
674
+ className: "w-full overflow-auto"
675
+ }, items?.map((item) => /* @__PURE__ */ import_react7.default.createElement("div", {
676
+ key: item.id
677
+ }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui_list.List.Item, {
678
+ role: "button",
679
+ item,
680
+ classNames: (0, import_react_ui_theme3.mx)("p-1 plb-2", "flex flex-col", "cursor-pointer", "hover:bg-hoverOverlay"),
681
+ "aria-expanded": selected === item.id
682
+ }, /* @__PURE__ */ import_react7.default.createElement("div", {
683
+ className: "flex items-center"
684
+ }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui_list.List.ItemDragHandle, null), /* @__PURE__ */ import_react7.default.createElement(import_react_ui_list.List.ItemTitle, {
685
+ onClick: () => handleClick(item.id),
686
+ classNames: "flex-1"
687
+ }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Tag, {
688
+ palette: item.color
689
+ }, item.title || "\u200B")), /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Icon, {
690
+ icon: selected === item.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
691
+ onClick: () => handleClick(item.id)
692
+ })), selected === item.id && /* @__PURE__ */ import_react7.default.createElement("div", {
693
+ className: "mis-4 mbs-2 flex flex-col gap-1"
694
+ }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Input.Label, {
695
+ classNames: "text-xs"
696
+ }, t("select option label")), /* @__PURE__ */ import_react7.default.createElement("div", {
697
+ className: "flex flex-row items-center gap-1"
698
+ }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Input.TextInput, {
699
+ placeholder: t("select option label placeholder"),
700
+ ref: selected === item.id ? inputRef : void 0,
701
+ value: item.title,
702
+ onChange: handleTitleChange(item.id),
703
+ onKeyDown: handleKeyDown,
704
+ classNames: "flex-1",
705
+ "data-no-submit": true
706
+ }), /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Toolbar.Root, {
707
+ classNames: "p-0 m-0 !is-auto"
708
+ }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui_pickers.HuePicker, {
709
+ value: item.color,
710
+ onChange: handleColorChange(item.id)
711
+ })), /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.IconButton, {
712
+ icon: "ph--trash--fill",
713
+ iconOnly: true,
714
+ label: t("select option delete"),
715
+ onClick: () => handleDelete(item.id)
716
+ })))))), /* @__PURE__ */ import_react7.default.createElement("div", {
717
+ role: "listitem"
718
+ }, /* @__PURE__ */ import_react7.default.createElement("div", {
719
+ role: "button",
720
+ className: (0, import_react_ui_theme3.mx)("p-1 plb-2", "flex flex-col", "cursor-pointer", "hover:bg-hoverOverlay"),
721
+ onClick: handleAdd
722
+ }, /* @__PURE__ */ import_react7.default.createElement("div", {
723
+ className: "flex items-center gap-1"
724
+ }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Icon, {
725
+ icon: "ph--plus--regular"
726
+ }), /* @__PURE__ */ import_react7.default.createElement("span", {
727
+ className: "text-sm"
728
+ }, t("select option add")))))))));
729
+ };
730
+ var gridCols = [
731
+ "grid-cols-1",
732
+ "grid-cols-2",
733
+ "grid-cols-3",
734
+ "grid-cols-4"
735
+ ];
736
+ var TupleInput = ({ binding, type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
737
+ const { status, error } = getStatus();
738
+ const values = getValue3() ?? {};
739
+ return /* @__PURE__ */ import_react8.default.createElement(import_react_ui6.Input.Root, {
740
+ validationValence: status
741
+ }, /* @__PURE__ */ import_react8.default.createElement(InputHeader, {
742
+ error
743
+ }, /* @__PURE__ */ import_react8.default.createElement(import_react_ui6.Input.Label, null, label)), /* @__PURE__ */ import_react8.default.createElement("div", {
744
+ className: (0, import_react_ui_theme4.mx)("grid gap-2", gridCols[binding.length - 1])
745
+ }, binding.map((prop) => /* @__PURE__ */ import_react8.default.createElement(import_react_ui6.Input.TextInput, {
746
+ key: prop,
747
+ type: "number",
748
+ disabled,
749
+ value: values[prop],
750
+ onChange: (event) => onValueChange(type, {
751
+ ...values,
752
+ [prop]: (0, import_util2.safeParseFloat)(event.target.value, 0)
753
+ }),
754
+ onBlur
755
+ }))));
756
+ };
757
+ var TextInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
758
+ const { status, error } = getStatus();
759
+ return /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Root, {
760
+ validationValence: status
761
+ }, !inputOnly && /* @__PURE__ */ import_react9.default.createElement(InputHeader, {
762
+ error
763
+ }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Label, null, label)), /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.TextInput, {
764
+ disabled,
765
+ placeholder,
766
+ value: getValue3() ?? "",
767
+ onChange: (event) => onValueChange(type, event.target.value),
768
+ onBlur
769
+ }), inputOnly && /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Validation, null, error));
770
+ };
771
+ var NumberInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
772
+ const { status, error } = getStatus();
773
+ return /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Root, {
774
+ validationValence: status
775
+ }, !inputOnly && /* @__PURE__ */ import_react9.default.createElement(InputHeader, {
776
+ error
777
+ }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Label, null, label)), /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.TextInput, {
778
+ type: "number",
779
+ disabled,
780
+ placeholder,
781
+ value: getValue3() ?? 0,
782
+ onChange: (event) => onValueChange(type, event.target.value),
783
+ onBlur
784
+ }), inputOnly && /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.DescriptionAndValidation, null, error));
785
+ };
786
+ var BooleanInput = ({ type, label, inputOnly, getStatus, getValue: getValue3, onValueChange }) => {
787
+ const { status, error } = getStatus();
788
+ const checked = Boolean(getValue3());
789
+ return /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Root, {
790
+ validationValence: status
791
+ }, !inputOnly && /* @__PURE__ */ import_react9.default.createElement(InputHeader, {
792
+ error
793
+ }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Label, null, label)), /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Switch, {
794
+ checked,
795
+ onCheckedChange: (value) => onValueChange(type, value)
796
+ }), inputOnly && /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.DescriptionAndValidation, null, error));
797
+ };
798
+ var SelectInput = ({ type, label, inputOnly, disabled, placeholder, options, getStatus, getValue: getValue3, onValueChange }) => {
799
+ const { status, error } = getStatus();
800
+ return /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Root, {
801
+ validationValence: status
802
+ }, !inputOnly && /* @__PURE__ */ import_react9.default.createElement(InputHeader, {
803
+ error
804
+ }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Label, null, label)), /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Select.Root, {
805
+ value: getValue3(),
806
+ onValueChange: (value) => onValueChange(type, value)
807
+ }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Select.TriggerButton, {
808
+ classNames: "is-full",
809
+ disabled,
810
+ placeholder
811
+ }), /* @__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 }) => (
812
+ // NOTE: Numeric values are converted to and from strings.
813
+ /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Select.Option, {
814
+ key: String(value),
815
+ value: String(value)
816
+ }, label2 ?? String(value))
817
+ )))))), inputOnly && /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.DescriptionAndValidation, null, error));
818
+ };
819
+ var MarkdownInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
820
+ const { status, error } = getStatus();
821
+ const textareaRef = (0, import_react9.useRef)(null);
822
+ const adjustHeight = (0, import_react9.useCallback)(() => {
823
+ const textarea = textareaRef.current;
824
+ if (textarea) {
825
+ textarea.style.blockSize = "auto";
826
+ textarea.style.blockSize = `${textarea.scrollHeight + 2}px`;
619
827
  }
620
- return /* @__PURE__ */ import_react7.default.createElement("div", {
621
- key: name,
622
- role: "none",
623
- className: padding
624
- }, /* @__PURE__ */ import_react7.default.createElement(InputComponent, {
625
- type,
626
- format,
627
- property: name,
628
- disabled: readonly,
629
- label,
630
- placeholder,
631
- ...inputProps
632
- }));
633
- }).filter(import_util3.isNotFalsy), (onCancel || onSave) && !autoSave && /* @__PURE__ */ import_react7.default.createElement(FormActions, {
634
- onCancel,
635
- onSubmit: handleSave,
636
- canSubmit: canSave,
637
- readonly
638
- }));
828
+ }, []);
829
+ (0, import_react9.useEffect)(() => {
830
+ adjustHeight();
831
+ }, [
832
+ adjustHeight
833
+ ]);
834
+ (0, import_react9.useEffect)(() => {
835
+ adjustHeight();
836
+ }, [
837
+ getValue3(),
838
+ adjustHeight
839
+ ]);
840
+ return /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Root, {
841
+ validationValence: status
842
+ }, !inputOnly && /* @__PURE__ */ import_react9.default.createElement(InputHeader, {
843
+ error
844
+ }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Label, null, label)), /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.TextArea, {
845
+ ref: textareaRef,
846
+ disabled,
847
+ placeholder,
848
+ value: getValue3() ?? "",
849
+ classNames: "min-bs-auto max-h-40 overflow-auto",
850
+ onChange: (event) => onValueChange(type, event.target.value),
851
+ onBlur,
852
+ style: {
853
+ resize: "none"
854
+ },
855
+ spellCheck: false
856
+ }), inputOnly && /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Validation, null, error));
639
857
  };
640
- var ArrayField = ({ name, type, label, ast, values, format, readonly, placeholder, inputProps, Custom }) => {
641
- const { t } = (0, import_react_ui7.useTranslation)(translationKey);
642
- const arrayValues = values[name] ?? [];
643
- const key = [
644
- name
645
- ];
646
- const tupleType = (0, import_effect2.findNode)(ast, import_echo_schema2.AST.isTupleType);
858
+ var FormActions = ({ onCancel, readonly }) => {
859
+ const { t } = (0, import_react_ui8.useTranslation)(translationKey);
860
+ const { canSave, handleSave } = useFormContext();
861
+ return /* @__PURE__ */ import_react11.default.createElement("div", {
862
+ role: "none",
863
+ className: "mt-2 flex justify-center"
864
+ }, /* @__PURE__ */ import_react11.default.createElement("div", {
865
+ role: "none",
866
+ className: (0, import_react_ui_theme6.mx)(onCancel && !readonly && "grid grid-cols-2 gap-2")
867
+ }, onCancel && !readonly && /* @__PURE__ */ import_react11.default.createElement(import_react_ui8.IconButton, {
868
+ "data-testid": "cancel-button",
869
+ icon: "ph--x--regular",
870
+ label: t("button cancel"),
871
+ onClick: onCancel
872
+ }), handleSave && /* @__PURE__ */ import_react11.default.createElement(import_react_ui8.IconButton, {
873
+ type: "submit",
874
+ "data-testid": "save-button",
875
+ disabled: !canSave,
876
+ icon: "ph--check--regular",
877
+ label: t("button save"),
878
+ onClick: handleSave
879
+ })));
880
+ };
881
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/Form/ArrayField.tsx";
882
+ var padding = "px-2";
883
+ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponent }) => {
884
+ const { t } = (0, import_react_ui9.useTranslation)(translationKey);
885
+ const { ast, name, type, title } = property;
886
+ const values = useFormValues(path ?? []);
887
+ (0, import_invariant2.invariant)(Array.isArray(values), `Values at path ${path?.join(".")} must be an array.`, {
888
+ F: __dxlog_file2,
889
+ L: 37,
890
+ S: void 0,
891
+ A: [
892
+ "Array.isArray(values)",
893
+ "`Values at path ${path?.join('.')} must be an array.`"
894
+ ]
895
+ });
896
+ const label = title ?? (0, import_effect5.pipe)(name, import_String2.capitalize);
897
+ const tupleType = (0, import_effect6.findNode)(ast, import_echo_schema6.AST.isTupleType);
647
898
  const elementType = tupleType?.rest[0]?.type;
648
- if (type === "object" && elementType) {
649
- const baseNode = (0, import_effect2.findNode)(elementType, import_effect2.isDiscriminatedUnion);
650
- const typeLiteral = baseNode ? (0, import_effect2.getDiscriminatedType)(baseNode, values[name]) : (0, import_effect2.findNode)(elementType, import_echo_schema2.AST.isTypeLiteral);
651
- if (typeLiteral) {
652
- const schema = import_echo_schema2.S.make(typeLiteral);
653
- return /* @__PURE__ */ import_react7.default.createElement("div", {
654
- key: name,
655
- role: "none",
656
- className: (0, import_react_ui_theme3.mx)(padding)
657
- }, /* @__PURE__ */ import_react7.default.createElement(InputHeader, null, label), /* @__PURE__ */ import_react7.default.createElement("div", {
658
- role: "none",
659
- className: "flex flex-col gap-1"
660
- }, arrayValues.map((value, index) => {
661
- return /* @__PURE__ */ import_react7.default.createElement("div", {
662
- key: index,
663
- role: "none",
664
- className: "flex items-center gap-1"
665
- }, /* @__PURE__ */ import_react7.default.createElement("div", {
666
- role: "none",
667
- className: "flex-1"
668
- }, /* @__PURE__ */ import_react7.default.createElement(Form, {
669
- schema,
670
- path: [
671
- ...key,
672
- `[${index}]`
673
- ],
674
- values: value,
675
- onValuesChanged: (childValues) => {
676
- const newValues = [
677
- ...arrayValues
678
- ];
679
- newValues[index] = childValues;
680
- inputProps.onValueChange(name, "object", newValues);
681
- },
682
- Custom
683
- })), /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.IconButton, {
684
- icon: "ph--trash--regular",
685
- iconOnly: true,
686
- label: t("button remove"),
687
- onClick: () => {
688
- const newValues = arrayValues.filter((_, i) => i !== index);
689
- inputProps.onValueChange(name, type, newValues);
690
- }
691
- }));
692
- })), /* @__PURE__ */ import_react7.default.createElement("div", {
693
- role: "none",
694
- className: "flex justify-between items-center plb-1"
695
- }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.IconButton, {
696
- icon: "ph--plus--regular",
697
- iconOnly: true,
698
- label: t("button add"),
699
- onClick: () => {
700
- const newValues = [
701
- ...arrayValues,
702
- {}
703
- ];
704
- inputProps.onValueChange(name, type, newValues);
705
- }
706
- })));
899
+ const getDefaultObjectValue = (typeNode) => {
900
+ const baseNode = (0, import_effect6.findNode)(typeNode, import_effect6.isDiscriminatedUnion);
901
+ const typeLiteral = baseNode ? (0, import_effect6.getDiscriminatedType)(baseNode, {}) : (0, import_effect6.findNode)(typeNode, import_echo_schema6.AST.isTypeLiteral);
902
+ if (!typeLiteral) {
903
+ return {};
707
904
  }
708
- return /* @__PURE__ */ import_react7.default.createElement("div", {
709
- key: name,
710
- role: "none"
711
- }, "Nested form not supported in arrays, yet.");
712
- }
713
- const InputComponent = getInputComponent(type, format);
714
- if (!InputComponent) {
905
+ return Object.fromEntries((0, import_schema4.getSchemaProperties)(typeLiteral, {}).map((prop) => [
906
+ prop.name,
907
+ prop.defaultValue
908
+ ]));
909
+ };
910
+ const newValue = (0, import_react13.useMemo)(() => {
911
+ if (type === "object" && elementType) {
912
+ return getDefaultObjectValue(elementType);
913
+ } else {
914
+ return import_effect6.SimpleType.getDefaultValue(type);
915
+ }
916
+ }, [
917
+ type,
918
+ elementType
919
+ ]);
920
+ const handleAdd = (0, import_react13.useCallback)(() => {
921
+ inputProps.onValueChange(type, [
922
+ ...values,
923
+ newValue
924
+ ]);
925
+ }, [
926
+ type,
927
+ elementType,
928
+ inputProps,
929
+ newValue,
930
+ values
931
+ ]);
932
+ const handleRemove = (0, import_react13.useCallback)((index) => {
933
+ const newValues = values.filter((_, i) => i !== index);
934
+ inputProps.onValueChange(type, newValues);
935
+ }, [
936
+ type,
937
+ inputProps,
938
+ values
939
+ ]);
940
+ if (!elementType) {
715
941
  return null;
716
942
  }
717
- return /* @__PURE__ */ import_react7.default.createElement("div", {
943
+ return /* @__PURE__ */ import_react13.default.createElement("div", {
718
944
  role: "none",
719
- key: "meta-input",
720
- className: (0, import_react_ui_theme3.mx)(padding)
721
- }, /* @__PURE__ */ import_react7.default.createElement(InputHeader, null, label), /* @__PURE__ */ import_react7.default.createElement("div", {
945
+ className: (0, import_react_ui_theme8.mx)(padding)
946
+ }, /* @__PURE__ */ import_react13.default.createElement(InputHeader, null, label), /* @__PURE__ */ import_react13.default.createElement("div", {
722
947
  role: "none",
723
948
  className: "flex flex-col gap-1"
724
- }, arrayValues.map((_, index) => /* @__PURE__ */ import_react7.default.createElement("div", {
949
+ }, values.map((_value, index) => /* @__PURE__ */ import_react13.default.createElement("div", {
725
950
  key: index,
726
951
  role: "none",
727
- className: "flex items-start gap-1"
728
- }, /* @__PURE__ */ import_react7.default.createElement("div", {
952
+ className: "flex items-center gap-1"
953
+ }, /* @__PURE__ */ import_react13.default.createElement("div", {
729
954
  role: "none",
730
955
  className: "flex-1"
731
- }, /* @__PURE__ */ import_react7.default.createElement(InputComponent, {
732
- type,
733
- format,
734
- label,
735
- inputOnly: true,
736
- property: `${name}[${index}]`,
737
- disabled: readonly,
738
- placeholder,
739
- ...inputProps
740
- })), /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.IconButton, {
956
+ }, /* @__PURE__ */ import_react13.default.createElement(FormField, {
957
+ property: {
958
+ ...property,
959
+ array: false,
960
+ ast: elementType
961
+ },
962
+ path: [
963
+ ...path ?? [],
964
+ index
965
+ ],
966
+ readonly,
967
+ inline: true,
968
+ Custom,
969
+ lookupComponent
970
+ })), /* @__PURE__ */ import_react13.default.createElement(import_react_ui9.IconButton, {
741
971
  icon: "ph--trash--regular",
742
972
  iconOnly: true,
743
973
  label: t("button remove"),
744
- onClick: () => {
745
- const newValues = arrayValues.filter((_2, i) => i !== index);
746
- inputProps.onValueChange(name, type, newValues);
747
- }
748
- })))), /* @__PURE__ */ import_react7.default.createElement("div", {
974
+ onClick: () => handleRemove(index)
975
+ })))), /* @__PURE__ */ import_react13.default.createElement("div", {
749
976
  role: "none",
750
977
  className: "flex justify-between items-center plb-1"
751
- }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.IconButton, {
978
+ }, /* @__PURE__ */ import_react13.default.createElement(import_react_ui9.IconButton, {
752
979
  icon: "ph--plus--regular",
753
980
  iconOnly: true,
754
981
  label: t("button add"),
755
- onClick: () => {
756
- const newValues = [
757
- ...arrayValues,
758
- import_effect2.SimpleType.getDefaultValue(type)
759
- ];
760
- inputProps.onValueChange(name, type, newValues);
761
- }
982
+ onClick: handleAdd
762
983
  })));
763
984
  };
764
- var FormActions = ({ onCancel, onSubmit, canSubmit, readonly }) => {
765
- const { t } = (0, import_react_ui7.useTranslation)(translationKey);
766
- return /* @__PURE__ */ import_react7.default.createElement("div", {
767
- role: "none",
768
- className: "flex justify-center"
769
- }, /* @__PURE__ */ import_react7.default.createElement("div", {
985
+ var getInputComponent = (type, format) => {
986
+ switch (format) {
987
+ case import_echo_schema7.FormatEnum.GeoPoint:
988
+ return GeoPointInput;
989
+ case import_echo_schema7.FormatEnum.Markdown:
990
+ return MarkdownInput;
991
+ }
992
+ switch (type) {
993
+ case "string":
994
+ return TextInput;
995
+ case "number":
996
+ return NumberInput;
997
+ case "boolean":
998
+ return BooleanInput;
999
+ }
1000
+ };
1001
+ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom }) => {
1002
+ const inputProps = useInputProps(path);
1003
+ const { ast, name, type, format, title, description, options, examples, array } = property;
1004
+ const label = (0, import_react12.useMemo)(() => title ?? (0, import_effect3.pipe)(name, import_String.capitalize), [
1005
+ title,
1006
+ name
1007
+ ]);
1008
+ const placeholder = (0, import_react12.useMemo)(() => examples?.length ? `Example: "${examples[0]}"` : description, [
1009
+ examples,
1010
+ description
1011
+ ]);
1012
+ const FoundComponent = lookupComponent?.({
1013
+ prop: name,
1014
+ schema: import_echo_schema5.S.make(ast),
1015
+ inputProps: {
1016
+ type,
1017
+ format,
1018
+ label,
1019
+ disabled: readonly,
1020
+ placeholder,
1021
+ ...inputProps
1022
+ }
1023
+ });
1024
+ if (FoundComponent) {
1025
+ return /* @__PURE__ */ import_react12.default.createElement("div", {
1026
+ role: "none"
1027
+ }, FoundComponent);
1028
+ }
1029
+ const jsonPath = (0, import_effect4.createJsonPath)(path ?? []);
1030
+ const CustomComponent = Custom?.[jsonPath];
1031
+ if (CustomComponent) {
1032
+ return /* @__PURE__ */ import_react12.default.createElement(CustomComponent, {
1033
+ type,
1034
+ format,
1035
+ label,
1036
+ inputOnly: inline,
1037
+ placeholder,
1038
+ disabled: readonly,
1039
+ ...inputProps
1040
+ });
1041
+ }
1042
+ if (array) {
1043
+ return /* @__PURE__ */ import_react12.default.createElement(ArrayField, {
1044
+ property,
1045
+ path,
1046
+ inputProps,
1047
+ readonly,
1048
+ Custom
1049
+ });
1050
+ }
1051
+ const InputComponent = getInputComponent(type, format);
1052
+ if (InputComponent) {
1053
+ return /* @__PURE__ */ import_react12.default.createElement("div", {
1054
+ role: "none"
1055
+ }, /* @__PURE__ */ import_react12.default.createElement(InputComponent, {
1056
+ type,
1057
+ format,
1058
+ label,
1059
+ inputOnly: inline,
1060
+ placeholder,
1061
+ disabled: readonly,
1062
+ ...inputProps
1063
+ }));
1064
+ }
1065
+ if (options) {
1066
+ return /* @__PURE__ */ import_react12.default.createElement("div", {
1067
+ role: "none"
1068
+ }, /* @__PURE__ */ import_react12.default.createElement(SelectInput, {
1069
+ type,
1070
+ format,
1071
+ disabled: readonly,
1072
+ inputOnly: inline,
1073
+ label,
1074
+ options: options.map((option) => ({
1075
+ value: option,
1076
+ label: String(option)
1077
+ })),
1078
+ placeholder,
1079
+ ...inputProps
1080
+ }));
1081
+ }
1082
+ if (type === "object") {
1083
+ const baseNode = (0, import_effect4.findNode)(ast, import_effect4.isDiscriminatedUnion);
1084
+ const typeLiteral = baseNode ? (0, import_effect4.getDiscriminatedType)(baseNode, inputProps.getValue()) : (0, import_effect4.findNode)(ast, import_echo_schema5.AST.isTypeLiteral);
1085
+ if (typeLiteral) {
1086
+ return /* @__PURE__ */ import_react12.default.createElement("div", {
1087
+ role: "none"
1088
+ }, !inline && /* @__PURE__ */ import_react12.default.createElement("div", null, label), /* @__PURE__ */ import_react12.default.createElement(FormFields, {
1089
+ schema: import_echo_schema5.S.make(typeLiteral),
1090
+ path,
1091
+ readonly,
1092
+ Custom
1093
+ }));
1094
+ }
1095
+ }
1096
+ return null;
1097
+ };
1098
+ var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custom }) => {
1099
+ const values = useFormValues(path);
1100
+ const properties = (0, import_react12.useMemo)(() => {
1101
+ const props = (0, import_schema3.getSchemaProperties)(schema.ast, values);
1102
+ const filtered = filter ? filter(props) : props;
1103
+ return sort ? filtered.sort((a, b) => sort.indexOf(a.name) - sort.indexOf(b.name)) : filtered;
1104
+ }, [
1105
+ schema,
1106
+ values,
1107
+ filter,
1108
+ sort
1109
+ ]);
1110
+ return /* @__PURE__ */ import_react12.default.createElement("div", {
1111
+ role: "form",
1112
+ className: (0, import_react_ui_theme7.mx)("flex flex-col w-full gap-2")
1113
+ }, properties.map((property) => {
1114
+ return /* @__PURE__ */ import_react12.default.createElement(FormField, {
1115
+ key: property.name,
1116
+ property,
1117
+ path: [
1118
+ ...path ?? [],
1119
+ property.name
1120
+ ],
1121
+ readonly,
1122
+ lookupComponent,
1123
+ Custom
1124
+ });
1125
+ }).filter(import_util3.isNotFalsy));
1126
+ };
1127
+ var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, lookupComponent, Custom }) => {
1128
+ const formRef = (0, import_react10.useRef)(null);
1129
+ const onValid = (0, import_react10.useMemo)(() => autoSave ? onSave : void 0, [
1130
+ autoSave,
1131
+ onSave
1132
+ ]);
1133
+ (0, import_react10.useEffect)(() => {
1134
+ if (autoFocus && formRef.current) {
1135
+ const input = formRef.current.querySelector("input");
1136
+ if (input) {
1137
+ input.focus();
1138
+ }
1139
+ }
1140
+ }, [
1141
+ autoFocus
1142
+ ]);
1143
+ return /* @__PURE__ */ import_react10.default.createElement(FormProvider, {
1144
+ formRef,
1145
+ schema,
1146
+ autoSave,
1147
+ initialValues,
1148
+ onValuesChanged,
1149
+ onValidate,
1150
+ onValid,
1151
+ onSave
1152
+ }, /* @__PURE__ */ import_react10.default.createElement("div", {
1153
+ ref: formRef,
770
1154
  role: "none",
771
- className: (0, import_react_ui_theme3.mx)(onCancel && !readonly && "grid grid-cols-2 gap-2")
772
- }, onCancel && !readonly && /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.IconButton, {
773
- "data-testid": "cancel-button",
774
- icon: "ph--x--regular",
775
- label: t("button cancel"),
776
- onClick: onCancel
777
- }), onSubmit && /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.IconButton, {
778
- type: "submit",
779
- "data-testid": "save-button",
780
- disabled: !canSubmit,
781
- icon: "ph--check--regular",
782
- label: t("button save"),
783
- onClick: onSubmit
1155
+ className: (0, import_react_ui_theme5.mx)("p-2", classNames),
1156
+ "data-testid": testId
1157
+ }, /* @__PURE__ */ import_react10.default.createElement(FormFields, {
1158
+ schema,
1159
+ path,
1160
+ readonly,
1161
+ filter,
1162
+ sort,
1163
+ lookupComponent,
1164
+ Custom
1165
+ }), (onCancel || onSave) && !autoSave && /* @__PURE__ */ import_react10.default.createElement(FormActions, {
1166
+ onCancel,
1167
+ readonly
784
1168
  })));
785
1169
  };
786
1170
  var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
@@ -848,7 +1232,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
848
1232
  type
849
1233
  };
850
1234
  }
851
- return props2;
1235
+ return _props;
852
1236
  });
853
1237
  }, [
854
1238
  schemas,
@@ -904,7 +1288,8 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
904
1288
  options: referenceSchema ? (0, import_schema.getSchemaProperties)(referenceSchema.ast).sort(import_schema.sortProperties).map((p) => ({
905
1289
  value: p.name
906
1290
  })) : []
907
- })
1291
+ }),
1292
+ ["options"]: (props2) => /* @__PURE__ */ import_react2.default.createElement(SelectOptionInput, props2)
908
1293
  }), [
909
1294
  t,
910
1295
  schemas,
@@ -916,7 +1301,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
916
1301
  props
917
1302
  }, {
918
1303
  F: __dxlog_file3,
919
- L: 173,
1304
+ L: 174,
920
1305
  S: void 0,
921
1306
  C: (f, a) => f(...a)
922
1307
  });
@@ -940,22 +1325,22 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
940
1325
  });
941
1326
  };
942
1327
  var grid = "grid grid-cols-[32px_1fr_32px] min-bs-[2.5rem]";
943
- var ViewMetaSchema = import_echo_schema5.S.Struct({
944
- name: import_echo_schema5.S.String.annotations({
945
- [import_echo_schema5.AST.TitleAnnotationId]: "View"
1328
+ var ViewMetaSchema = import_echo_schema8.S.Struct({
1329
+ name: import_echo_schema8.S.String.annotations({
1330
+ [import_echo_schema8.AST.TitleAnnotationId]: "View"
946
1331
  }),
947
- typename: import_echo_schema5.Format.DXN.annotations({
948
- [import_echo_schema5.AST.TitleAnnotationId]: "Typename"
1332
+ typename: import_echo_schema8.Format.URL.annotations({
1333
+ [import_echo_schema8.AST.TitleAnnotationId]: "Typename"
949
1334
  })
950
- }).pipe(import_echo_schema5.S.mutable);
1335
+ }).pipe(import_echo_schema8.S.mutable);
951
1336
  var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading = false, onTypenameChanged, onDelete }) => {
952
- const { t } = (0, import_react_ui8.useTranslation)(translationKey);
953
- const projection = (0, import_react9.useMemo)(() => new import_schema4.ViewProjection(schema, view), [
1337
+ const { t } = (0, import_react_ui10.useTranslation)(translationKey);
1338
+ const projection = (0, import_react14.useMemo)(() => new import_schema5.ViewProjection(schema, view), [
954
1339
  schema,
955
1340
  view
956
1341
  ]);
957
- const [field, setField] = (0, import_react9.useState)();
958
- const viewValues = (0, import_react9.useMemo)(() => {
1342
+ const [field, setField] = (0, import_react14.useState)();
1343
+ const viewValues = (0, import_react14.useMemo)(() => {
959
1344
  return {
960
1345
  name: view.name,
961
1346
  // TODO(burdon): Need to warn user of possible consequences of editing.
@@ -965,7 +1350,7 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
965
1350
  }, [
966
1351
  view
967
1352
  ]);
968
- const handleViewUpdate = (0, import_react9.useCallback)(({ name, typename }) => {
1353
+ const handleViewUpdate = (0, import_react14.useCallback)(({ name, typename }) => {
969
1354
  requestAnimationFrame(() => {
970
1355
  if (view.name !== name) {
971
1356
  view.name = name;
@@ -979,72 +1364,76 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
979
1364
  schema,
980
1365
  onTypenameChanged
981
1366
  ]);
982
- const handleSelect = (0, import_react9.useCallback)((field2) => {
1367
+ const handleSelect = (0, import_react14.useCallback)((field2) => {
983
1368
  setField((f) => f === field2 ? void 0 : field2);
984
1369
  }, []);
985
- const handleAdd = (0, import_react9.useCallback)(() => {
1370
+ const handleAdd = (0, import_react14.useCallback)(() => {
986
1371
  const field2 = projection.createFieldProjection();
987
1372
  setField(field2);
988
1373
  }, [
989
1374
  view
990
1375
  ]);
991
- const handleMove = (0, import_react9.useCallback)((fromIndex, toIndex) => {
992
- (0, import_util4.arrayMove)(view.fields, fromIndex, toIndex);
1376
+ const handleMove = (0, import_react14.useCallback)((fromIndex, toIndex) => {
1377
+ const fields = [
1378
+ ...view.fields
1379
+ ];
1380
+ const [moved] = fields.splice(fromIndex, 1);
1381
+ fields.splice(toIndex, 0, moved);
1382
+ view.fields = fields;
993
1383
  }, [
994
1384
  view.fields
995
1385
  ]);
996
- const handleClose = (0, import_react9.useCallback)(() => setField(void 0), []);
997
- return /* @__PURE__ */ import_react9.default.createElement("div", {
1386
+ const handleClose = (0, import_react14.useCallback)(() => setField(void 0), []);
1387
+ return /* @__PURE__ */ import_react14.default.createElement("div", {
998
1388
  role: "none",
999
- className: (0, import_react_ui_theme4.mx)("flex flex-col w-full divide-y divide-separator", classNames)
1000
- }, /* @__PURE__ */ import_react9.default.createElement(Form, {
1001
- autoFocus: true,
1389
+ className: (0, import_react_ui_theme9.mx)("flex flex-col w-full divide-y divide-separator", classNames)
1390
+ }, /* @__PURE__ */ import_react14.default.createElement(Form, {
1002
1391
  autoSave: true,
1003
1392
  schema: ViewMetaSchema,
1004
1393
  values: viewValues,
1005
1394
  onSave: handleViewUpdate
1006
- }), /* @__PURE__ */ import_react9.default.createElement("div", null, /* @__PURE__ */ import_react9.default.createElement("div", {
1395
+ }), /* @__PURE__ */ import_react14.default.createElement("div", null, /* @__PURE__ */ import_react14.default.createElement("div", {
1007
1396
  role: "none",
1008
1397
  className: "p-2"
1009
- }, /* @__PURE__ */ import_react9.default.createElement("label", {
1010
- className: (0, import_react_ui_theme4.mx)(import_react_ui_theme4.inputTextLabel)
1011
- }, t("fields label"))), /* @__PURE__ */ import_react9.default.createElement(import_react_ui_list.List.Root, {
1398
+ }, /* @__PURE__ */ import_react14.default.createElement("label", {
1399
+ className: (0, import_react_ui_theme9.mx)(import_react_ui_theme9.inputTextLabel)
1400
+ }, t("fields label"))), /* @__PURE__ */ import_react14.default.createElement(import_react_ui_list2.List.Root, {
1012
1401
  items: view.fields,
1013
- isItem: import_echo_schema5.S.is(import_schema4.FieldSchema),
1402
+ isItem: import_echo_schema8.S.is(import_schema5.FieldSchema),
1014
1403
  getId: (field2) => field2.id,
1015
1404
  onMove: handleMove
1016
- }, ({ items: fields }) => /* @__PURE__ */ import_react9.default.createElement(import_react9.default.Fragment, null, showHeading && /* @__PURE__ */ import_react9.default.createElement("div", {
1405
+ }, ({ items: fields }) => /* @__PURE__ */ import_react14.default.createElement(import_react14.default.Fragment, null, showHeading && /* @__PURE__ */ import_react14.default.createElement("div", {
1017
1406
  role: "heading",
1018
1407
  className: grid
1019
- }, /* @__PURE__ */ import_react9.default.createElement("div", null), /* @__PURE__ */ import_react9.default.createElement("div", {
1408
+ }, /* @__PURE__ */ import_react14.default.createElement("div", null), /* @__PURE__ */ import_react14.default.createElement("div", {
1020
1409
  className: "flex items-center text-sm"
1021
- }, t("field path label"))), /* @__PURE__ */ import_react9.default.createElement("div", {
1410
+ }, t("field path label"))), /* @__PURE__ */ import_react14.default.createElement("div", {
1022
1411
  role: "list",
1023
1412
  className: "flex flex-col w-full"
1024
- }, fields?.map((field2) => /* @__PURE__ */ import_react9.default.createElement(import_react_ui_list.List.Item, {
1413
+ }, fields?.map((field2) => /* @__PURE__ */ import_react14.default.createElement(import_react_ui_list2.List.Item, {
1025
1414
  key: field2.id,
1026
1415
  item: field2,
1027
- classNames: (0, import_react_ui_theme4.mx)(grid, import_react_ui_theme4.ghostHover, "cursor-pointer")
1028
- }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui_list.List.ItemDragHandle, null), /* @__PURE__ */ import_react9.default.createElement(import_react_ui_list.List.ItemTitle, {
1416
+ classNames: (0, import_react_ui_theme9.mx)(grid, import_react_ui_theme9.ghostHover, "cursor-pointer")
1417
+ }, /* @__PURE__ */ import_react14.default.createElement(import_react_ui_list2.List.ItemDragHandle, null), /* @__PURE__ */ import_react14.default.createElement(import_react_ui_list2.List.ItemTitle, {
1029
1418
  onClick: () => handleSelect(field2)
1030
- }, field2.path), /* @__PURE__ */ import_react9.default.createElement(import_react_ui_list.List.ItemDeleteButton, {
1419
+ }, field2.path), /* @__PURE__ */ import_react14.default.createElement(import_react_ui_list2.List.ItemDeleteButton, {
1031
1420
  disabled: view.fields.length <= 1,
1032
1421
  onClick: () => onDelete(field2.id)
1033
- }))))))), field && /* @__PURE__ */ import_react9.default.createElement(FieldEditor, {
1422
+ }))))))), field && /* @__PURE__ */ import_react14.default.createElement(FieldEditor, {
1034
1423
  key: field.id,
1035
1424
  view,
1036
1425
  projection,
1037
1426
  field,
1038
1427
  registry,
1039
1428
  onSave: handleClose
1040
- }), !readonly && !field && /* @__PURE__ */ import_react9.default.createElement("div", {
1429
+ }), !readonly && !field && /* @__PURE__ */ import_react14.default.createElement("div", {
1041
1430
  className: "flex p-2 justify-center"
1042
- }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui8.IconButton, {
1431
+ }, /* @__PURE__ */ import_react14.default.createElement(import_react_ui10.IconButton, {
1043
1432
  icon: "ph--plus--regular",
1044
1433
  label: t("button add property"),
1045
1434
  onClick: handleAdd,
1046
1435
  // TODO(burdon): Show field limit in ux (not tooltip).
1047
- disabled: view.fields.length >= import_schema4.VIEW_FIELD_LIMIT
1436
+ disabled: view.fields.length >= import_schema5.VIEW_FIELD_LIMIT
1048
1437
  })));
1049
1438
  };
1050
1439
  var parseValue = ({ type, format, value }) => {
@@ -1053,7 +1442,7 @@ var parseValue = ({ type, format, value }) => {
1053
1442
  }
1054
1443
  const parseScalar = (type2) => {
1055
1444
  switch (type2) {
1056
- case import_echo_schema6.TypeEnum.Boolean: {
1445
+ case import_echo_schema9.TypeEnum.Boolean: {
1057
1446
  if (typeof value === "string") {
1058
1447
  const lowercaseValue = value.toLowerCase();
1059
1448
  if (lowercaseValue === "0" || lowercaseValue === "false") {
@@ -1064,13 +1453,13 @@ var parseValue = ({ type, format, value }) => {
1064
1453
  }
1065
1454
  return Boolean(value);
1066
1455
  }
1067
- case import_echo_schema6.TypeEnum.Number: {
1456
+ case import_echo_schema9.TypeEnum.Number: {
1068
1457
  const cleaned = typeof value === "string" ? value.replace(/[^0-9.-]+/g, "") : value;
1069
1458
  const num = Number(cleaned);
1070
1459
  return Number.isNaN(num) ? null : num;
1071
1460
  }
1072
- case import_echo_schema6.TypeEnum.String:
1073
- case import_echo_schema6.TypeEnum.Ref:
1461
+ case import_echo_schema9.TypeEnum.String:
1462
+ case import_echo_schema9.TypeEnum.Ref:
1074
1463
  return String(value);
1075
1464
  default: {
1076
1465
  return value;
@@ -1081,25 +1470,45 @@ var parseValue = ({ type, format, value }) => {
1081
1470
  return parseScalar(type);
1082
1471
  }
1083
1472
  switch (format) {
1084
- case import_echo_schema6.FormatEnum.Boolean:
1085
- return parseScalar(import_echo_schema6.TypeEnum.Boolean);
1086
- case import_echo_schema6.FormatEnum.Number:
1087
- case import_echo_schema6.FormatEnum.Percent:
1088
- case import_echo_schema6.FormatEnum.Currency:
1089
- return parseScalar(import_echo_schema6.TypeEnum.Number);
1090
- case import_echo_schema6.FormatEnum.String:
1091
- case import_echo_schema6.FormatEnum.Markdown: {
1092
- return parseScalar(import_echo_schema6.TypeEnum.String);
1473
+ case import_echo_schema9.FormatEnum.Boolean:
1474
+ return parseScalar(import_echo_schema9.TypeEnum.Boolean);
1475
+ case import_echo_schema9.FormatEnum.Number:
1476
+ case import_echo_schema9.FormatEnum.Percent:
1477
+ case import_echo_schema9.FormatEnum.Currency:
1478
+ return parseScalar(import_echo_schema9.TypeEnum.Number);
1479
+ case import_echo_schema9.FormatEnum.String:
1480
+ case import_echo_schema9.FormatEnum.Markdown: {
1481
+ return parseScalar(import_echo_schema9.TypeEnum.String);
1093
1482
  }
1094
- case import_echo_schema6.FormatEnum.Ref:
1095
- throw new Error(`unexpected format: ${import_echo_schema6.FormatEnum.Ref}`);
1096
- case import_echo_schema6.FormatEnum.DateTime:
1097
- case import_echo_schema6.FormatEnum.Date:
1098
- case import_echo_schema6.FormatEnum.Time:
1099
- case import_echo_schema6.FormatEnum.Timestamp: {
1483
+ case import_echo_schema9.FormatEnum.Ref:
1484
+ throw new Error(`unexpected format: ${import_echo_schema9.FormatEnum.Ref}`);
1485
+ case import_echo_schema9.FormatEnum.DateTime:
1486
+ case import_echo_schema9.FormatEnum.Date:
1487
+ case import_echo_schema9.FormatEnum.Time:
1488
+ case import_echo_schema9.FormatEnum.Timestamp: {
1100
1489
  const date = new Date(value);
1101
1490
  return isNaN(date.getTime()) ? null : date;
1102
1491
  }
1492
+ case import_echo_schema9.FormatEnum.GeoPoint: {
1493
+ if (typeof value === "string") {
1494
+ const cleaned = value.replace(/[^0-9.,-]+/g, "");
1495
+ const parts = cleaned.split(",");
1496
+ if (parts.length === 2) {
1497
+ const lat = parseFloat(parts[0]);
1498
+ const long = parseFloat(parts[1]);
1499
+ if (!isNaN(lat) && !isNaN(long)) {
1500
+ return import_echo_schema9.GeoLocation.toGeoPoint({
1501
+ latitude: lat,
1502
+ longitude: long
1503
+ });
1504
+ }
1505
+ }
1506
+ }
1507
+ return [
1508
+ 0,
1509
+ 0
1510
+ ];
1511
+ }
1103
1512
  default: {
1104
1513
  return value;
1105
1514
  }
@@ -1108,19 +1517,19 @@ var parseValue = ({ type, format, value }) => {
1108
1517
  var cellClassesForFieldType = ({ type, format }) => {
1109
1518
  if (!format) {
1110
1519
  switch (type) {
1111
- case import_echo_schema6.TypeEnum.Number:
1520
+ case import_echo_schema9.TypeEnum.Number:
1112
1521
  return [
1113
1522
  "text-right",
1114
1523
  "font-mono"
1115
1524
  ];
1116
- case import_echo_schema6.TypeEnum.Boolean:
1525
+ case import_echo_schema9.TypeEnum.Boolean:
1117
1526
  return [
1118
1527
  "text-right",
1119
1528
  "font-mono"
1120
1529
  ];
1121
- case import_echo_schema6.TypeEnum.String:
1530
+ case import_echo_schema9.TypeEnum.String:
1122
1531
  return void 0;
1123
- case import_echo_schema6.TypeEnum.Ref:
1532
+ case import_echo_schema9.TypeEnum.Ref:
1124
1533
  return void 0;
1125
1534
  default: {
1126
1535
  return void 0;
@@ -1128,20 +1537,20 @@ var cellClassesForFieldType = ({ type, format }) => {
1128
1537
  }
1129
1538
  }
1130
1539
  switch (format) {
1131
- case import_echo_schema6.FormatEnum.Markdown:
1540
+ case import_echo_schema9.FormatEnum.Markdown:
1132
1541
  return void 0;
1133
- case import_echo_schema6.FormatEnum.Timestamp:
1134
- case import_echo_schema6.FormatEnum.DateTime:
1135
- case import_echo_schema6.FormatEnum.Date:
1136
- case import_echo_schema6.FormatEnum.Time:
1542
+ case import_echo_schema9.FormatEnum.Timestamp:
1543
+ case import_echo_schema9.FormatEnum.DateTime:
1544
+ case import_echo_schema9.FormatEnum.Date:
1545
+ case import_echo_schema9.FormatEnum.Time:
1137
1546
  return [
1138
1547
  "font-mono"
1139
1548
  ];
1140
- case import_echo_schema6.FormatEnum.Currency:
1549
+ case import_echo_schema9.FormatEnum.Currency:
1141
1550
  return [
1142
1551
  "text-right"
1143
1552
  ];
1144
- case import_echo_schema6.FormatEnum.JSON:
1553
+ case import_echo_schema9.FormatEnum.JSON:
1145
1554
  return [
1146
1555
  "font-mono"
1147
1556
  ];
@@ -1159,12 +1568,12 @@ var pathNotUniqueError = (path) => ({
1159
1568
  var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
1160
1569
  const formatScalar = (type2) => {
1161
1570
  switch (type2) {
1162
- case import_echo_schema7.TypeEnum.Boolean:
1571
+ case import_echo_schema10.TypeEnum.Boolean:
1163
1572
  return value.toLocaleString().toUpperCase();
1164
- case import_echo_schema7.TypeEnum.Number:
1573
+ case import_echo_schema10.TypeEnum.Number:
1165
1574
  return value.toLocaleString(locale);
1166
- case import_echo_schema7.TypeEnum.String:
1167
- case import_echo_schema7.TypeEnum.Ref:
1575
+ case import_echo_schema10.TypeEnum.String:
1576
+ case import_echo_schema10.TypeEnum.Ref:
1168
1577
  return String(value);
1169
1578
  default: {
1170
1579
  return String(value);
@@ -1175,20 +1584,20 @@ var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
1175
1584
  return formatScalar(type);
1176
1585
  }
1177
1586
  switch (format) {
1178
- case import_echo_schema7.FormatEnum.Boolean: {
1179
- return formatScalar(import_echo_schema7.TypeEnum.Boolean);
1587
+ case import_echo_schema10.FormatEnum.Boolean: {
1588
+ return formatScalar(import_echo_schema10.TypeEnum.Boolean);
1180
1589
  }
1181
- case import_echo_schema7.FormatEnum.Number: {
1182
- return formatScalar(import_echo_schema7.TypeEnum.Number);
1590
+ case import_echo_schema10.FormatEnum.Number: {
1591
+ return formatScalar(import_echo_schema10.TypeEnum.Number);
1183
1592
  }
1184
- case import_echo_schema7.FormatEnum.String:
1185
- case import_echo_schema7.FormatEnum.Ref: {
1186
- return formatScalar(import_echo_schema7.TypeEnum.String);
1593
+ case import_echo_schema10.FormatEnum.String:
1594
+ case import_echo_schema10.FormatEnum.Ref: {
1595
+ return formatScalar(import_echo_schema10.TypeEnum.String);
1187
1596
  }
1188
- case import_echo_schema7.FormatEnum.Percent: {
1597
+ case import_echo_schema10.FormatEnum.Percent: {
1189
1598
  return `${value * 100}%`;
1190
1599
  }
1191
- case import_echo_schema7.FormatEnum.Currency: {
1600
+ case import_echo_schema10.FormatEnum.Currency: {
1192
1601
  return value.toLocaleString(locale, {
1193
1602
  style: "currency",
1194
1603
  currency: "USD",
@@ -1196,18 +1605,28 @@ var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
1196
1605
  maximumFractionDigits: 2
1197
1606
  });
1198
1607
  }
1199
- case import_echo_schema7.FormatEnum.DateTime:
1200
- case import_echo_schema7.FormatEnum.Date:
1201
- case import_echo_schema7.FormatEnum.Time: {
1608
+ case import_echo_schema10.FormatEnum.DateTime:
1609
+ case import_echo_schema10.FormatEnum.Date:
1610
+ case import_echo_schema10.FormatEnum.Time: {
1202
1611
  const date = new Date(value);
1203
- if (format === import_echo_schema7.FormatEnum.DateTime) {
1612
+ if (format === import_echo_schema10.FormatEnum.DateTime) {
1204
1613
  return date.toLocaleString(locale);
1205
- } else if (format === import_echo_schema7.FormatEnum.Date) {
1614
+ } else if (format === import_echo_schema10.FormatEnum.Date) {
1206
1615
  return date.toLocaleDateString(locale);
1207
1616
  } else {
1208
1617
  return date.toLocaleTimeString(locale);
1209
1618
  }
1210
1619
  }
1620
+ case import_echo_schema10.FormatEnum.GeoPoint: {
1621
+ if (value === null || value === void 0) {
1622
+ return "";
1623
+ }
1624
+ if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
1625
+ const { latitude, longitude } = import_echo_schema10.GeoLocation.fromGeoPoint(value);
1626
+ return `${latitude},${longitude}`;
1627
+ }
1628
+ return String(value);
1629
+ }
1211
1630
  default: {
1212
1631
  if (value === null || value === "undefined") {
1213
1632
  return "";
@@ -1219,10 +1638,10 @@ var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
1219
1638
  var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1220
1639
  const formatScalar = (type2) => {
1221
1640
  switch (type2) {
1222
- case import_echo_schema7.TypeEnum.Boolean:
1223
- case import_echo_schema7.TypeEnum.Number:
1224
- case import_echo_schema7.TypeEnum.String:
1225
- case import_echo_schema7.TypeEnum.Ref:
1641
+ case import_echo_schema10.TypeEnum.Boolean:
1642
+ case import_echo_schema10.TypeEnum.Number:
1643
+ case import_echo_schema10.TypeEnum.String:
1644
+ case import_echo_schema10.TypeEnum.Ref:
1226
1645
  return String(value);
1227
1646
  default:
1228
1647
  return String(value);
@@ -1232,30 +1651,40 @@ var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1232
1651
  return formatScalar(type);
1233
1652
  }
1234
1653
  switch (format) {
1235
- case import_echo_schema7.FormatEnum.Boolean:
1236
- case import_echo_schema7.FormatEnum.Number:
1237
- case import_echo_schema7.FormatEnum.String:
1238
- case import_echo_schema7.FormatEnum.Ref: {
1654
+ case import_echo_schema10.FormatEnum.Boolean:
1655
+ case import_echo_schema10.FormatEnum.Number:
1656
+ case import_echo_schema10.FormatEnum.String:
1657
+ case import_echo_schema10.FormatEnum.Ref: {
1239
1658
  return formatScalar(type);
1240
1659
  }
1241
- case import_echo_schema7.FormatEnum.Percent: {
1660
+ case import_echo_schema10.FormatEnum.Percent: {
1242
1661
  return String(value * 100);
1243
1662
  }
1244
- case import_echo_schema7.FormatEnum.Currency: {
1663
+ case import_echo_schema10.FormatEnum.Currency: {
1245
1664
  return String(value);
1246
1665
  }
1247
- case import_echo_schema7.FormatEnum.DateTime: {
1666
+ case import_echo_schema10.FormatEnum.DateTime: {
1248
1667
  const date = new Date(value);
1249
1668
  return date.toISOString();
1250
1669
  }
1251
- case import_echo_schema7.FormatEnum.Date: {
1670
+ case import_echo_schema10.FormatEnum.Date: {
1252
1671
  const date = new Date(value);
1253
1672
  return date.toISOString().split("T")[0];
1254
1673
  }
1255
- case import_echo_schema7.FormatEnum.Time: {
1674
+ case import_echo_schema10.FormatEnum.Time: {
1256
1675
  const date = new Date(value);
1257
1676
  return date.toISOString().split("T")[1].split(".")[0];
1258
1677
  }
1678
+ case import_echo_schema10.FormatEnum.GeoPoint: {
1679
+ if (value === null || value === void 0) {
1680
+ return "";
1681
+ }
1682
+ if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
1683
+ const { latitude, longitude } = import_echo_schema10.GeoLocation.fromGeoPoint(value);
1684
+ return `${latitude},${longitude}`;
1685
+ }
1686
+ return String(value);
1687
+ }
1259
1688
  default: {
1260
1689
  return String(value);
1261
1690
  }
@@ -1264,14 +1693,16 @@ var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1264
1693
  // Annotate the CommonJS export names for ESM import in node:
1265
1694
  0 && (module.exports = {
1266
1695
  BooleanInput,
1696
+ DeprecatedFormContainer,
1267
1697
  DeprecatedFormInput,
1268
1698
  FieldEditor,
1269
1699
  Form,
1270
- FormActions,
1271
1700
  GeoPointInput,
1272
1701
  InputHeader,
1702
+ MarkdownInput,
1273
1703
  NumberInput,
1274
1704
  SelectInput,
1705
+ SelectOptionInput,
1275
1706
  TextInput,
1276
1707
  TupleInput,
1277
1708
  ViewEditor,
@@ -1282,6 +1713,7 @@ var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1282
1713
  parseValue,
1283
1714
  pathNotUniqueError,
1284
1715
  translations,
1285
- useForm
1716
+ useForm,
1717
+ useFormValues
1286
1718
  });
1287
1719
  //# sourceMappingURL=index.cjs.map