@dxos/react-ui-form 0.7.1 → 0.7.2-main.f1adc9f

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 (39) hide show
  1. package/dist/lib/browser/index.mjs +137 -111
  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 +130 -104
  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 +137 -111
  8. package/dist/lib/node-esm/index.mjs.map +4 -4
  9. package/dist/lib/node-esm/meta.json +1 -1
  10. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts +2 -2
  11. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
  12. package/dist/types/src/components/Form/Custom.d.ts +2 -1
  13. package/dist/types/src/components/Form/Custom.d.ts.map +1 -1
  14. package/dist/types/src/components/Form/Defaults.d.ts +11 -4
  15. package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
  16. package/dist/types/src/components/Form/Form.d.ts +6 -5
  17. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  18. package/dist/types/src/components/Form/Form.stories.d.ts +1 -4
  19. package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
  20. package/dist/types/src/components/Form/Input.d.ts +3 -8
  21. package/dist/types/src/components/Form/Input.d.ts.map +1 -1
  22. package/dist/types/src/components/Form/factory.d.ts +2 -2
  23. package/dist/types/src/components/Form/factory.d.ts.map +1 -1
  24. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
  25. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
  26. package/dist/types/src/hooks/useForm.d.ts +8 -7
  27. package/dist/types/src/hooks/useForm.d.ts.map +1 -1
  28. package/package.json +22 -24
  29. package/src/components/FieldEditor/FieldEditor.stories.tsx +2 -2
  30. package/src/components/FieldEditor/FieldEditor.tsx +8 -8
  31. package/src/components/Form/Custom.tsx +9 -9
  32. package/src/components/Form/Defaults.tsx +10 -5
  33. package/src/components/Form/Form.stories.tsx +6 -6
  34. package/src/components/Form/Form.tsx +52 -28
  35. package/src/components/Form/Input.tsx +3 -7
  36. package/src/components/Form/factory.tsx +4 -4
  37. package/src/components/ViewEditor/ViewEditor.stories.tsx +1 -2
  38. package/src/components/ViewEditor/ViewEditor.tsx +8 -7
  39. package/src/hooks/useForm.ts +18 -17
@@ -89,6 +89,8 @@ import { useTranslation as useTranslation3 } from "@dxos/react-ui";
89
89
  import { getFormatSchema, getSchemaProperties as getSchemaProperties2, sortProperties } from "@dxos/schema";
90
90
 
91
91
  // packages/ui/react-ui-form/src/components/Form/Form.tsx
92
+ import { pipe } from "effect";
93
+ import { capitalize } from "effect/String";
92
94
  import React5, { useEffect as useEffect2, useMemo as useMemo2 } from "react";
93
95
  import { AST, S } from "@dxos/echo-schema";
94
96
  import { findNode, getDiscriminatedType, isDiscriminatedUnion } from "@dxos/effect";
@@ -98,12 +100,9 @@ import { mx } from "@dxos/react-ui-theme";
98
100
  import { getSchemaProperties } from "@dxos/schema";
99
101
  import { isNotFalsy } from "@dxos/util";
100
102
 
101
- // packages/ui/react-ui-form/src/components/Form/factory.tsx
102
- import { FormatEnum } from "@dxos/echo-schema";
103
-
104
- // packages/ui/react-ui-form/src/components/Form/Custom.tsx
103
+ // packages/ui/react-ui-form/src/components/Form/Defaults.tsx
105
104
  import React3 from "react";
106
- import { Input as Input2, useTranslation } from "@dxos/react-ui";
105
+ import { Input as Input2, Select } from "@dxos/react-ui";
107
106
 
108
107
  // packages/ui/react-ui-form/src/components/Form/Input.tsx
109
108
  import React2 from "react";
@@ -124,57 +123,14 @@ var InputHeader = ({ children, error }) => {
124
123
  }, /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null), error)));
125
124
  };
126
125
 
