@dxos/react-ui-form 0.7.5-labs.c0e040f → 0.7.5-labs.d199c0f

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 (56) hide show
  1. package/dist/lib/browser/index.mjs +200 -92
  2. package/dist/lib/browser/index.mjs.map +3 -3
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +224 -116
  5. package/dist/lib/node/index.cjs.map +3 -3
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/lib/node-esm/index.mjs +200 -92
  8. package/dist/lib/node-esm/index.mjs.map +3 -3
  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 +1 -2
  13. package/dist/types/src/components/Form/ArrayField.d.ts.map +1 -1
  14. package/dist/types/src/components/Form/Defaults.d.ts +5 -6
  15. package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
  16. package/dist/types/src/components/Form/Form.d.ts +2 -2
  17. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  18. package/dist/types/src/components/Form/FormActions.d.ts +1 -2
  19. package/dist/types/src/components/Form/FormActions.d.ts.map +1 -1
  20. package/dist/types/src/components/Form/FormContent.d.ts +2 -3
  21. package/dist/types/src/components/Form/FormContent.d.ts.map +1 -1
  22. package/dist/types/src/components/Form/FormContext.d.ts +1 -1
  23. package/dist/types/src/components/Form/FormContext.d.ts.map +1 -1
  24. package/dist/types/src/components/Form/Input.d.ts +2 -2
  25. package/dist/types/src/components/Form/Input.d.ts.map +1 -1
  26. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts +1 -2
  27. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts.map +1 -1
  28. package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts +1 -2
  29. package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts.map +1 -1
  30. package/dist/types/src/components/Form/custom/TupleInput.d.ts +1 -2
  31. package/dist/types/src/components/Form/custom/TupleInput.d.ts.map +1 -1
  32. package/dist/types/src/components/ViewEditor/Test.stories.d.ts +1 -2
  33. package/dist/types/src/components/ViewEditor/Test.stories.d.ts.map +1 -1
  34. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +1 -2
  35. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
  36. package/dist/types/src/components/deprecated/Form.d.ts +1 -2
  37. package/dist/types/src/components/deprecated/Form.d.ts.map +1 -1
  38. package/dist/types/src/components/deprecated/Form.stories.d.ts +1 -2
  39. package/dist/types/src/components/deprecated/Form.stories.d.ts.map +1 -1
  40. package/dist/types/src/components/deprecated/FormInput.d.ts +2 -2
  41. package/dist/types/src/components/deprecated/FormInput.d.ts.map +1 -1
  42. package/dist/types/src/components/testing.d.ts +3 -3
  43. package/dist/types/src/components/testing.d.ts.map +1 -1
  44. package/dist/types/src/hooks/useForm.d.ts.map +1 -1
  45. package/dist/types/src/util/field.d.ts.map +1 -1
  46. package/dist/types/src/util/formatting.d.ts.map +1 -1
  47. package/package.json +25 -24
  48. package/src/components/Form/Defaults.tsx +1 -1
  49. package/src/components/Form/FormContext.tsx +11 -7
  50. package/src/components/Form/custom/GeoPointInput.tsx +42 -12
  51. package/src/components/Form/custom/SelectOptionsInput.tsx +2 -2
  52. package/src/components/Form/factory.tsx +1 -1
  53. package/src/hooks/useForm.ts +64 -41
  54. package/src/translations.ts +1 -1
  55. package/src/util/field.ts +19 -1
  56. package/src/util/formatting.ts +29 -1
@@ -29,7 +29,7 @@ var translations_default = [
29
29
  "format hostname": "Hostname",
30
30
  "format integer": "Integer",
31
31
  "format json": "JSON",
32
- "format latlng": "LatLng",
32
+ "format latlng": "Geopoint",
33
33
  "format markdown": "Markdown",
34
34
  "format percent": "Percent",
35
35
  "format ref": "Reference",
@@ -99,14 +99,14 @@ var DeprecatedFormInput = ({ label, description, secondary, children }) => {
99
99
  };
100
100
 
101
101
  // packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx
102
- import React12, { useCallback as useCallback5, useEffect as useEffect6, useMemo as useMemo5, useState as useState3 } from "react";
102
+ import React12, { useCallback as useCallback6, useEffect as useEffect7, useMemo as useMemo7, useState as useState4 } from "react";
103
103
  import { FormatEnum as FormatEnum2, FormatEnums, formatToType } from "@dxos/echo-schema";
104
104
  import { log as log2 } from "@dxos/log";
105
105
  import { useTranslation as useTranslation5 } from "@dxos/react-ui";
106
106
  import { getFormatSchema, getSchemaProperties as getSchemaProperties3, sortProperties } from "@dxos/schema";
107
107
 
108
108
  // packages/ui/react-ui-form/src/components/Form/FormContext.tsx
109
- import React2, { createContext, useContext, useEffect as useEffect2 } from "react";
109
+ import React2, { createContext, useContext, useEffect as useEffect2, useMemo as useMemo2 } from "react";
110
110
  import { raise } from "@dxos/debug";
111
111
  import { getValue as getValue2 } from "@dxos/echo-schema";
112
112
  import { createJsonPath as createJsonPath2 } from "@dxos/effect";
@@ -170,7 +170,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
170
170
  }, [
171
171
  errors
172
172
  ]);
