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