127
- // packages/ui/react-ui-form/src/components/Form/Custom.tsx
128
- var LatLngInput = ({ property, type, label, disabled, getStatus, getValue, onValueChange, onBlur }) => {
129
- const { t } = useTranslation(translationKey);
130
- const { status, error } = getStatus?.(property);
131
- const { lat = 0, lng = 0 } = getValue(property) ?? {};
132
- return /* @__PURE__ */ React3.createElement(Input2.Root, {
133
- validationValence: status
134
- }, /* @__PURE__ */ React3.createElement(InputHeader, {
135
- error
136
- }, /* @__PURE__ */ React3.createElement(Input2.Label, null, label)), /* @__PURE__ */ React3.createElement("div", {
137
- className: "grid grid-cols-2 gap-2"
138
- }, /* @__PURE__ */ React3.createElement(Input2.TextInput, {
139
- type: "number",
140
- disabled,
141
- placeholder: t("placeholder latitude"),
142
- value: lat,
143
- onChange: (event) => onValueChange(property, type, {
144
- lat: safeParseFloat(event.target.value, 0),
145
- lng
146
- }),
147
- onBlur
148
- }), /* @__PURE__ */ React3.createElement(Input2.TextInput, {
149
- type: "number",
150
- disabled,
151
- placeholder: t("placeholder longitude"),
152
- value: lng,
153
- onChange: (event) => onValueChange(property, type, {
154
- lat,
155
- lng: safeParseFloat(event.target.value, 0)
156
- }),
157
- onBlur
158
- })));
159
- };
160
- var safeParseFloat = (str, defaultValue) => {
161
- try {
162
- return parseFloat(str);
163
- } catch {
164
- return defaultValue ?? 0;
165
- }
166
- };
167
-
168
126
  // packages/ui/react-ui-form/src/components/Form/Defaults.tsx
