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