173
- const canSave = useMemo(() => !saving && // Check if any error paths that are touched have errors
173
+ const canSave = useMemo(() => !saving && // Check if any error paths that are touched have errors.
174
174
  !Object.entries(touched).some(([path, isTouched]) => isTouched && Object.keys(errors).some((errorPath) => errorPath === path || errorPath.startsWith(`${path}.`) || errorPath.startsWith(`${path}[`))), [
175
175
  touched,
176
176
  errors,
@@ -203,10 +203,12 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
203
203
  }, [
204
204
  errors
205
205
  ]);
206
- const getFormValue = (path) => {
206
+ const getFormValue = useCallback((path) => {
207
207
  return getValue(values, createJsonPath(path));
208
- };
209
- const onValueChange = (path, type, value) => {
208
+ }, [
209
+ values
210
+ ]);
211
+ const onValueChange = useCallback((path, type, value) => {
210
212
  const jsonPath = createJsonPath(path);
211
213
  let parsedValue = value;
212
214
  try {
@@ -216,7 +218,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
216
218
  } catch (err) {
217
219
  log.catch(err, void 0, {
218
220
  F: __dxlog_file,
219
- L: 198,
221
+ L: 202,
220
222
  S: void 0,
221
223
  C: (f, a) => f(...a)
222
224
  });
@@ -237,7 +239,13 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
237
239
  changed
238
240
  });
239
241
  }
240
- };
242
+ }, [
243
+ values,
244
+ onValuesChanged,
245
+ validate,
246
+ onValid,
247
+ changed
248
+ ]);
241
249
  const onTouched = useCallback((path) => {
242
250
  const jsonPath = createJsonPath(path);
243
251
  setTouched((touched2) => ({
@@ -249,26 +257,39 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
249
257
  validate,
250
258
  values
251
259
  ]);
252
- return {
260
+ return useMemo(() => ({
253
261
  // State.
254
262
  values,
255
263
  errors,
256
264
  touched,
257
265
  changed,
258
266
  canSave,
259
- handleSave,
260
267
  formIsValid,
268
+ // Actions.
269
+ handleSave,
261
270
  // Field utils.
262
271
  getStatus,
263
272
  getValue: getFormValue,
264
273
  onValueChange,
265
274
  onTouched
266
- };
275
+ }), [
276
+ values,
277
+ errors,
278
+ touched,
279
+ changed,
280
+ canSave,
281
+ formIsValid,
282
+ handleSave,
283
+ getStatus,
284
+ getFormValue,
285
+ onValueChange,
286
+ onTouched
287
+ ]);
267
288
  };
268
289
  var createKeySet = (obj, value) => {
269
290
  invariant(obj, void 0, {
270
291
  F: __dxlog_file,
271
- L: 241,
292
+ L: 264,
272
293
  S: void 0,
273
294
  A: [
274
295
  "obj",
@@ -302,12 +323,21 @@ var useFormValues = (path = []) => {
302
323
  };
303
324
  var useInputProps = (path = []) => {
304
325
  const { getStatus, getValue: getFormValue, onValueChange, onTouched } = useFormContext();
305
- return {
306
- getStatus: () => getStatus(path),
307
- getValue: () => getFormValue(path),
308
- onValueChange: (type, value) => onValueChange(path, type, value),
309
- onBlur: () => onTouched(path)
310
- };
326
+ const stablePath = useMemo2(() => path, [
327
+ Array.isArray(path) ? path.join(".") : path
328
+ ]);
329
+ return useMemo2(() => ({
330
+ getStatus: () => getStatus(stablePath),
331
+ getValue: () => getFormValue(stablePath),
332
+ onValueChange: (type, value) => onValueChange(stablePath, type, value),
333
+ onBlur: () => onTouched(stablePath)
334
+ }), [
335
+ getStatus,
336
+ getFormValue,
337
+ onValueChange,
338
+ onTouched,
339
+ stablePath
340
+ ]);
311
341
  };
312
342
  var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
313
343
  const form = useForm(formOptions);
@@ -347,7 +377,8 @@ var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
347
377
  };
348
378
 
349
379
  // packages/ui/react-ui-form/src/components/Form/custom/GeoPointInput.tsx
350
- import React4 from "react";
380
+ import React4, { useCallback as useCallback2, useState as useState2, useEffect as useEffect3, useMemo as useMemo3 } from "react";
381
+ import { GeoLocation } from "@dxos/echo-schema";
351
382
  import { Input as Input2, useTranslation } from "@dxos/react-ui";
352
383
  import { safeParseFloat } from "@dxos/util";
353
384
 
@@ -374,51 +405,88 @@ var InputHeader = ({ children, error }) => {
374
405
  var GeoPointInput = ({ type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
375
406
  const { t } = useTranslation(translationKey);
376
407
  const { status, error } = getStatus();
377
- const [lng = 0, lat = 0] = getValue3() ?? [];
408
+ const geoPoint = useMemo3(() => getValue3() ?? [
409
+ 0,
410
+ 0
411
+ ], [
412
+ getValue3
413
+ ]);
414
+ const geoLocation = useMemo3(() => GeoLocation.fromGeoPoint(geoPoint), [
415
+ geoPoint
416
+ ]);
417
+ const [longitudeText, setLongitudeText] = useState2(geoLocation.longitude?.toString());
418
+ const [latitudeText, setLatitudeText] = useState2(geoLocation.latitude?.toString());
419
+ useEffect3(() => {
420
+ const location = GeoLocation.fromGeoPoint(geoPoint);
421
+ setLongitudeText(location.longitude.toString());
422
+ setLatitudeText(location.latitude.toString());
423
+ }, [
424
+ geoPoint
425
+ ]);
426
+ const handleCoordinateChange = useCallback2((coordinateType, setText) => (event) => {
427
+ const inputText = event.target.value;
428
+ setText(inputText);
429
+ if (inputText !== "" && inputText !== "-") {
430
+ const coord = safeParseFloat(inputText);
431
+ if (coord !== void 0 && !isNaN(coord)) {
432
+ const currentLocation = GeoLocation.fromGeoPoint(getValue3() ?? [
433
+ 0,
434
+ 0
435
+ ]);
436
+ const newLocation = {
437
+ ...currentLocation,
438
+ [coordinateType]: coord
439
+ };
440
+ const newValue = GeoLocation.toGeoPoint(newLocation);
441
+ onValueChange(type, newValue);
442
+ }
443
+ }
444
+ }, [
445
+ getValue3,
446
+ onValueChange,
447
+ type
448
+ ]);
378
449
  return /* @__PURE__ */ React4.createElement(Input2.Root, {
379
450
  validationValence: status
380
451
  }, /* @__PURE__ */ React4.createElement(InputHeader, {
381
452
  error
382
453
  }, /* @__PURE__ */ React4.createElement(Input2.Label, null, label)), /* @__PURE__ */ React4.createElement("div", {
454
+ role: "none",
383
455
  className: "grid grid-cols-2 gap-2"
384
456
  }, /* @__PURE__ */ React4.createElement(Input2.TextInput, {
385
- type: "number",
457
+ type: "text",
458
+ pattern: "^-?[0-9]*\\.?[0-9]*$",
386
459
  disabled,
387
- placeholder: t("placeholder longitude"),
388
- value: lng,
389
- onChange: (event) => onValueChange(type, [
390
- lat,
391
- safeParseFloat(event.target.value, 0)
392
- ]),
460
+ placeholder: t("placeholder latitude"),
461
+ value: latitudeText,
462
+ onChange: handleCoordinateChange("latitude", setLatitudeText),
393
463
  onBlur
394
464
  }), /* @__PURE__ */ React4.createElement(Input2.TextInput, {
395
- type: "number",
465
+ type: "text",
466
+ pattern: "^-?[0-9]*\\.?[0-9]*$",
396
467
  disabled,
397
- placeholder: t("placeholder latitude"),
398
- value: lat,
399
- onChange: (event) => onValueChange(type, [
400
- safeParseFloat(event.target.value, 0),
401
- lng
402
- ]),
468
+ placeholder: t("placeholder longitude"),
469
+ value: longitudeText,
470
+ onChange: handleCoordinateChange("longitude", setLongitudeText),
403
471
  onBlur
404
472
  })));
405
473
  };
406
474
 
407
475
  // packages/ui/react-ui-form/src/components/Form/custom/SelectOptionsInput.tsx
408
- import React5, { useCallback as useCallback2, useEffect as useEffect3, useState as useState2, useRef } from "react";
476
+ import React5, { useCallback as useCallback3, useEffect as useEffect4, useState as useState3, useRef } from "react";
409
477
  import { PublicKey } from "@dxos/keys";
410
478
  import { Icon as Icon2, IconButton, Input as Input3, Tag, Toolbar, useTranslation as useTranslation2 } from "@dxos/react-ui";
411
479
  import { List } from "@dxos/react-ui-list";
412
- import { HuePickerToolbarButton } from "@dxos/react-ui-pickers";
480
+ import { HuePicker } from "@dxos/react-ui-pickers";
413
481
  import { hues, mx as mx2 } from "@dxos/react-ui-theme";
414
482
  var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3, onValueChange }) => {
415
- const [selected, setSelectedId] = useState2(null);
416
- const [isNewOption, setIsNewOption] = useState2(false);
483
+ const [selected, setSelectedId] = useState3(null);
484
+ const [isNewOption, setIsNewOption] = useState3(false);
417
485
  const inputRef = useRef(null);
418
486
  const { t } = useTranslation2(translationKey);
419
487
  const { status, error } = getStatus();
420
488
  const options = getValue3();
421
- useEffect3(() => {
489
+ useEffect4(() => {
422
490
  if (options === void 0) {
423
491
  onValueChange(type, []);
424
492
  }
@@ -437,7 +505,7 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
437
505
  const availableHues = hues.filter((hue) => !lastThree.has(hue));
438
506
  return availableHues[Math.floor(Math.random() * availableHues.length)] ?? hues[Math.floor(Math.random() * hues.length)];
439
507
  };
440
- const handleAdd = useCallback2(() => {
508
+ const handleAdd = useCallback3(() => {
441
509
  const newId = PublicKey.random().truncate();
442
510
  const newOption = {
443
511
  id: newId,
@@ -455,7 +523,7 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
455
523
  type,
456
524
  onValueChange
457
525
  ]);
458
- const handleDelete = useCallback2((id) => {
526
+ const handleDelete = useCallback3((id) => {
459
527
  const newOptions = options?.filter((option) => option.id !== id) ?? [];
460
528
  onValueChange(type, newOptions);
461
529
  setSelectedId(null);
@@ -464,7 +532,7 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
464
532
  type,
465
533
  onValueChange
466
534
  ]);
467
- const handleMove = useCallback2((from, to) => {
535
+ const handleMove = useCallback3((from, to) => {
468
536
  if (!options) {
469
537
  return;
470
538
  }
@@ -479,10 +547,10 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
479
547
  type,
480
548
  onValueChange
481
549
  ]);
482
- const handleClick = useCallback2((id) => {
550
+ const handleClick = useCallback3((id) => {
483
551
  setSelectedId((current) => current === id ? null : id);
484
552
  }, []);
485
- const handleTitleChange = useCallback2((id) => (e) => {
553
+ const handleTitleChange = useCallback3((id) => (e) => {
486
554
  const newOptions = options?.map((o) => o.id === id ? {
487
555
  ...o,
488
556
  title: e.target.value
@@ -493,12 +561,12 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
493
561
  type,
494
562
  onValueChange
495
563
  ]);
496
- const handleKeyDown = useCallback2((e) => {
564
+ const handleKeyDown = useCallback3((e) => {
497
565
  if (e.key === "Enter") {
498
566
  setSelectedId(null);
499
567
  }
500
568
  }, []);
501
- const handleColorChange = useCallback2((id) => (hue) => {
569
+ const handleColorChange = useCallback3((id) => (hue) => {
502
570
  const newOptions = options?.map((o) => o.id === id ? {
503
571
  ...o,
504
572
  color: hue
@@ -509,7 +577,7 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
509
577
  type,
510
578
  onValueChange
511
579
  ]);
512
- useEffect3(() => {
580
+ useEffect4(() => {
513
581
  if (selected && isNewOption && inputRef.current) {
514
582
  inputRef.current.focus();
515
583
  setIsNewOption(false);
@@ -564,9 +632,9 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
564
632
  "data-no-submit": true
565
633
  }), /* @__PURE__ */ React5.createElement(Toolbar.Root, {
566
634
  classNames: "p-0 m-0 !is-auto"
567
- }, /* @__PURE__ */ React5.createElement(HuePickerToolbarButton, {
568
- hue: item.color,
569
- onChangeHue: handleColorChange(item.id)
635
+ }, /* @__PURE__ */ React5.createElement(HuePicker, {
636
+ value: item.color,
637
+ onChange: handleColorChange(item.id)
570
638
  })), /* @__PURE__ */ React5.createElement(IconButton, {
571
639
  icon: "ph--trash--fill",
572
640
  iconOnly: true,
@@ -621,7 +689,7 @@ var TupleInput = ({ binding, type, label, disabled, getStatus, getValue: getValu
621
689
  };
622
690
 
623
691
  // packages/ui/react-ui-form/src/components/Form/Defaults.tsx
624
- import React7, { useCallback as useCallback3, useEffect as useEffect4, useRef as useRef2 } from "react";
692
+ import React7, { useCallback as useCallback4, useEffect as useEffect5, useRef as useRef2 } from "react";
625
693
  import { Input as Input5, Select } from "@dxos/react-ui";
626
694
  var TextInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
627
695
  const { status, error } = getStatus();
@@ -688,19 +756,19 @@ var SelectInput = ({ type, label, inputOnly, disabled, placeholder, options, get
688
756
  var MarkdownInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
689
757
  const { status, error } = getStatus();
690
758
  const textareaRef = useRef2(null);
691
- const adjustHeight = useCallback3(() => {
759
+ const adjustHeight = useCallback4(() => {
692
760
  const textarea = textareaRef.current;
693
761
  if (textarea) {
694
762
  textarea.style.blockSize = "auto";
695
763
  textarea.style.blockSize = `${textarea.scrollHeight + 2}px`;
696
764
  }
697
765
  }, []);
698
- useEffect4(() => {
766
+ useEffect5(() => {
699
767
  adjustHeight();
700
768
  }, [
701
769
  adjustHeight
702
770
  ]);
703
- useEffect4(() => {
771
+ useEffect5(() => {
704
772
  adjustHeight();
705
773
  }, [
706
774
  getValue3(),
@@ -715,7 +783,7 @@ var MarkdownInput = ({ type, label, inputOnly, disabled, placeholder, getStatus,
715
783
  disabled,
716
784
  placeholder,
717
785
  value: getValue3() ?? "",
718
- classNames: "min-bs-auto overflow-hidden",
786
+ classNames: "min-bs-auto max-h-40 overflow-auto",
719
787
  onChange: (event) => onValueChange(type, event.target.value),
720
788
  onBlur,
721
789
  style: {
@@ -726,7 +794,7 @@ var MarkdownInput = ({ type, label, inputOnly, disabled, placeholder, getStatus,
726
794
  };
727
795
 
728
796
  // packages/ui/react-ui-form/src/components/Form/Form.tsx
729
- import React11, { useEffect as useEffect5, useMemo as useMemo4, useRef as useRef3 } from "react";
797
+ import React11, { useEffect as useEffect6, useMemo as useMemo6, useRef as useRef3 } from "react";
730
798
  import { mx as mx7 } from "@dxos/react-ui-theme";
731
799
 
732
800
  // packages/ui/react-ui-form/src/components/Form/FormActions.tsx
@@ -760,7 +828,7 @@ var FormActions = ({ onCancel, readonly }) => {
760
828
  // packages/ui/react-ui-form/src/components/Form/FormContent.tsx
761
829
  import { pipe as pipe2 } from "effect";
762
830
  import { capitalize as capitalize2 } from "effect/String";
763
- import React10, { useMemo as useMemo3 } from "react";
831
+ import React10, { useMemo as useMemo5 } from "react";
764
832
  import { AST as AST3, S } from "@dxos/echo-schema";
765
833
  import { createJsonPath as createJsonPath3, findNode as findNode2, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2 } from "@dxos/effect";
766
834
  import { mx as mx6 } from "@dxos/react-ui-theme";
@@ -770,7 +838,7 @@ import { isNotFalsy } from "@dxos/util";
770
838
  // packages/ui/react-ui-form/src/components/Form/ArrayField.tsx
771
839
  import { pipe } from "effect";
772
840
  import { capitalize } from "effect/String";
773
- import React9, { useCallback as useCallback4, useMemo as useMemo2 } from "react";
841
+ import React9, { useCallback as useCallback5, useMemo as useMemo4 } from "react";
774
842
  import { AST as AST2 } from "@dxos/echo-schema";
775
843
  import { findNode, getDiscriminatedType, isDiscriminatedUnion, SimpleType } from "@dxos/effect";
776
844
  import { invariant as invariant2 } from "@dxos/invariant";
@@ -806,7 +874,7 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
806
874
  prop.defaultValue
807
875
  ]));
808
876
  };
809
- const newValue = useMemo2(() => {
877
+ const newValue = useMemo4(() => {
810
878
  if (type === "object" && elementType) {
811
879
  return getDefaultObjectValue(elementType);
812
880
  } else {
@@ -816,7 +884,7 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
816
884
  type,
817
885
  elementType
818
886
  ]);
819
- const handleAdd = useCallback4(() => {
887
+ const handleAdd = useCallback5(() => {
820
888
  inputProps.onValueChange(type, [
821
889
  ...values,
822
890
  newValue
@@ -828,7 +896,7 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
828
896
  newValue,
829
897
  values
830
898
  ]);
831
- const handleRemove = useCallback4((index) => {
899
+ const handleRemove = useCallback5((index) => {
832
900
  const newValues = values.filter((_, i) => i !== index);
833
901
  inputProps.onValueChange(type, newValues);
834
902
  }, [
@@ -886,7 +954,7 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
886
954
  import { FormatEnum } from "@dxos/echo-schema";
887
955
  var getInputComponent = (type, format) => {
888
956
  switch (format) {
889
- case FormatEnum.LatLng:
957
+ case FormatEnum.GeoPoint:
890
958
  return GeoPointInput;
891
959
  case FormatEnum.Markdown:
892
960
  return MarkdownInput;
@@ -905,11 +973,11 @@ var getInputComponent = (type, format) => {
905
973
  var FormField = ({ property, path, readonly, inline, lookupComponent, Custom }) => {
906
974
  const inputProps = useInputProps(path);
907
975
  const { ast, name, type, format, title, description, options, examples, array } = property;
908
- const label = useMemo3(() => title ?? pipe2(name, capitalize2), [
976
+ const label = useMemo5(() => title ?? pipe2(name, capitalize2), [
909
977
  title,
910
978
  name
911
979
  ]);
912
- const placeholder = useMemo3(() => examples?.length ? `Example: "${examples[0]}"` : description, [
980
+ const placeholder = useMemo5(() => examples?.length ? `Example: "${examples[0]}"` : description, [
913
981
  examples,
914
982
  description
915
983
  ]);
@@ -1001,7 +1069,7 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
1001
1069
  };
1002
1070
  var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custom }) => {
1003
1071
  const values = useFormValues(path);
1004
- const properties = useMemo3(() => {
1072
+ const properties = useMemo5(() => {
1005
1073
  const props = getSchemaProperties2(schema.ast, values);
1006
1074
  const filtered = filter ? filter(props) : props;
1007
1075
  return sort ? filtered.sort((a, b) => sort.indexOf(a.name) - sort.indexOf(b.name)) : filtered;
@@ -1032,11 +1100,11 @@ var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custo
1032
1100
  // packages/ui/react-ui-form/src/components/Form/Form.tsx
1033
1101
  var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, lookupComponent, Custom }) => {
1034
1102
  const formRef = useRef3(null);
1035
- const onValid = useMemo4(() => autoSave ? onSave : void 0, [
1103
+ const onValid = useMemo6(() => autoSave ? onSave : void 0, [
1036
1104
  autoSave,
1037
1105
  onSave
1038
1106
  ]);
1039
- useEffect5(() => {
1107
+ useEffect6(() => {
1040
1108
  if (autoFocus && formRef.current) {
1041
1109
  const input = formRef.current.querySelector("input");
1042
1110
  if (input) {
@@ -1078,13 +1146,13 @@ var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, r
1078
1146
  var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
1079
1147
  var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1080
1148
  const { t } = useTranslation5(translationKey);
1081
- const [props, setProps] = useState3(projection.getFieldProjection(field.id).props);
1082
- useEffect6(() => setProps(projection.getFieldProjection(field.id).props), [
1149
+ const [props, setProps] = useState4(projection.getFieldProjection(field.id).props);
1150
+ useEffect7(() => setProps(projection.getFieldProjection(field.id).props), [
1083
1151
  field,
1084
1152
  projection
1085
1153
  ]);
1086
- const [schemas, setSchemas] = useState3([]);
1087
- useEffect6(() => {
1154
+ const [schemas, setSchemas] = useState4([]);
1155
+ useEffect7(() => {
1088
1156
  if (!registry) {
1089
1157
  return;
1090
1158
  }
@@ -1102,17 +1170,17 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1102
1170
  }, [
1103
1171
  registry
1104
1172
  ]);
1105
- const [referenceSchema, setReferenceSchema] = useState3();
1106
- useEffect6(() => {
1173
+ const [referenceSchema, setReferenceSchema] = useState4();
1174
+ useEffect7(() => {
1107
1175
  setReferenceSchema(schemas.find((schema) => schema.typename === props?.referenceSchema));
1108
1176
  }, [
1109
1177
  schemas,
1110
1178
  props?.referenceSchema
1111
1179
  ]);
1112
- const [{ fieldSchema }, setFieldSchema] = useState3({
1180
+ const [{ fieldSchema }, setFieldSchema] = useState4({
1113
1181
  fieldSchema: getFormatSchema(props?.format)
1114
1182
  });
1115
- const handleValuesChanged = useCallback5((_props) => {
1183
+ const handleValuesChanged = useCallback6((_props) => {
1116
1184
  setFieldSchema((prev) => {
1117
1185
  const fieldSchema2 = getFormatSchema(_props.format);
1118
1186
  if (prev.fieldSchema === fieldSchema2) {
@@ -1147,7 +1215,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1147
1215
  props.format,
1148
1216
  props.referenceSchema
1149
1217
  ]);
1150
- const handleValidate = useCallback5(({ property }) => {
1218
+ const handleValidate = useCallback6(({ property }) => {
1151
1219
  if (property && view.fields.find((f) => f.path === property && f.path !== field.path)) {
1152
1220
  return [
1153
1221
  {
@@ -1160,7 +1228,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1160
1228
  view.fields,
1161
1229
  field
1162
1230
  ]);
1163
- const handleSave = useCallback5((props2) => {
1231
+ const handleSave = useCallback6((props2) => {
1164
1232
  projection.setFieldProjection({
1165
1233
  field,
1166
1234
  props: props2
@@ -1171,13 +1239,13 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1171
1239
  field,
1172
1240
  onSave
1173
1241
  ]);
1174
- const handleCancel = useCallback5(() => {
1242
+ const handleCancel = useCallback6(() => {
1175
1243
  requestAnimationFrame(() => onCancel?.());
1176
1244
  onSave();
1177
1245
  }, [
1178
1246
  onSave
1179
1247
  ]);
1180
- const Custom = useMemo5(() => ({
1248
+ const Custom = useMemo7(() => ({
1181
1249
  ["format"]: (props2) => /* @__PURE__ */ React12.createElement(SelectInput, {
1182
1250
  ...props2,
1183
1251
  options: FormatEnums.filter((value) => value !== FormatEnum2.None).map((value) => ({
@@ -1203,7 +1271,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1203
1271
  schemas,
1204
1272
  referenceSchema
1205
1273
  ]);
1206
- const propIsNotType = useCallback5((props2) => props2.filter((p) => p.name !== "type"), []);
1274
+ const propIsNotType = useCallback6((props2) => props2.filter((p) => p.name !== "type"), []);
1207
1275
  if (!fieldSchema) {
1208
1276
  log2.warn("invalid format", {
1209
1277
  props
@@ -1234,7 +1302,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1234
1302
  };
1235
1303
 
1236
1304
  // packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx
1237
- import React13, { useCallback as useCallback6, useMemo as useMemo6, useState as useState4 } from "react";
1305
+ import React13, { useCallback as useCallback7, useMemo as useMemo8, useState as useState5 } from "react";
1238
1306
  import { AST as AST4, Format, S as S2 } from "@dxos/echo-schema";
1239
1307
  import { IconButton as IconButton4, useTranslation as useTranslation6 } from "@dxos/react-ui";
1240
1308
  import { List as List2 } from "@dxos/react-ui-list";
@@ -1251,12 +1319,12 @@ var ViewMetaSchema = S2.Struct({
1251
1319
  }).pipe(S2.mutable);
1252
1320
  var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading = false, onTypenameChanged, onDelete }) => {
1253
1321
  const { t } = useTranslation6(translationKey);
1254
- const projection = useMemo6(() => new ViewProjection(schema, view), [
1322
+ const projection = useMemo8(() => new ViewProjection(schema, view), [
1255
1323
  schema,
1256
1324
  view
1257
1325
  ]);
1258
- const [field, setField] = useState4();
1259
- const viewValues = useMemo6(() => {
1326
+ const [field, setField] = useState5();
1327
+ const viewValues = useMemo8(() => {
1260
1328
  return {
1261
1329
  name: view.name,
1262
1330
  // TODO(burdon): Need to warn user of possible consequences of editing.
@@ -1266,7 +1334,7 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1266
1334
  }, [
1267
1335
  view
1268
1336
  ]);
1269
- const handleViewUpdate = useCallback6(({ name, typename }) => {
1337
+ const handleViewUpdate = useCallback7(({ name, typename }) => {
1270
1338
  requestAnimationFrame(() => {
1271
1339
  if (view.name !== name) {
1272
1340
  view.name = name;
@@ -1280,16 +1348,16 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1280
1348
  schema,
1281
1349
  onTypenameChanged
1282
1350
  ]);
1283
- const handleSelect = useCallback6((field2) => {
1351
+ const handleSelect = useCallback7((field2) => {
1284
1352
  setField((f) => f === field2 ? void 0 : field2);
1285
1353
  }, []);
1286
- const handleAdd = useCallback6(() => {
1354
+ const handleAdd = useCallback7(() => {
1287
1355
  const field2 = projection.createFieldProjection();
1288
1356
  setField(field2);
1289
1357
  }, [
1290
1358
  view
1291
1359
  ]);
1292
- const handleMove = useCallback6((fromIndex, toIndex) => {
1360
+ const handleMove = useCallback7((fromIndex, toIndex) => {
1293
1361
  const fields = [
1294
1362
  ...view.fields
1295
1363
  ];
@@ -1299,7 +1367,7 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1299
1367
  }, [
1300
1368
  view.fields
1301
1369
  ]);
1302
- const handleClose = useCallback6(() => setField(void 0), []);
1370
+ const handleClose = useCallback7(() => setField(void 0), []);
1303
1371
  return /* @__PURE__ */ React13.createElement("div", {
1304
1372
  role: "none",
1305
1373
  className: mx8("flex flex-col w-full divide-y divide-separator", classNames)
@@ -1354,7 +1422,7 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1354
1422
  };
1355
1423
 
1356
1424
  // packages/ui/react-ui-form/src/util/field.ts
1357
- import { FormatEnum as FormatEnum3, TypeEnum } from "@dxos/echo-schema";
1425
+ import { FormatEnum as FormatEnum3, GeoLocation as GeoLocation2, TypeEnum } from "@dxos/echo-schema";
1358
1426
  var parseValue = ({ type, format, value }) => {
1359
1427
  if (value === void 0 || value === null || value === "") {
1360
1428
  return void 0;
@@ -1408,6 +1476,26 @@ var parseValue = ({ type, format, value }) => {
1408
1476
  const date = new Date(value);
1409
1477
  return isNaN(date.getTime()) ? null : date;
1410
1478
  }
1479
+ case FormatEnum3.GeoPoint: {
1480
+ if (typeof value === "string") {
1481
+ const cleaned = value.replace(/[^0-9.,-]+/g, "");
1482
+ const parts = cleaned.split(",");
1483
+ if (parts.length === 2) {
1484
+ const lat = parseFloat(parts[0]);
1485
+ const long = parseFloat(parts[1]);
1486
+ if (!isNaN(lat) && !isNaN(long)) {
1487
+ return GeoLocation2.toGeoPoint({
1488
+ latitude: lat,
1489
+ longitude: long
1490
+ });
1491
+ }
1492
+ }
1493
+ }
1494
+ return [
1495
+ 0,
1496
+ 0
1497
+ ];
1498
+ }
1411
1499
  default: {
1412
1500
  return value;
1413
1501
  }
@@ -1466,7 +1554,7 @@ var pathNotUniqueError = (path) => ({
1466
1554
  });
1467
1555
 
1468
1556
  // packages/ui/react-ui-form/src/util/formatting.ts
1469
- import { FormatEnum as FormatEnum4, TypeEnum as TypeEnum2 } from "@dxos/echo-schema";
1557
+ import { FormatEnum as FormatEnum4, GeoLocation as GeoLocation3, TypeEnum as TypeEnum2 } from "@dxos/echo-schema";
1470
1558
  var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
1471
1559
  const formatScalar = (type2) => {
1472
1560
  switch (type2) {
@@ -1519,6 +1607,16 @@ var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
1519
1607
  return date.toLocaleTimeString(locale);
1520
1608
  }
1521
1609
  }
1610
+ case FormatEnum4.GeoPoint: {
1611
+ if (value === null || value === void 0) {
1612
+ return "";
1613
+ }
1614
+ if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
1615
+ const { latitude, longitude } = GeoLocation3.fromGeoPoint(value);
1616
+ return `${latitude},${longitude}`;
1617
+ }
1618
+ return String(value);
1619
+ }
1522
1620
  default: {
1523
1621
  if (value === null || value === "undefined") {
1524
1622
  return "";
@@ -1567,6 +1665,16 @@ var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1567
1665
  const date = new Date(value);
1568
1666
  return date.toISOString().split("T")[1].split(".")[0];
1569
1667
  }
1668
+ case FormatEnum4.GeoPoint: {
1669
+ if (value === null || value === void 0) {
1670
+ return "";
1671
+ }
1672
+ if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
1673
+ const { latitude, longitude } = GeoLocation3.fromGeoPoint(value);
1674
+ return `${latitude},${longitude}`;
1675
+ }
1676
+ return String(value);
1677
+ }
1570
1678
  default: {
1571
1679
  return String(value);
1572
1680
  }