169
- import React4 from "react";
170
- import { Input as Input3, Select } from "@dxos/react-ui";
171
127
  var TextInput = ({ property, type, label, disabled, placeholder, getStatus, getValue, onValueChange, onBlur }) => {
172
128
  const { status, error } = getStatus?.(property);
173
- return /* @__PURE__ */ React4.createElement(Input3.Root, {
129
+ return /* @__PURE__ */ React3.createElement(Input2.Root, {
174
130
  validationValence: status
175
- }, /* @__PURE__ */ React4.createElement(InputHeader, {
131
+ }, /* @__PURE__ */ React3.createElement(InputHeader, {
176
132
  error
177
- }, /* @__PURE__ */ React4.createElement(Input3.Label, null, label)), /* @__PURE__ */ React4.createElement(Input3.TextInput, {
133
+ }, /* @__PURE__ */ React3.createElement(Input2.Label, null, label)), /* @__PURE__ */ React3.createElement(Input2.TextInput, {
178
134
  disabled,
179
135
  placeholder,
180
136
  value: getValue(property) ?? "",
@@ -184,11 +140,11 @@ var TextInput = ({ property, type, label, disabled, placeholder, getStatus, getV
184
140
  };
185
141
  var NumberInput = ({ property, type, label, disabled, placeholder, getStatus, getValue, onValueChange, onBlur }) => {
186
142
  const { status, error } = getStatus?.(property);
187
- return /* @__PURE__ */ React4.createElement(Input3.Root, {
143
+ return /* @__PURE__ */ React3.createElement(Input2.Root, {
188
144
  validationValence: status
189
- }, /* @__PURE__ */ React4.createElement(InputHeader, {
145
+ }, /* @__PURE__ */ React3.createElement(InputHeader, {
190
146
  error
191
- }, /* @__PURE__ */ React4.createElement(Input3.Label, null, label)), /* @__PURE__ */ React4.createElement(Input3.TextInput, {
147
+ }, /* @__PURE__ */ React3.createElement(Input2.Label, null, label)), /* @__PURE__ */ React3.createElement(Input2.TextInput, {
192
148
  type: "number",
193
149
  disabled,
194
150
  placeholder,
@@ -199,42 +155,88 @@ var NumberInput = ({ property, type, label, disabled, placeholder, getStatus, ge
199
155
  };
200
156
  var BooleanInput = ({ property, type, label, getStatus, getValue, onValueChange }) => {
201
157
  const { status, error } = getStatus?.(property);
202
- return /* @__PURE__ */ React4.createElement(Input3.Root, {
158
+ return /* @__PURE__ */ React3.createElement(Input2.Root, {
203
159
  validationValence: status
204
- }, /* @__PURE__ */ React4.createElement(InputHeader, {
160
+ }, /* @__PURE__ */ React3.createElement(InputHeader, {
205
161
  error
206
- }, /* @__PURE__ */ React4.createElement(Input3.Label, null, label)), /* @__PURE__ */ React4.createElement(Input3.Switch, {
162
+ }, /* @__PURE__ */ React3.createElement(Input2.Label, null, label)), /* @__PURE__ */ React3.createElement(Input2.Switch, {
207
163
  checked: getValue(property),
208
164
  onCheckedChange: (value) => onValueChange(property, type, value)
209
165
  }));
210
166
  };
211
167
  var SelectInput = ({ property, type, label, disabled, placeholder, options, getStatus, getValue, onValueChange }) => {
212
168
  const { status, error } = getStatus?.(property);
213
- return /* @__PURE__ */ React4.createElement(Input3.Root, {
169
+ return /* @__PURE__ */ React3.createElement(Input2.Root, {
214
170
  validationValence: status
215
- }, /* @__PURE__ */ React4.createElement(InputHeader, {
171
+ }, /* @__PURE__ */ React3.createElement(InputHeader, {
216
172
  error
217
- }, /* @__PURE__ */ React4.createElement(Input3.Label, null, label)), /* @__PURE__ */ React4.createElement(Select.Root, {
173
+ }, /* @__PURE__ */ React3.createElement(Input2.Label, null, label)), /* @__PURE__ */ React3.createElement(Select.Root, {
218
174
  value: getValue(property),
219
175
  onValueChange: (value) => onValueChange(property, type, value)
220
- }, /* @__PURE__ */ React4.createElement(Select.TriggerButton, {
176
+ }, /* @__PURE__ */ React3.createElement(Select.TriggerButton, {
221
177
  classNames: "is-full",
222
178
  disabled,
223
179
  placeholder
224
- }), /* @__PURE__ */ React4.createElement(Select.Portal, null, /* @__PURE__ */ React4.createElement(Select.Content, null, /* @__PURE__ */ React4.createElement(Select.Viewport, null, options?.map(({ value, label: label2 }) => (
180
+ }), /* @__PURE__ */ React3.createElement(Select.Portal, null, /* @__PURE__ */ React3.createElement(Select.Content, null, /* @__PURE__ */ React3.createElement(Select.Viewport, null, options?.map(({ value, label: label2 }) => (
225
181
  // NOTE: Numeric values are converted to and from strings.
226
- /* @__PURE__ */ React4.createElement(Select.Option, {
182
+ /* @__PURE__ */ React3.createElement(Select.Option, {
227
183
  key: String(value),
228
184
  value: String(value)
229
185
  }, label2 ?? String(value))
230
186
  )))))));
231
187
  };
232
188
 
189
+ // packages/ui/react-ui-form/src/components/Form/factory.tsx
190
+ import { FormatEnum } from "@dxos/echo-schema";
191
+
192
+ // packages/ui/react-ui-form/src/components/Form/Custom.tsx
193
+ import React4 from "react";
194
+ import { Input as Input3, useTranslation } from "@dxos/react-ui";
195
+ var GeiPointInput = ({ property, type, label, disabled, getStatus, getValue, onValueChange, onBlur }) => {
196
+ const { t } = useTranslation(translationKey);
197
+ const { status, error } = getStatus?.(property);
198
+ const [lng = 0, lat = 0] = getValue(property) ?? [];
199
+ return /* @__PURE__ */ React4.createElement(Input3.Root, {
200
+ validationValence: status
201
+ }, /* @__PURE__ */ React4.createElement(InputHeader, {
202
+ error
203
+ }, /* @__PURE__ */ React4.createElement(Input3.Label, null, label)), /* @__PURE__ */ React4.createElement("div", {
204
+ className: "grid grid-cols-2 gap-2"
205
+ }, /* @__PURE__ */ React4.createElement(Input3.TextInput, {
206
+ type: "number",
207
+ disabled,
208
+ placeholder: t("placeholder longitude"),
209
+ value: lng,
210
+ onChange: (event) => onValueChange(property, type, [
211
+ lat,
212
+ safeParseFloat(event.target.value, 0)
213
+ ]),
214
+ onBlur
215
+ }), /* @__PURE__ */ React4.createElement(Input3.TextInput, {
216
+ type: "number",
217
+ disabled,
218
+ placeholder: t("placeholder latitude"),
219
+ value: lat,
220
+ onChange: (event) => onValueChange(property, type, [
221
+ safeParseFloat(event.target.value, 0),
222
+ lng
223
+ ]),
224
+ onBlur
225
+ })));
226
+ };
227
+ var safeParseFloat = (str, defaultValue) => {
228
+ try {
229
+ return parseFloat(str);
230
+ } catch {
231
+ return defaultValue ?? 0;
232
+ }
233
+ };
234
+
233
235
  // packages/ui/react-ui-form/src/components/Form/factory.tsx
234
236
  var getInputComponent = (type, format) => {
235
237
  switch (format) {
236
238
  case FormatEnum.LatLng:
237
- return LatLngInput;
239
+ return GeiPointInput;
238
240
  }
239
241
  switch (type) {
240
242
  case "string":
@@ -252,7 +254,7 @@ import { invariant } from "@dxos/invariant";
252
254
  import { log } from "@dxos/log";
253
255
  import { validateSchema } from "@dxos/schema";
254
256
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/hooks/useForm.ts";
255
- var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, onSubmit }) => {
257
+ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, onSave }) => {
256
258
  const [values, setValues] = useState(initialValues);
257
259
  useEffect(() => {
258
260
  setValues(initialValues);
@@ -286,21 +288,21 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
286
288
  values,
287
289
  schemaDirty
288
290
  ]);
289
- const canSubmit = useMemo(() => Object.keys(values).every((property) => touched[property] === false || !errors[property]), [
291
+ const canSave = useMemo(() => Object.keys(values).every((property) => touched[property] === false || !errors[property]), [
290
292
  values,
291
293
  touched,
292
294
  errors
293
295
  ]);
294
- const handleSubmit = useCallback(() => {
296
+ const handleSave = useCallback(() => {
295
297
  if (validate(values)) {
296
- onSubmit?.(values, {
298
+ onSave?.(values, {
297
299
  changed
298
300
  });
299
301
  }
300
302
  }, [
301
303
  values,
302
304
  validate,
303
- onSubmit
305
+ onSave
304
306
  ]);
305
307
  const getStatus = useCallback((property) => ({
306
308
  status: errors[property] ? "error" : void 0,
@@ -321,7 +323,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
321
323
  } catch (err) {
322
324
  log.catch(err, void 0, {
323
325
  F: __dxlog_file,
324
- L: 164,
326
+ L: 165,
325
327
  S: void 0,
326
328
  C: (f, a) => f(...a)
327
329
  });
@@ -364,8 +366,8 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
364
366
  errors,
365
367
  touched,
366
368
  changed,
367
- canSubmit,
368
- handleSubmit,
369
+ canSave,
370
+ handleSave,
369
371
  // Field utils.
370
372
  getStatus,
371
373
  getValue,
@@ -376,7 +378,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
376
378
  var createKeySet = (obj, value) => {
377
379
  invariant(obj, void 0, {
378
380
  F: __dxlog_file,
379
- L: 215,
381
+ L: 216,
380
382
  S: void 0,
381
383
  A: [
382
384
  "obj",
@@ -400,25 +402,25 @@ var flatMap = (errors) => {
400
402
  // packages/ui/react-ui-form/src/components/Form/Form.tsx
401
403
  var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/Form/Form.tsx";
402
404
  var padding = "px-2";
403
- var Form = ({ classNames, schema, values: initialValues, path = [], readonly, filter, sort, autoSave, onValuesChanged, onValidate, onSubmit, onCancel, Custom }) => {
405
+ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, filter, sort, autoSave, onValuesChanged, onValidate, onSave, onCancel, Custom }) => {
404
406
  const { t } = useTranslation2(translationKey);
405
- const onValid = useMemo2(() => autoSave ? onSubmit : void 0, [
407
+ const onValid = useMemo2(() => autoSave ? onSave : void 0, [
406
408
  autoSave,
407
- onSubmit
409
+ onSave
408
410
  ]);
409
- const { canSubmit, values, errors, handleSubmit, ...inputProps } = useForm({
411
+ const { canSave, values, errors, handleSave, ...inputProps } = useForm({
410
412
  schema,
411
413
  initialValues,
412
414
  onValuesChanged,
413
415
  onValidate,
414
416
  onValid,
415
- onSubmit
417
+ onSave
416
418
  });
417
- const props = useMemo2(() => {
418
- const props2 = getSchemaProperties(schema.ast, values);
419
- const filtered = filter ? filter(props2) : props2;
420
- const findIndex = (props3, prop) => {
421
- const idx = props3.findIndex((p) => p === prop);
419
+ const properties = useMemo2(() => {
420
+ const props = getSchemaProperties(schema.ast, values);
421
+ const filtered = filter ? filter(props) : props;
422
+ const findIndex = (props2, prop) => {
423
+ const idx = props2.findIndex((p) => p === prop);
422
424
  return idx === -1 ? Infinity : idx;
423
425
  };
424
426
  return sort ? filtered.sort(({ name: a }, { name: b }) => findIndex(sort, a) - findIndex(sort, b)) : filtered;
@@ -433,7 +435,7 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
433
435
  errors
434
436
  }, {
435
437
  F: __dxlog_file2,
436
- L: 93,
438
+ L: 96,
437
439
  S: void 0,
438
440
  C: (f, a) => f(...a)
439
441
  });
@@ -444,16 +446,41 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
444
446
  return /* @__PURE__ */ React5.createElement("div", {
445
447
  role: "form",
446
448
  className: mx("flex flex-col w-full gap-2 py-2", classNames)
447
- }, props.map(({ prop, name, type, format, title, description, examples }) => {
449
+ }, properties.map((property) => {
450
+ const { ast, name, type, format, title, description, examples, options } = property;
448
451
  const key = [
449
452
  ...path,
450
453
  name
451
454
  ];
452
- const InputComponent = Custom?.[key.join(".")] ?? getInputComponent(type, format);
455
+ const label = title ?? pipe(name, capitalize);
456
+ const placeholder = examples?.length ? `Example: "${examples[0]}"` : description;
457
+ let InputComponent = Custom?.[key.join(".")];
458
+ if (!InputComponent) {
459
+ if (options) {
460
+ return /* @__PURE__ */ React5.createElement("div", {
461
+ key: name,
462
+ role: "none",
463
+ className: padding
464
+ }, /* @__PURE__ */ React5.createElement(SelectInput, {
465
+ type,
466
+ format,
467
+ property: name,
468
+ disabled: readonly,
469
+ label,
470
+ options: options.map((option) => ({
471
+ value: option,
472
+ label: String(option)
473
+ })),
474
+ placeholder,
475
+ ...inputProps
476
+ }));
477
+ }
478
+ InputComponent = getInputComponent(type, format);
479
+ }
453
480
  if (!InputComponent) {
454
481
  if (type === "object") {
455
- const baseNode = findNode(prop.type, isDiscriminatedUnion);
456
- const typeLiteral = baseNode ? getDiscriminatedType(baseNode, values[name]) : findNode(prop.type, AST.isTypeLiteral);
482
+ const baseNode = findNode(ast, isDiscriminatedUnion);
483
+ const typeLiteral = baseNode ? getDiscriminatedType(baseNode, values[name]) : findNode(ast, AST.isTypeLiteral);
457
484
  if (typeLiteral) {
458
485
  const schema2 = S.make(typeLiteral);
459
486
  return /* @__PURE__ */ React5.createElement("div", {
@@ -461,7 +488,7 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
461
488
  role: "none"
462
489
  }, /* @__PURE__ */ React5.createElement("div", {
463
490
  className: padding
464
- }, title ?? name), /* @__PURE__ */ React5.createElement(Form, {
491
+ }, label), /* @__PURE__ */ React5.createElement(Form, {
465
492
  schema: schema2,
466
493
  path: key,
467
494
  values: values[name] ?? {},
@@ -477,13 +504,12 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
477
504
  type
478
505
  }, {
479
506
  F: __dxlog_file2,
480
- L: 132,
507
+ L: 160,
481
508
  S: void 0,
482
509
  C: (f, a) => f(...a)
483
510
  });
484
511
  return null;
485
512
  }
486
- const placeholder = examples?.length ? `Example: ${examples[0]}` : description;
487
513
  return /* @__PURE__ */ React5.createElement("div", {
488
514
  key: name,
489
515
  role: "none",
@@ -493,11 +519,11 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
493
519
  format,
494
520
  property: name,
495
521
  disabled: readonly,
496
- label: title ?? name,
522
+ label,
497
523
  placeholder,
498
524
  ...inputProps
499
525
  }));
500
- }).filter(isNotFalsy), (onCancel || onSubmit) && !autoSave && /* @__PURE__ */ React5.createElement("div", {
526
+ }).filter(isNotFalsy), (onCancel || onSave) && !autoSave && /* @__PURE__ */ React5.createElement("div", {
501
527
  role: "none",
502
528
  className: "flex justify-center"
503
529
  }, /* @__PURE__ */ React5.createElement("div", {
@@ -507,18 +533,18 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
507
533
  icon: "ph--x--regular",
508
534
  label: t("button cancel"),
509
535
  onClick: onCancel
510
- }), onSubmit && /* @__PURE__ */ React5.createElement(IconButton, {
536
+ }), onSave && /* @__PURE__ */ React5.createElement(IconButton, {
511
537
  type: "submit",
512
- disabled: !canSubmit,
538
+ disabled: !canSave,
513
539
  icon: "ph--check--regular",
514
540
  label: t("button save"),
515
- onClick: handleSubmit
541
+ onClick: handleSave
516
542
  }))));
517
543
  };
518
544
 
519
545
  // packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx
520
546
  var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
521
- var FieldEditor = ({ view, projection, field, registry, onClose, onCancel }) => {
547
+ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
522
548
  const { t } = useTranslation3(translationKey);
523
549
  const [props, setProps] = useState2(projection.getFieldProjection(field.id).props);
524
550
  useEffect3(() => setProps(projection.getFieldProjection(field.id).props), [
@@ -589,22 +615,22 @@ var FieldEditor = ({ view, projection, field, registry, onClose, onCancel }) =>
589
615
  view.fields,
590
616
  field
591
617
  ]);
592
- const handleSubmit = useCallback2((props2) => {
618
+ const handleSave = useCallback2((props2) => {
593
619
  projection.setFieldProjection({
594
620
  field,
595
621
  props: props2
596
622
  });
597
- onClose();
623
+ onSave();
598
624
  }, [
599
625
  projection,
600
626
  field,
601
- onClose
627
+ onSave
602
628
  ]);
603
629
  const handleCancel = useCallback2(() => {
604
630
  requestAnimationFrame(() => onCancel?.());
605
- onClose();
631
+ onSave();
606
632
  }, [
607
- onClose
633
+ onSave
608
634
  ]);
609
635
  if (!fieldSchema) {
610
636
  log3.warn("invalid format", {
@@ -629,7 +655,7 @@ var FieldEditor = ({ view, projection, field, registry, onClose, onCancel }) =>
629
655
  ],
630
656
  onValuesChanged: handleValuesChanged,
631
657
  onValidate: handleValidate,
632
- onSubmit: handleSubmit,
658
+ onSave: handleSave,
633
659
  onCancel: handleCancel,
634
660
  Custom: {
635
661
  ["format"]: (props2) => /* @__PURE__ */ React6.createElement(SelectInput, {
@@ -668,7 +694,7 @@ var ViewMetaSchema = S2.Struct({
668
694
  name: S2.String.annotations({
669
695
  [AST2.TitleAnnotationId]: "View"
670
696
  }),
671
- type: Format.DXN.annotations({
697
+ typename: Format.DXN.annotations({
672
698
  [AST2.TitleAnnotationId]: "Typename"
673
699
  })
674
700
  }).pipe(S2.mutable);
@@ -684,16 +710,16 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
684
710
  name: view.name,
685
711
  // TODO(burdon): Need to warn user of possible consequences of editing.
686
712
  // TODO(burdon): Settings should have domain name owned by user.
687
- type: view.query.type
713
+ typename: view.query.typename
688
714
  };
689
715
  }, [
690
716
  view
691
717
  ]);
692
- const handleViewUpdate = useCallback3(({ name, type }) => {
718
+ const handleViewUpdate = useCallback3(({ name, typename }) => {
693
719
  requestAnimationFrame(() => {
694
720
  view.name = name;
695
- view.query.type = type;
696
- schema.updateTypename(type);
721
+ view.query.typename = typename;
722
+ schema.updateTypename(typename);
697
723
  });
698
724
  }, [
699
725
  view,
@@ -722,7 +748,7 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
722
748
  autoSave: true,
723
749
  schema: ViewMetaSchema,
724
750
  values: viewValues,
725
- onSubmit: handleViewUpdate
751
+ onSave: handleViewUpdate
726
752
  }), /* @__PURE__ */ React7.createElement("div", null, /* @__PURE__ */ React7.createElement("div", {
727
753
  role: "none",
728
754
  className: "p-2"
@@ -756,7 +782,7 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
756
782
  projection,
757
783
  field,
758
784
  registry,
759
- onClose: handleClose
785
+ onSave: handleClose
760
786
  }), !readonly && !field && /* @__PURE__ */ React7.createElement("div", {
761
787
  className: "flex p-2 justify-center"
762
788
  }, /* @__PURE__ */ React7.createElement(IconButton2, {
@@ -992,8 +1018,8 @@ export {
992
1018
  DeprecatedFormInput,
993
1019
  FieldEditor,
994
1020
  Form,
1021
+ GeiPointInput,
995
1022
  InputHeader,
996
- LatLngInput,
997
1023
  NumberInput,
998
1024
  SelectInput,
999
1025
  TextInput,