@dxos/react-ui-form 0.8.2-main.12df754 → 0.8.2-main.30e4dbb

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 (84) hide show
  1. package/dist/lib/browser/index.mjs +823 -524
  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 +661 -372
  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 +823 -524
  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/ControlSection/ControlSection.d.ts.map +1 -1
  11. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
  12. package/dist/types/src/components/Form/ArrayField.d.ts.map +1 -1
  13. package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
  14. package/dist/types/src/components/Form/Form.d.ts +6 -4
  15. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  16. package/dist/types/src/components/Form/Form.stories.d.ts +37 -34
  17. package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
  18. package/dist/types/src/components/Form/FormActions.d.ts.map +1 -1
  19. package/dist/types/src/components/Form/FormContent.d.ts +14 -11
  20. package/dist/types/src/components/Form/FormContent.d.ts.map +1 -1
  21. package/dist/types/src/components/Form/FormContext.d.ts +2 -2
  22. package/dist/types/src/components/Form/FormContext.d.ts.map +1 -1
  23. package/dist/types/src/components/Form/Input.d.ts.map +1 -1
  24. package/dist/types/src/components/Form/RefField.d.ts +12 -0
  25. package/dist/types/src/components/Form/RefField.d.ts.map +1 -0
  26. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts.map +1 -1
  27. package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts.map +1 -1
  28. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts.map +1 -1
  29. package/dist/types/src/components/Form/custom/TupleInput.d.ts.map +1 -1
  30. package/dist/types/src/components/Form/factory.d.ts +1 -1
  31. package/dist/types/src/components/Form/factory.d.ts.map +1 -1
  32. package/dist/types/src/components/Form/index.d.ts.map +1 -1
  33. package/dist/types/src/components/ViewEditor/Test.stories.d.ts.map +1 -1
  34. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
  35. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
  36. package/dist/types/src/components/deprecated/Form.d.ts +2 -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.map +1 -1
  39. package/dist/types/src/components/deprecated/FormInput.d.ts.map +1 -1
  40. package/dist/types/src/components/testing.d.ts.map +1 -1
  41. package/dist/types/src/hooks/index.d.ts +2 -0
  42. package/dist/types/src/hooks/index.d.ts.map +1 -1
  43. package/dist/types/src/hooks/useForm.d.ts +2 -2
  44. package/dist/types/src/hooks/useForm.d.ts.map +1 -1
  45. package/dist/types/src/hooks/useQueryRefOptions.d.ts +23 -0
  46. package/dist/types/src/hooks/useQueryRefOptions.d.ts.map +1 -0
  47. package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts +8 -0
  48. package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts.map +1 -0
  49. package/dist/types/src/util/field.d.ts.map +1 -1
  50. package/dist/types/src/util/formatting.d.ts.map +1 -1
  51. package/dist/types/src/util/index.d.ts +2 -0
  52. package/dist/types/src/util/index.d.ts.map +1 -1
  53. package/dist/types/src/util/refs.d.ts +9 -0
  54. package/dist/types/src/util/refs.d.ts.map +1 -0
  55. package/dist/types/src/util/schema.d.ts +3 -0
  56. package/dist/types/src/util/schema.d.ts.map +1 -0
  57. package/dist/types/tsconfig.tsbuildinfo +1 -1
  58. package/package.json +26 -25
  59. package/src/components/ControlSection/ControlSection.stories.tsx +1 -1
  60. package/src/components/FieldEditor/FieldEditor.stories.tsx +1 -1
  61. package/src/components/Form/ArrayField.tsx +8 -7
  62. package/src/components/Form/Defaults.tsx +4 -1
  63. package/src/components/Form/Form.stories.tsx +92 -43
  64. package/src/components/Form/Form.tsx +7 -3
  65. package/src/components/Form/FormContent.tsx +90 -19
  66. package/src/components/Form/FormContext.tsx +13 -3
  67. package/src/components/Form/Input.tsx +3 -9
  68. package/src/components/Form/RefField.tsx +197 -0
  69. package/src/components/Form/custom/GeoPointInput.tsx +2 -2
  70. package/src/components/Form/custom/SelectOptionsInput.stories.tsx +6 -5
  71. package/src/components/Form/custom/SelectOptionsInput.tsx +2 -2
  72. package/src/components/Form/factory.tsx +1 -1
  73. package/src/components/Form/index.ts +0 -1
  74. package/src/components/ViewEditor/ViewEditor.stories.tsx +4 -3
  75. package/src/components/ViewEditor/ViewEditor.tsx +12 -10
  76. package/src/components/deprecated/Form.tsx +6 -6
  77. package/src/hooks/index.ts +3 -1
  78. package/src/hooks/useForm.ts +3 -3
  79. package/src/hooks/useQueryRefOptions.ts +53 -0
  80. package/src/hooks/useRefQueryLookupHandler.ts +41 -0
  81. package/src/util/formatting.ts +15 -3
  82. package/src/util/index.ts +3 -1
  83. package/src/util/refs.ts +38 -0
  84. package/src/util/schema.ts +14 -0
@@ -183,9 +183,9 @@ var ControlFrameItem = ({ title, description, children }) => {
183
183
  };
184
184
 
185
185
  // packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx
186
- import React13, { useCallback as useCallback6, useEffect as useEffect7, useMemo as useMemo7, useState as useState4 } from "react";
187
- import { FormatEnum as FormatEnum2, FormatEnums, formatToType } from "@dxos/echo-schema";
188
- import { log as log2 } from "@dxos/log";
186
+ import React14, { useCallback as useCallback8, useEffect as useEffect8, useMemo as useMemo8, useState as useState5 } from "react";
187
+ import { FormatEnum as FormatEnum5, FormatEnums, formatToType } from "@dxos/echo-schema";
188
+ import { log as log3 } from "@dxos/log";
189
189
  import { useTranslation as useTranslation6 } from "@dxos/react-ui";
190
190
  import { getFormatSchema, getSchemaProperties as getSchemaProperties3, sortProperties } from "@dxos/schema";
191
191
 
@@ -203,15 +203,15 @@ var InputHeader = ({ children, error }) => {
203
203
  return /* @__PURE__ */ React3.createElement("div", {
204
204
  role: "none",
205
205
  className: "flex justify-between items-center mb-1"
206
- }, children, error && /* @__PURE__ */ React3.createElement(Tooltip.Root, null, /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
207
- asChild: true
206
+ }, children, error && /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
207
+ asChild: true,
208
+ content: error,
209
+ side: "bottom"
208
210
  }, /* @__PURE__ */ React3.createElement(Icon, {
209
211
  icon: "ph--warning--regular",
210
212
  size: 4,
211
213
  classNames: errorText
212
- })), /* @__PURE__ */ React3.createElement(Tooltip.Content, {
213
- side: "bottom"
214
- }, /* @__PURE__ */ React3.createElement(Tooltip.Arrow, null), error)));
214
+ })));
215
215
  };
216
216
 
217
217
  // packages/ui/react-ui-form/src/components/Form/custom/GeoPointInput.tsx
@@ -548,23 +548,28 @@ var BooleanInput = ({ type, label, inputOnly, getStatus, getValue: getValue3, on
548
548
  };
549
549
  var SelectInput = ({ type, label, inputOnly, disabled, placeholder, options, getStatus, getValue: getValue3, onValueChange }) => {
550
550
  const { status, error } = getStatus();
551
+ const value = getValue3();
552
+ const handleValueChange = useCallback3((value2) => onValueChange(type, value2), [
553
+ type,
554
+ onValueChange
555
+ ]);
551
556
  return /* @__PURE__ */ React7.createElement(Input6.Root, {
552
557
  validationValence: status
553
558
  }, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
554
559
  error
555
560
  }, /* @__PURE__ */ React7.createElement(Input6.Label, null, label)), /* @__PURE__ */ React7.createElement(Select.Root, {
556
- value: getValue3(),
557
- onValueChange: (value) => onValueChange(type, value)
561
+ value,
562
+ onValueChange: handleValueChange
558
563
  }, /* @__PURE__ */ React7.createElement(Select.TriggerButton, {
559
564
  classNames: "is-full",
560
565
  disabled,
561
566
  placeholder
562
- }), /* @__PURE__ */ React7.createElement(Select.Portal, null, /* @__PURE__ */ React7.createElement(Select.Content, null, /* @__PURE__ */ React7.createElement(Select.Viewport, null, options?.map(({ value, label: label2 }) => (
567
+ }), /* @__PURE__ */ React7.createElement(Select.Portal, null, /* @__PURE__ */ React7.createElement(Select.Content, null, /* @__PURE__ */ React7.createElement(Select.Viewport, null, options?.map(({ value: value2, label: label2 }) => (
563
568
  // NOTE: Numeric values are converted to and from strings.
564
569
  /* @__PURE__ */ React7.createElement(Select.Option, {
565
- key: String(value),
566
- value: String(value)
567
- }, label2 ?? String(value))
570
+ key: String(value2),
571
+ value: String(value2)
572
+ }, label2 ?? String(value2))
568
573
  )))))), inputOnly && /* @__PURE__ */ React7.createElement(Input6.DescriptionAndValidation, null, error));
569
574
  };
570
575
  var MarkdownInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
@@ -608,7 +613,7 @@ var MarkdownInput = ({ type, label, inputOnly, disabled, placeholder, getStatus,
608
613
  };
609
614
 
610
615
  // packages/ui/react-ui-form/src/components/Form/Form.tsx
611
- import React12, { useEffect as useEffect6, useMemo as useMemo6, useRef as useRef3 } from "react";
616
+ import React13, { useEffect as useEffect7, useMemo as useMemo7, useRef as useRef3 } from "react";
612
617
  import { mx as mx8 } from "@dxos/react-ui-theme";
613
618
 
614
619
  // packages/ui/react-ui-form/src/components/Form/FormActions.tsx
@@ -617,13 +622,13 @@ import { IconButton as IconButton2, useTranslation as useTranslation4 } from "@d
617
622
  import { mx as mx5 } from "@dxos/react-ui-theme";
618
623
 
619
624
  // packages/ui/react-ui-form/src/components/Form/FormContext.tsx
620
- import React8, { createContext, useContext, useEffect as useEffect5, useMemo as useMemo3 } from "react";
625
+ import React8, { createContext, useContext, useEffect as useEffect6, useMemo as useMemo3 } from "react";
621
626
  import { raise } from "@dxos/debug";
622
627
  import { getValue as getValue2 } from "@dxos/echo-schema";
623
628
  import { createJsonPath as createJsonPath2 } from "@dxos/effect";
624
629
 
625
630
  // packages/ui/react-ui-form/src/hooks/useForm.ts
626
- import { SchemaAST as AST } from "effect";
631
+ import { SchemaAST } from "effect";
627
632
  import { useCallback as useCallback4, useEffect as useEffect4, useMemo as useMemo2, useState as useState3 } from "react";
628
633
  import { getValue, setValue } from "@dxos/echo-schema";
629
634
  import { createJsonPath, fromEffectValidationPath } from "@dxos/effect";
@@ -632,12 +637,12 @@ import { log } from "@dxos/log";
632
637
  import { validateSchema } from "@dxos/schema";
633
638
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/hooks/useForm.ts";
634
639
  var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, onSave }) => {
635
- invariant(AST.isTypeLiteral(schema.ast), void 0, {
640
+ invariant(SchemaAST.isTypeLiteral(schema.ast), void 0, {
636
641
  F: __dxlog_file,
637
642
  L: 93,
638
643
  S: void 0,
639
644
  A: [
640
- "AST.isTypeLiteral(schema.ast)",
645
+ "SchemaAST.isTypeLiteral(schema.ast)",
641
646
  ""
642
647
  ]
643
648
  });
@@ -831,6 +836,81 @@ var flatMap = (errors) => {
831
836
  }, {});
832
837
  };
833
838
 
839
+ // packages/ui/react-ui-form/src/hooks/useRefQueryLookupHandler.ts
840
+ import { useCallback as useCallback5 } from "react";
841
+ import { getDXN } from "@dxos/echo-schema";
842
+ import { Filter } from "@dxos/react-client/echo";
843
+ import { isNonNullable } from "@dxos/util";
844
+ var useRefQueryLookupHandler = ({ space }) => {
845
+ const handleRefQueryLookup = useCallback5(async (typeInfo) => {
846
+ if (!space) {
847
+ return [];
848
+ }
849
+ const query = space.db.query(Filter.typename(typeInfo.typename));
850
+ const { objects } = await query.run();
851
+ return objects.map((object) => {
852
+ const dxn = getDXN(object);
853
+ if (!dxn) {
854
+ return void 0;
855
+ }
856
+ const item = {
857
+ dxn,
858
+ label: object?.name ?? object?.id ?? ""
859
+ };
860
+ return item;
861
+ }).filter(isNonNullable);
862
+ }, [
863
+ space
864
+ ]);
865
+ return handleRefQueryLookup;
866
+ };
867
+
868
+ // packages/ui/react-ui-form/src/hooks/useQueryRefOptions.ts
869
+ import { useEffect as useEffect5, useState as useState4 } from "react";
870
+ import { log as log2 } from "@dxos/log";
871
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/hooks/useQueryRefOptions.ts";
872
+ var useQueryRefOptions = ({ refTypeInfo, onQueryRefOptions }) => {
873
+ const [options, setOptions] = useState4([]);
874
+ const [loading, setLoading] = useState4(false);
875
+ useEffect5(() => {
876
+ if (!refTypeInfo || !onQueryRefOptions) {
877
+ return;
878
+ }
879
+ const fetchOptions = async () => {
880
+ setLoading(true);
881
+ try {
882
+ const fetchedOptions = await onQueryRefOptions(refTypeInfo);
883
+ setOptions(fetchedOptions.map((option) => {
884
+ const dxn = option.dxn.toString();
885
+ return {
886
+ id: dxn,
887
+ label: option.label ?? dxn,
888
+ hue: "neutral"
889
+ };
890
+ }));
891
+ } catch (error) {
892
+ log2.error("Failed to fetch ref options:", error, {
893
+ F: __dxlog_file2,
894
+ L: 42,
895
+ S: void 0,
896
+ C: (f, a) => f(...a)
897
+ });
898
+ setOptions([]);
899
+ } finally {
900
+ setLoading(false);
901
+ }
902
+ };
903
+ void fetchOptions();
904
+ }, [
905
+ refTypeInfo,
906
+ onQueryRefOptions
907
+ ]);
908
+ return {
909
+ options,
910
+ loading
911
+ };
912
+ };
913
+
834
914
  // packages/ui/react-ui-form/src/components/Form/FormContext.tsx
835
915
  var FormContext = /* @__PURE__ */ createContext(void 0);
836
916
  var useFormContext = () => {
@@ -861,7 +941,7 @@ var useInputProps = (path = []) => {
861
941
  };
862
942
  var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
863
943
  const form = useForm(formOptions);
864
- useEffect5(() => {
944
+ useEffect6(() => {
865
945
  if (!formRef?.current) {
866
946
  return;
867
947
  }
@@ -869,7 +949,7 @@ var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
869
949
  const keyIsEnter = event.key === "Enter";
870
950
  const modifierUsed = event.ctrlKey || event.altKey || event.metaKey || event.shiftKey;
871
951
  const inputIsTextarea = event.target.tagName.toLowerCase() === "textarea";
872
- const inputOptOut = event.target.hasAttribute("data-no-submit");
952
+ const inputOptOut = event.target.hasAttribute("data-no-submit") || event.target.closest("[data-no-submit]") !== null;
873
953
  const shouldSubmitRegularInput = !inputIsTextarea && keyIsEnter && !modifierUsed;
874
954
  const shouldSubmitTextarea = inputIsTextarea && keyIsEnter && event.metaKey;
875
955
  if ((shouldSubmitRegularInput || shouldSubmitTextarea) && !inputOptOut) {
@@ -922,182 +1002,629 @@ var FormActions = ({ onCancel, readonly }) => {
922
1002
  };
923
1003
 
924
1004
  // packages/ui/react-ui-form/src/components/Form/FormContent.tsx
925
- import { pipe as pipe2 } from "effect";
1005
+ import { Schema, SchemaAST as SchemaAST4, pipe as pipe2 } from "effect";
926
1006
  import { capitalize as capitalize2 } from "effect/String";
927
- import React11, { useMemo as useMemo5 } from "react";
928
- import { AST as AST3, S } from "@dxos/echo-schema";
929
- import { createJsonPath as createJsonPath3, findNode as findNode2, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2 } from "@dxos/effect";
1007
+ import React12, { useMemo as useMemo6 } from "react";
1008
+ import { createJsonPath as createJsonPath3, findNode as findNode3, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2 } from "@dxos/effect";
930
1009
  import { mx as mx7 } from "@dxos/react-ui-theme";
931
1010
  import { getSchemaProperties as getSchemaProperties2 } from "@dxos/schema";
932
1011
  import { isNotFalsy } from "@dxos/util";
933
1012
 
934
1013
  // packages/ui/react-ui-form/src/components/Form/ArrayField.tsx
935
- import { pipe } from "effect";
1014
+ import { SchemaAST as SchemaAST3, pipe } from "effect";
936
1015
  import { capitalize } from "effect/String";
937
- import React10, { useCallback as useCallback5, useMemo as useMemo4 } from "react";
938
- import { AST as AST2 } from "@dxos/echo-schema";
939
- import { findNode, getDiscriminatedType, isDiscriminatedUnion, SimpleType } from "@dxos/effect";
1016
+ import React10, { useCallback as useCallback6, useMemo as useMemo4 } from "react";
1017
+ import { findNode as findNode2, getDiscriminatedType, isDiscriminatedUnion, SimpleType } from "@dxos/effect";
940
1018
  import { invariant as invariant2 } from "@dxos/invariant";
941
1019
  import { IconButton as IconButton3, useTranslation as useTranslation5 } from "@dxos/react-ui";
942
1020
  import { mx as mx6 } from "@dxos/react-ui-theme";
943
1021
  import { getSchemaProperties } from "@dxos/schema";
944
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/Form/ArrayField.tsx";
945
- var padding = "px-2";
946
- var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponent }) => {
947
- const { t } = useTranslation5(translationKey);
948
- const { ast, name, type, title } = property;
949
- const values = useFormValues(path ?? []);
950
- invariant2(Array.isArray(values), `Values at path ${path?.join(".")} must be an array.`, {
951
- F: __dxlog_file2,
952
- L: 37,
953
- S: void 0,
954
- A: [
955
- "Array.isArray(values)",
956
- "`Values at path ${path?.join('.')} must be an array.`"
957
- ]
958
- });
959
- const label = title ?? pipe(name, capitalize);
960
- const tupleType = findNode(ast, AST2.isTupleType);
961
- const elementType = tupleType?.rest[0]?.type;
962
- const getDefaultObjectValue = (typeNode) => {
963
- const baseNode = findNode(typeNode, isDiscriminatedUnion);
964
- const typeLiteral = baseNode ? getDiscriminatedType(baseNode, {}) : findNode(typeNode, AST2.isTypeLiteral);
965
- if (!typeLiteral) {
966
- return {};
1022
+
1023
+ // packages/ui/react-ui-form/src/util/field.ts
1024
+ import { FormatEnum, GeoLocation as GeoLocation2, TypeEnum } from "@dxos/echo-schema";
1025
+ var parseValue = ({ type, format, value }) => {
1026
+ if (value === void 0 || value === null || value === "") {
1027
+ return void 0;
1028
+ }
1029
+ const parseScalar = (type2) => {
1030
+ switch (type2) {
1031
+ case TypeEnum.Boolean: {
1032
+ if (typeof value === "string") {
1033
+ const lowercaseValue = value.toLowerCase();
1034
+ if (lowercaseValue === "0" || lowercaseValue === "false") {
1035
+ return false;
1036
+ } else if (lowercaseValue === "1" || lowercaseValue === "true") {
1037
+ return true;
1038
+ }
1039
+ }
1040
+ return Boolean(value);
1041
+ }
1042
+ case TypeEnum.Number: {
1043
+ const cleaned = typeof value === "string" ? value.replace(/[^0-9.-]+/g, "") : value;
1044
+ const num = Number(cleaned);
1045
+ return Number.isNaN(num) ? null : num;
1046
+ }
1047
+ case TypeEnum.String:
1048
+ case TypeEnum.Ref:
1049
+ return String(value);
1050
+ default: {
1051
+ return value;
1052
+ }
967
1053
  }
968
- return Object.fromEntries(getSchemaProperties(typeLiteral, {}).map((prop) => [
969
- prop.name,
970
- prop.defaultValue
971
- ]));
972
1054
  };
973
- const newValue = useMemo4(() => {
974
- if (type === "object" && elementType) {
975
- return getDefaultObjectValue(elementType);
976
- } else {
977
- return SimpleType.getDefaultValue(type);
1055
+ if (!format) {
1056
+ return parseScalar(type);
1057
+ }
1058
+ switch (format) {
1059
+ case FormatEnum.Boolean:
1060
+ return parseScalar(TypeEnum.Boolean);
1061
+ case FormatEnum.Number:
1062
+ case FormatEnum.Percent:
1063
+ case FormatEnum.Currency:
1064
+ return parseScalar(TypeEnum.Number);
1065
+ case FormatEnum.String:
1066
+ case FormatEnum.Markdown: {
1067
+ return parseScalar(TypeEnum.String);
1068
+ }
1069
+ case FormatEnum.Ref:
1070
+ throw new Error(`unexpected format: ${FormatEnum.Ref}`);
1071
+ case FormatEnum.DateTime:
1072
+ case FormatEnum.Date:
1073
+ case FormatEnum.Time:
1074
+ case FormatEnum.Timestamp: {
1075
+ const date = new Date(value);
1076
+ return isNaN(date.getTime()) ? null : date;
1077
+ }
1078
+ case FormatEnum.GeoPoint: {
1079
+ if (typeof value === "string") {
1080
+ const cleaned = value.replace(/[^0-9.,-]+/g, "");
1081
+ const parts = cleaned.split(",");
1082
+ if (parts.length === 2) {
1083
+ const lat = parseFloat(parts[0]);
1084
+ const long = parseFloat(parts[1]);
1085
+ if (!isNaN(lat) && !isNaN(long)) {
1086
+ return GeoLocation2.toGeoPoint({
1087
+ latitude: lat,
1088
+ longitude: long
1089
+ });
1090
+ }
1091
+ }
1092
+ }
1093
+ return [
1094
+ 0,
1095
+ 0
1096
+ ];
1097
+ }
1098
+ default: {
1099
+ return value;
978
1100
  }
979
- }, [
980
- type,
981
- elementType
982
- ]);
983
- const handleAdd = useCallback5(() => {
984
- inputProps.onValueChange(type, [
985
- ...values,
986
- newValue
987
- ]);
988
- }, [
989
- type,
990
- elementType,
991
- inputProps,
992
- newValue,
993
- values
994
- ]);
995
- const handleRemove = useCallback5((index) => {
996
- const newValues = values.filter((_, i) => i !== index);
997
- inputProps.onValueChange(type, newValues);
998
- }, [
999
- type,
1000
- inputProps,
1001
- values
1002
- ]);
1003
- if (!elementType) {
1004
- return null;
1005
1101
  }
1006
- return /* @__PURE__ */ React10.createElement("div", {
1007
- role: "none",
1008
- className: mx6(padding)
1009
- }, /* @__PURE__ */ React10.createElement(InputHeader, null, label), /* @__PURE__ */ React10.createElement("div", {
1010
- role: "none",
1011
- className: "flex flex-col gap-1"
1012
- }, values.map((_value, index) => /* @__PURE__ */ React10.createElement("div", {
1013
- key: index,
1014
- role: "none",
1015
- className: "flex items-center gap-1"
1016
- }, /* @__PURE__ */ React10.createElement("div", {
1017
- role: "none",
1018
- className: "flex-1"
1019
- }, /* @__PURE__ */ React10.createElement(FormField, {
1020
- property: {
1021
- ...property,
1022
- array: false,
1023
- ast: elementType
1024
- },
1025
- path: [
1026
- ...path ?? [],
1027
- index
1028
- ],
1029
- readonly,
1030
- inline: true,
1031
- Custom,
1032
- lookupComponent
1033
- })), /* @__PURE__ */ React10.createElement(IconButton3, {
1034
- icon: "ph--trash--regular",
1035
- iconOnly: true,
1036
- label: t("button remove"),
1037
- onClick: () => handleRemove(index)
1038
- })))), /* @__PURE__ */ React10.createElement("div", {
1039
- role: "none",
1040
- className: "flex justify-between items-center plb-1"
1041
- }, /* @__PURE__ */ React10.createElement(IconButton3, {
1042
- icon: "ph--plus--regular",
1043
- iconOnly: true,
1044
- label: t("button add"),
1045
- onClick: handleAdd
1046
- })));
1047
1102
  };
1048
-
1049
- // packages/ui/react-ui-form/src/components/Form/factory.tsx
1050
- import { FormatEnum } from "@dxos/echo-schema";
1051
- var getInputComponent = (type, format) => {
1103
+ var cellClassesForFieldType = ({ type, format }) => {
1104
+ if (!format) {
1105
+ switch (type) {
1106
+ case TypeEnum.Number:
1107
+ return [
1108
+ "text-right",
1109
+ "font-mono"
1110
+ ];
1111
+ case TypeEnum.Boolean:
1112
+ return [
1113
+ "text-right",
1114
+ "font-mono"
1115
+ ];
1116
+ case TypeEnum.String:
1117
+ return void 0;
1118
+ case TypeEnum.Ref:
1119
+ return void 0;
1120
+ default: {
1121
+ return void 0;
1122
+ }
1123
+ }
1124
+ }
1052
1125
  switch (format) {
1053
- case FormatEnum.GeoPoint:
1054
- return GeoPointInput;
1055
1126
  case FormatEnum.Markdown:
1056
- return MarkdownInput;
1057
- }
1058
- switch (type) {
1059
- case "string":
1060
- return TextInput;
1061
- case "number":
1062
- return NumberInput;
1063
- case "boolean":
1064
- return BooleanInput;
1127
+ return void 0;
1128
+ case FormatEnum.Time:
1129
+ case FormatEnum.Timestamp:
1130
+ case FormatEnum.DateTime:
1131
+ case FormatEnum.Date:
1132
+ case FormatEnum.Duration:
1133
+ return [
1134
+ "font-mono",
1135
+ "text-right"
1136
+ ];
1137
+ case FormatEnum.Currency:
1138
+ return [
1139
+ "text-right"
1140
+ ];
1141
+ case FormatEnum.JSON:
1142
+ case FormatEnum.DID:
1143
+ return [
1144
+ "font-mono"
1145
+ ];
1146
+ default:
1147
+ return void 0;
1065
1148
  }
1066
1149
  };
1150
+ var pathNotUniqueError = (path) => ({
1151
+ path: "path",
1152
+ message: `'${path}' is already present`
1153
+ });
1067
1154
 
1068
- // packages/ui/react-ui-form/src/components/Form/FormContent.tsx
1069
- var FormField = ({ property, path, readonly, inline, lookupComponent, Custom }) => {
1070
- const inputProps = useInputProps(path);
1071
- const { ast, name, type, format, title, description, options, examples, array } = property;
1072
- const label = useMemo5(() => title ?? pipe2(name, capitalize2), [
1073
- title,
1074
- name
1075
- ]);
1076
- const placeholder = useMemo5(() => examples?.length ? `Example: "${examples[0]}"` : description, [
1077
- examples,
1078
- description
1079
- ]);
1080
- const FoundComponent = lookupComponent?.({
1081
- prop: name,
1082
- schema: S.make(ast),
1083
- inputProps: {
1084
- type,
1085
- format,
1086
- label,
1087
- disabled: readonly,
1088
- placeholder,
1089
- ...inputProps
1090
- }
1091
- });
1155
+ // packages/ui/react-ui-form/src/util/formatting.ts
1156
+ import { format as formatDate } from "date-fns/format";
1157
+ import { FormatEnum as FormatEnum2, GeoLocation as GeoLocation3, TypeEnum as TypeEnum2 } from "@dxos/echo-schema";
1158
+ var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
1159
+ const formatScalar = (type2) => {
1160
+ switch (type2) {
1161
+ case TypeEnum2.Boolean:
1162
+ return value.toLocaleString().toUpperCase();
1163
+ case TypeEnum2.Number:
1164
+ return value.toLocaleString(locale);
1165
+ case TypeEnum2.String:
1166
+ case TypeEnum2.Ref:
1167
+ return String(value);
1168
+ default: {
1169
+ return String(value);
1170
+ }
1171
+ }
1172
+ };
1173
+ if (!format) {
1174
+ return formatScalar(type);
1175
+ }
1176
+ switch (format) {
1177
+ case FormatEnum2.Boolean: {
1178
+ return formatScalar(TypeEnum2.Boolean);
1179
+ }
1180
+ case FormatEnum2.Number: {
1181
+ return formatScalar(TypeEnum2.Number);
1182
+ }
1183
+ case FormatEnum2.String:
1184
+ case FormatEnum2.Ref: {
1185
+ return formatScalar(TypeEnum2.String);
1186
+ }
1187
+ case FormatEnum2.Percent: {
1188
+ return `${value * 100}%`;
1189
+ }
1190
+ case FormatEnum2.Currency: {
1191
+ return value.toLocaleString(locale, {
1192
+ style: "currency",
1193
+ currency: "USD",
1194
+ minimumFractionDigits: 2,
1195
+ maximumFractionDigits: 2
1196
+ });
1197
+ }
1198
+ case FormatEnum2.Date: {
1199
+ try {
1200
+ return formatDate(new Date(value), "yyyy-MM-dd");
1201
+ } catch (error) {
1202
+ return "Invalid Date";
1203
+ }
1204
+ }
1205
+ case FormatEnum2.Time: {
1206
+ try {
1207
+ return formatDate(new Date(value), "HH:mm:ss");
1208
+ } catch (error) {
1209
+ return "Invalid Time";
1210
+ }
1211
+ }
1212
+ case FormatEnum2.DateTime: {
1213
+ try {
1214
+ return formatDate(new Date(value), "yyyy-MM-dd HH:mm:ss");
1215
+ } catch (error) {
1216
+ return "Invalid DateTime";
1217
+ }
1218
+ }
1219
+ case FormatEnum2.GeoPoint: {
1220
+ if (value === null || value === void 0) {
1221
+ return "";
1222
+ }
1223
+ if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
1224
+ const { latitude, longitude } = GeoLocation3.fromGeoPoint(value);
1225
+ return `${latitude},${longitude}`;
1226
+ }
1227
+ return String(value);
1228
+ }
1229
+ default: {
1230
+ if (value === null || value === "undefined") {
1231
+ return "";
1232
+ }
1233
+ return String(value);
1234
+ }
1235
+ }
1236
+ };
1237
+ var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1238
+ const formatScalar = (type2) => {
1239
+ switch (type2) {
1240
+ case TypeEnum2.Boolean:
1241
+ case TypeEnum2.Number:
1242
+ case TypeEnum2.String:
1243
+ case TypeEnum2.Ref:
1244
+ return String(value);
1245
+ default:
1246
+ return String(value);
1247
+ }
1248
+ };
1249
+ if (!format) {
1250
+ return formatScalar(type);
1251
+ }
1252
+ switch (format) {
1253
+ case FormatEnum2.Boolean:
1254
+ case FormatEnum2.Number:
1255
+ case FormatEnum2.String:
1256
+ case FormatEnum2.Ref: {
1257
+ return formatScalar(type);
1258
+ }
1259
+ case FormatEnum2.Percent: {
1260
+ return String(value * 100);
1261
+ }
1262
+ case FormatEnum2.Currency: {
1263
+ return String(value);
1264
+ }
1265
+ case FormatEnum2.DateTime: {
1266
+ const date = new Date(value);
1267
+ return date.toISOString();
1268
+ }
1269
+ case FormatEnum2.Date: {
1270
+ const date = new Date(value);
1271
+ return date.toISOString().split("T")[0];
1272
+ }
1273
+ case FormatEnum2.Time: {
1274
+ const date = new Date(value);
1275
+ return date.toISOString().split("T")[1].split(".")[0];
1276
+ }
1277
+ case FormatEnum2.GeoPoint: {
1278
+ if (value === null || value === void 0) {
1279
+ return "";
1280
+ }
1281
+ if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
1282
+ const { latitude, longitude } = GeoLocation3.fromGeoPoint(value);
1283
+ return `${latitude},${longitude}`;
1284
+ }
1285
+ return String(value);
1286
+ }
1287
+ default: {
1288
+ return String(value);
1289
+ }
1290
+ }
1291
+ };
1292
+
1293
+ // packages/ui/react-ui-form/src/util/refs.ts
1294
+ import { FormatEnum as FormatEnum3, ReferenceAnnotationId } from "@dxos/echo-schema";
1295
+ import { findAnnotation } from "@dxos/effect";
1296
+
1297
+ // packages/ui/react-ui-form/src/util/schema.ts
1298
+ import { SchemaAST as SchemaAST2 } from "effect";
1299
+ import { findNode } from "@dxos/effect";
1300
+ var findArrayElementType = (ast) => {
1301
+ const tupleType = findNode(ast, SchemaAST2.isTupleType);
1302
+ const elementType = tupleType?.rest[0]?.type;
1303
+ return elementType;
1304
+ };
1305
+
1306
+ // packages/ui/react-ui-form/src/util/refs.ts
1307
+ var getRefProps = (property) => {
1308
+ const { ast, format, array } = property;
1309
+ if (format === FormatEnum3.Ref) {
1310
+ return {
1311
+ ast,
1312
+ isArray: false
1313
+ };
1314
+ }
1315
+ if (array) {
1316
+ const elementType = findArrayElementType(ast);
1317
+ if (elementType) {
1318
+ const annotation = findAnnotation(elementType, ReferenceAnnotationId);
1319
+ if (annotation) {
1320
+ return {
1321
+ ast: elementType,
1322
+ isArray: true
1323
+ };
1324
+ }
1325
+ }
1326
+ }
1327
+ return void 0;
1328
+ };
1329
+
1330
+ // packages/ui/react-ui-form/src/components/Form/ArrayField.tsx
1331
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/Form/ArrayField.tsx";
1332
+ var padding = "px-2";
1333
+ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponent }) => {
1334
+ const { t } = useTranslation5(translationKey);
1335
+ const { ast, name, type, title } = property;
1336
+ const values = useFormValues(path ?? []) ?? [];
1337
+ invariant2(Array.isArray(values), `Values at path ${path?.join(".")} must be an array.`, {
1338
+ F: __dxlog_file3,
1339
+ L: 39,
1340
+ S: void 0,
1341
+ A: [
1342
+ "Array.isArray(values)",
1343
+ "`Values at path ${path?.join('.')} must be an array.`"
1344
+ ]
1345
+ });
1346
+ const label = title ?? pipe(name, capitalize);
1347
+ const elementType = findArrayElementType(ast);
1348
+ const getDefaultObjectValue = (typeNode) => {
1349
+ const baseNode = findNode2(typeNode, isDiscriminatedUnion);
1350
+ const typeLiteral = baseNode ? getDiscriminatedType(baseNode, {}) : findNode2(typeNode, SchemaAST3.isTypeLiteral);
1351
+ if (!typeLiteral) {
1352
+ return {};
1353
+ }
1354
+ return Object.fromEntries(getSchemaProperties(typeLiteral, {}).map((prop) => [
1355
+ prop.name,
1356
+ prop.defaultValue
1357
+ ]));
1358
+ };
1359
+ const newValue = useMemo4(() => {
1360
+ if (type === "object" && elementType) {
1361
+ return getDefaultObjectValue(elementType);
1362
+ } else {
1363
+ return SimpleType.getDefaultValue(type);
1364
+ }
1365
+ }, [
1366
+ type,
1367
+ elementType
1368
+ ]);
1369
+ const handleAdd = useCallback6(() => {
1370
+ inputProps.onValueChange(type, [
1371
+ ...values,
1372
+ newValue
1373
+ ]);
1374
+ }, [
1375
+ type,
1376
+ elementType,
1377
+ inputProps,
1378
+ newValue,
1379
+ values
1380
+ ]);
1381
+ const handleRemove = useCallback6((index) => {
1382
+ const newValues = values.filter((_, i) => i !== index);
1383
+ inputProps.onValueChange(type, newValues);
1384
+ }, [
1385
+ type,
1386
+ inputProps,
1387
+ values
1388
+ ]);
1389
+ if (!elementType) {
1390
+ return null;
1391
+ }
1392
+ return /* @__PURE__ */ React10.createElement("div", {
1393
+ role: "none",
1394
+ className: mx6(padding)
1395
+ }, /* @__PURE__ */ React10.createElement(InputHeader, null, label), /* @__PURE__ */ React10.createElement("div", {
1396
+ role: "none",
1397
+ className: "flex flex-col gap-1"
1398
+ }, values.map((_value, index) => /* @__PURE__ */ React10.createElement("div", {
1399
+ key: index,
1400
+ role: "none",
1401
+ className: "flex items-center gap-1"
1402
+ }, /* @__PURE__ */ React10.createElement("div", {
1403
+ role: "none",
1404
+ className: "flex-1"
1405
+ }, /* @__PURE__ */ React10.createElement(FormField, {
1406
+ property: {
1407
+ ...property,
1408
+ array: false,
1409
+ ast: elementType
1410
+ },
1411
+ path: [
1412
+ ...path ?? [],
1413
+ index
1414
+ ],
1415
+ readonly,
1416
+ inline: true,
1417
+ Custom,
1418
+ lookupComponent
1419
+ })), /* @__PURE__ */ React10.createElement(IconButton3, {
1420
+ icon: "ph--trash--regular",
1421
+ iconOnly: true,
1422
+ label: t("button remove"),
1423
+ onClick: () => handleRemove(index)
1424
+ })))), /* @__PURE__ */ React10.createElement("div", {
1425
+ role: "none",
1426
+ className: "flex justify-between items-center plb-1"
1427
+ }, /* @__PURE__ */ React10.createElement(IconButton3, {
1428
+ icon: "ph--plus--regular",
1429
+ iconOnly: true,
1430
+ label: t("button add"),
1431
+ onClick: handleAdd
1432
+ })));
1433
+ };
1434
+
1435
+ // packages/ui/react-ui-form/src/components/Form/RefField.tsx
1436
+ import React11, { useCallback as useCallback7, useMemo as useMemo5 } from "react";
1437
+ import { Expando, getTypeAnnotation, Ref, ReferenceAnnotationId as ReferenceAnnotationId2 } from "@dxos/echo-schema";
1438
+ import { findAnnotation as findAnnotation2 } from "@dxos/effect";
1439
+ import { DXN } from "@dxos/keys";
1440
+ import { Input as Input7 } from "@dxos/react-ui";
1441
+ import { TagPicker } from "@dxos/react-ui-tag-picker";
1442
+ import { isNonNullable as isNonNullable2 } from "@dxos/util";
1443
+ var RefField = ({ type, label, disabled, placeholder, inputOnly, array, ast, getValue: getValue3, onBlur, onQueryRefOptions, onValueChange, ...restInputProps }) => {
1444
+ const refTypeInfo = useMemo5(() => ast ? findAnnotation2(ast, ReferenceAnnotationId2) : void 0, [
1445
+ ast
1446
+ ]);
1447
+ const { options: availableOptions, loading: _loading } = useQueryRefOptions({
1448
+ refTypeInfo,
1449
+ onQueryRefOptions
1450
+ });
1451
+ if (refTypeInfo && refTypeInfo?.typename === getTypeAnnotation(Expando)?.typename || !onQueryRefOptions) {
1452
+ return /* @__PURE__ */ React11.createElement(RefFieldFallback, {
1453
+ type,
1454
+ label,
1455
+ placeholder,
1456
+ disabled,
1457
+ inputOnly,
1458
+ getValue: getValue3,
1459
+ onBlur,
1460
+ onValueChange,
1461
+ ...restInputProps
1462
+ });
1463
+ }
1464
+ const handleGetValue = useCallback7(() => {
1465
+ const formValue = getValue3();
1466
+ const unknownToRefOption = (val) => {
1467
+ if (Ref.isRef(val)) {
1468
+ const dxnString = val.dxn.toString();
1469
+ const matchingOption = availableOptions.find((option2) => option2.id === dxnString);
1470
+ if (matchingOption) {
1471
+ return matchingOption;
1472
+ }
1473
+ }
1474
+ return void 0;
1475
+ };
1476
+ if (array && Array.isArray(formValue)) {
1477
+ return formValue.map(unknownToRefOption).filter(isNonNullable2) ?? [];
1478
+ }
1479
+ const option = unknownToRefOption(formValue);
1480
+ if (option) {
1481
+ return [
1482
+ option
1483
+ ];
1484
+ }
1485
+ return [];
1486
+ }, [
1487
+ getValue3,
1488
+ availableOptions,
1489
+ array
1490
+ ]);
1491
+ const handleSearch = useCallback7((text, ids) => availableOptions.filter((option) => !ids.includes(option.id)).filter((option) => option.label.toLowerCase().includes(text.toLowerCase())).map((option) => ({
1492
+ id: option.id,
1493
+ label: option.label,
1494
+ hue: option.hue
1495
+ })), [
1496
+ availableOptions
1497
+ ]);
1498
+ const handleUpdate = useCallback7((ids) => {
1499
+ if (ids.length === 0) {
1500
+ onValueChange("object", void 0);
1501
+ return;
1502
+ }
1503
+ const refs = ids.map((id) => {
1504
+ const item = availableOptions.find((option) => option.id === id);
1505
+ if (item) {
1506
+ const dxn = DXN.parse(item.id);
1507
+ return Ref.fromDXN(dxn);
1508
+ }
1509
+ return null;
1510
+ }).filter(isNonNullable2);
1511
+ if (array) {
1512
+ onValueChange("object", refs);
1513
+ } else {
1514
+ onValueChange("object", refs[0]);
1515
+ }
1516
+ }, [
1517
+ availableOptions,
1518
+ array,
1519
+ onValueChange
1520
+ ]);
1521
+ const tagPickerMode = useMemo5(() => array ? "multi-select" : "single-select", [
1522
+ array
1523
+ ]);
1524
+ if (!refTypeInfo) {
1525
+ return null;
1526
+ }
1527
+ const { status, error } = restInputProps.getStatus();
1528
+ return /* @__PURE__ */ React11.createElement(Input7.Root, {
1529
+ validationValence: status
1530
+ }, !inputOnly && /* @__PURE__ */ React11.createElement(InputHeader, {
1531
+ error
1532
+ }, /* @__PURE__ */ React11.createElement(Input7.Label, null, label)), /* @__PURE__ */ React11.createElement("div", {
1533
+ "data-no-submit": true
1534
+ }, /* @__PURE__ */ React11.createElement(TagPicker, {
1535
+ items: handleGetValue(),
1536
+ mode: tagPickerMode,
1537
+ onBlur: (event) => onBlur(event),
1538
+ onUpdate: handleUpdate,
1539
+ onSearch: handleSearch,
1540
+ classNames: "rounded-sm bg-input p-1.5"
1541
+ })), inputOnly && /* @__PURE__ */ React11.createElement(Input7.DescriptionAndValidation, null, error));
1542
+ };
1543
+ var RefFieldFallback = ({ type, label, disabled, placeholder, inputOnly, getValue: getValue3, onValueChange, ...restInputProps }) => {
1544
+ const handleOnValueChange = (_type, dxnString) => {
1545
+ const dxn = DXN.tryParse(dxnString);
1546
+ if (dxn) {
1547
+ onValueChange?.("object", Ref.fromDXN(dxn));
1548
+ } else if (dxnString === "") {
1549
+ onValueChange?.("object", void 0);
1550
+ } else {
1551
+ onValueChange?.("string", dxnString);
1552
+ }
1553
+ };
1554
+ const handleGetValue = () => {
1555
+ const formValue = getValue3();
1556
+ if (typeof formValue === "string") {
1557
+ return formValue;
1558
+ }
1559
+ if (Ref.isRef(formValue)) {
1560
+ return formValue.dxn.toString();
1561
+ }
1562
+ return void 0;
1563
+ };
1564
+ return /* @__PURE__ */ React11.createElement(TextInput, {
1565
+ type,
1566
+ label,
1567
+ disabled,
1568
+ placeholder,
1569
+ inputOnly,
1570
+ getValue: handleGetValue,
1571
+ onValueChange: handleOnValueChange,
1572
+ ...restInputProps
1573
+ });
1574
+ };
1575
+
1576
+ // packages/ui/react-ui-form/src/components/Form/factory.tsx
1577
+ import { FormatEnum as FormatEnum4 } from "@dxos/echo-schema";
1578
+ var getInputComponent = (type, format) => {
1579
+ switch (format) {
1580
+ case FormatEnum4.GeoPoint:
1581
+ return GeoPointInput;
1582
+ case FormatEnum4.Markdown:
1583
+ return MarkdownInput;
1584
+ }
1585
+ switch (type) {
1586
+ case "string":
1587
+ return TextInput;
1588
+ case "number":
1589
+ return NumberInput;
1590
+ case "boolean":
1591
+ return BooleanInput;
1592
+ }
1593
+ };
1594
+
1595
+ // packages/ui/react-ui-form/src/components/Form/FormContent.tsx
1596
+ var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupComponent, Custom }) => {
1597
+ const inputProps = useInputProps(path);
1598
+ const { ast, name, type, format, title, description, options, examples, array } = property;
1599
+ const label = useMemo6(() => title ?? pipe2(name, capitalize2), [
1600
+ title,
1601
+ name
1602
+ ]);
1603
+ const placeholder = useMemo6(() => examples?.length ? `Example: "${examples[0]}"` : description, [
1604
+ examples,
1605
+ description
1606
+ ]);
1607
+ const FoundComponent = lookupComponent?.({
1608
+ prop: name,
1609
+ schema: Schema.make(ast),
1610
+ inputProps: {
1611
+ type,
1612
+ format,
1613
+ label,
1614
+ disabled: readonly,
1615
+ placeholder,
1616
+ ...inputProps
1617
+ }
1618
+ });
1092
1619
  if (FoundComponent) {
1093
- return /* @__PURE__ */ React11.createElement("div", {
1620
+ return /* @__PURE__ */ React12.createElement("div", {
1094
1621
  role: "none"
1095
1622
  }, FoundComponent);
1096
1623
  }
1097
1624
  const jsonPath = createJsonPath3(path ?? []);
1098
1625
  const CustomComponent = Custom?.[jsonPath];
1099
1626
  if (CustomComponent) {
1100
- return /* @__PURE__ */ React11.createElement(CustomComponent, {
1627
+ return /* @__PURE__ */ React12.createElement(CustomComponent, {
1101
1628
  type,
1102
1629
  format,
1103
1630
  label,
@@ -1107,8 +1634,23 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
1107
1634
  ...inputProps
1108
1635
  });
1109
1636
  }
1637
+ const refProps = getRefProps(property);
1638
+ if (refProps) {
1639
+ return /* @__PURE__ */ React12.createElement(RefField, {
1640
+ ast: refProps.ast,
1641
+ array: refProps.isArray,
1642
+ type,
1643
+ format,
1644
+ label,
1645
+ placeholder,
1646
+ disabled: readonly,
1647
+ inputOnly: inline,
1648
+ onQueryRefOptions,
1649
+ ...inputProps
1650
+ });
1651
+ }
1110
1652
  if (array) {
1111
- return /* @__PURE__ */ React11.createElement(ArrayField, {
1653
+ return /* @__PURE__ */ React12.createElement(ArrayField, {
1112
1654
  property,
1113
1655
  path,
1114
1656
  inputProps,
@@ -1118,9 +1660,9 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
1118
1660
  }
1119
1661
  const InputComponent = getInputComponent(type, format);
1120
1662
  if (InputComponent) {
1121
- return /* @__PURE__ */ React11.createElement("div", {
1663
+ return /* @__PURE__ */ React12.createElement("div", {
1122
1664
  role: "none"
1123
- }, /* @__PURE__ */ React11.createElement(InputComponent, {
1665
+ }, /* @__PURE__ */ React12.createElement(InputComponent, {
1124
1666
  type,
1125
1667
  format,
1126
1668
  label,
@@ -1131,9 +1673,9 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
1131
1673
  }));
1132
1674
  }
1133
1675
  if (options) {
1134
- return /* @__PURE__ */ React11.createElement("div", {
1676
+ return /* @__PURE__ */ React12.createElement("div", {
1135
1677
  role: "none"
1136
- }, /* @__PURE__ */ React11.createElement(SelectInput, {
1678
+ }, /* @__PURE__ */ React12.createElement(SelectInput, {
1137
1679
  type,
1138
1680
  format,
1139
1681
  disabled: readonly,
@@ -1148,24 +1690,28 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
1148
1690
  }));
1149
1691
  }
1150
1692
  if (type === "object") {
1151
- const baseNode = findNode2(ast, isDiscriminatedUnion2);
1152
- const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, inputProps.getValue()) : findNode2(ast, AST3.isTypeLiteral);
1693
+ const baseNode = findNode3(ast, isDiscriminatedUnion2);
1694
+ const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, inputProps.getValue()) : findNode3(ast, SchemaAST4.isTypeLiteral);
1153
1695
  if (typeLiteral) {
1154
- return /* @__PURE__ */ React11.createElement("div", {
1696
+ return /* @__PURE__ */ React12.createElement("div", {
1155
1697
  role: "none"
1156
- }, !inline && /* @__PURE__ */ React11.createElement("div", null, label), /* @__PURE__ */ React11.createElement(FormFields, {
1157
- schema: S.make(typeLiteral),
1698
+ }, !inline && /* @__PURE__ */ React12.createElement("h3", {
1699
+ className: "text-lg mbs-2 mbe-1"
1700
+ }, label), /* @__PURE__ */ React12.createElement(FormFields, {
1701
+ schema: Schema.make(typeLiteral),
1158
1702
  path,
1159
1703
  readonly,
1160
- Custom
1704
+ onQueryRefOptions,
1705
+ Custom,
1706
+ lookupComponent
1161
1707
  }));
1162
1708
  }
1163
1709
  }
1164
1710
  return null;
1165
1711
  };
1166
- var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custom }) => {
1712
+ var FormFields = ({ schema, path, filter, sort, readonly, onQueryRefOptions, lookupComponent, Custom }) => {
1167
1713
  const values = useFormValues(path);
1168
- const properties = useMemo5(() => {
1714
+ const properties = useMemo6(() => {
1169
1715
  const props = getSchemaProperties2(schema.ast, values);
1170
1716
  const filtered = filter ? filter(props) : props;
1171
1717
  return sort ? filtered.sort((a, b) => sort.indexOf(a.name) - sort.indexOf(b.name)) : filtered;
@@ -1175,11 +1721,11 @@ var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custo
1175
1721
  filter,
1176
1722
  sort
1177
1723
  ]);
1178
- return /* @__PURE__ */ React11.createElement("div", {
1724
+ return /* @__PURE__ */ React12.createElement("div", {
1179
1725
  role: "form",
1180
1726
  className: mx7("flex flex-col w-full gap-2")
1181
1727
  }, properties.map((property) => {
1182
- return /* @__PURE__ */ React11.createElement(FormField, {
1728
+ return /* @__PURE__ */ React12.createElement(FormField, {
1183
1729
  key: property.name,
1184
1730
  property,
1185
1731
  path: [
@@ -1187,6 +1733,7 @@ var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custo
1187
1733
  property.name
1188
1734
  ],
1189
1735
  readonly,
1736
+ onQueryRefOptions,
1190
1737
  lookupComponent,
1191
1738
  Custom
1192
1739
  });
@@ -1194,13 +1741,13 @@ var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custo
1194
1741
  };
1195
1742
 
1196
1743
  // packages/ui/react-ui-form/src/components/Form/Form.tsx
1197
- var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, lookupComponent, Custom }) => {
1744
+ var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, onQueryRefOptions, lookupComponent, Custom }) => {
1198
1745
  const formRef = useRef3(null);
1199
- const onValid = useMemo6(() => autoSave ? onSave : void 0, [
1746
+ const onValid = useMemo7(() => autoSave ? onSave : void 0, [
1200
1747
  autoSave,
1201
1748
  onSave
1202
1749
  ]);
1203
- useEffect6(() => {
1750
+ useEffect7(() => {
1204
1751
  if (autoFocus && formRef.current) {
1205
1752
  const input = formRef.current.querySelector("input");
1206
1753
  if (input) {
@@ -1210,7 +1757,7 @@ var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, r
1210
1757
  }, [
1211
1758
  autoFocus
1212
1759
  ]);
1213
- return /* @__PURE__ */ React12.createElement(FormProvider, {
1760
+ return /* @__PURE__ */ React13.createElement(FormProvider, {
1214
1761
  formRef,
1215
1762
  schema,
1216
1763
  autoSave,
@@ -1219,36 +1766,37 @@ var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, r
1219
1766
  onValidate,
1220
1767
  onValid,
1221
1768
  onSave
1222
- }, /* @__PURE__ */ React12.createElement("div", {
1769
+ }, /* @__PURE__ */ React13.createElement("div", {
1223
1770
  ref: formRef,
1224
1771
  role: "none",
1225
1772
  className: mx8("p-2", classNames),
1226
1773
  "data-testid": testId
1227
- }, /* @__PURE__ */ React12.createElement(FormFields, {
1774
+ }, /* @__PURE__ */ React13.createElement(FormFields, {
1228
1775
  schema,
1229
1776
  path,
1230
1777
  readonly,
1231
1778
  filter,
1232
1779
  sort,
1780
+ onQueryRefOptions,
1233
1781
  lookupComponent,
1234
1782
  Custom
1235
- }), (onCancel || onSave) && !autoSave && /* @__PURE__ */ React12.createElement(FormActions, {
1783
+ }), (onCancel || onSave) && !autoSave && /* @__PURE__ */ React13.createElement(FormActions, {
1236
1784
  onCancel,
1237
1785
  readonly
1238
1786
  })));
1239
1787
  };
1240
1788
 
1241
1789
  // packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx
1242
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
1790
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
1243
1791
  var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1244
1792
  const { t } = useTranslation6(translationKey);
1245
- const [props, setProps] = useState4(projection.getFieldProjection(field.id).props);
1246
- useEffect7(() => setProps(projection.getFieldProjection(field.id).props), [
1793
+ const [props, setProps] = useState5(projection.getFieldProjection(field.id).props);
1794
+ useEffect8(() => setProps(projection.getFieldProjection(field.id).props), [
1247
1795
  field,
1248
1796
  projection
1249
1797
  ]);
1250
- const [schemas, setSchemas] = useState4([]);
1251
- useEffect7(() => {
1798
+ const [schemas, setSchemas] = useState5([]);
1799
+ useEffect8(() => {
1252
1800
  if (!registry) {
1253
1801
  return;
1254
1802
  }
@@ -1266,17 +1814,17 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1266
1814
  }, [
1267
1815
  registry
1268
1816
  ]);
1269
- const [referenceSchema, setReferenceSchema] = useState4();
1270
- useEffect7(() => {
1817
+ const [referenceSchema, setReferenceSchema] = useState5();
1818
+ useEffect8(() => {
1271
1819
  setReferenceSchema(schemas.find((schema) => schema.typename === props?.referenceSchema));
1272
1820
  }, [
1273
1821
  schemas,
1274
1822
  props?.referenceSchema
1275
1823
  ]);
1276
- const [{ fieldSchema }, setFieldSchema] = useState4({
1824
+ const [{ fieldSchema }, setFieldSchema] = useState5({
1277
1825
  fieldSchema: getFormatSchema(props?.format)
1278
1826
  });
1279
- const handleValuesChanged = useCallback6((_props) => {
1827
+ const handleValuesChanged = useCallback8((_props) => {
1280
1828
  setFieldSchema((prev) => {
1281
1829
  const fieldSchema2 = getFormatSchema(_props.format);
1282
1830
  if (prev.fieldSchema === fieldSchema2) {
@@ -1311,7 +1859,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1311
1859
  props.format,
1312
1860
  props.referenceSchema
1313
1861
  ]);
1314
- const handleValidate = useCallback6(({ property }) => {
1862
+ const handleValidate = useCallback8(({ property }) => {
1315
1863
  if (property && view.fields.find((f) => f.path === property && f.path !== field.path)) {
1316
1864
  return [
1317
1865
  {
@@ -1324,7 +1872,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1324
1872
  view.fields,
1325
1873
  field
1326
1874
  ]);
1327
- const handleSave = useCallback6((props2) => {
1875
+ const handleSave = useCallback8((props2) => {
1328
1876
  projection.setFieldProjection({
1329
1877
  field,
1330
1878
  props: props2
@@ -1335,51 +1883,51 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1335
1883
  field,
1336
1884
  onSave
1337
1885
  ]);
1338
- const handleCancel = useCallback6(() => {
1886
+ const handleCancel = useCallback8(() => {
1339
1887
  requestAnimationFrame(() => onCancel?.());
1340
1888
  onSave();
1341
1889
  }, [
1342
1890
  onSave
1343
1891
  ]);
1344
- const Custom = useMemo7(() => ({
1345
- ["format"]: (props2) => /* @__PURE__ */ React13.createElement(SelectInput, {
1892
+ const Custom = useMemo8(() => ({
1893
+ ["format"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
1346
1894
  ...props2,
1347
- options: FormatEnums.filter((value) => value !== FormatEnum2.None).map((value) => ({
1895
+ options: FormatEnums.filter((value) => value !== FormatEnum5.None).map((value) => ({
1348
1896
  value,
1349
1897
  label: t(`format ${value}`)
1350
1898
  }))
1351
1899
  }),
1352
- ["referenceSchema"]: (props2) => /* @__PURE__ */ React13.createElement(SelectInput, {
1900
+ ["referenceSchema"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
1353
1901
  ...props2,
1354
1902
  options: schemas.map((schema) => ({
1355
1903
  value: schema.typename
1356
1904
  }))
1357
1905
  }),
1358
- ["referencePath"]: (props2) => /* @__PURE__ */ React13.createElement(SelectInput, {
1906
+ ["referencePath"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
1359
1907
  ...props2,
1360
1908
  options: referenceSchema ? getSchemaProperties3(referenceSchema.ast).sort(sortProperties).map((p) => ({
1361
1909
  value: p.name
1362
1910
  })) : []
1363
1911
  }),
1364
- ["options"]: (props2) => /* @__PURE__ */ React13.createElement(SelectOptionInput, props2)
1912
+ ["options"]: (props2) => /* @__PURE__ */ React14.createElement(SelectOptionInput, props2)
1365
1913
  }), [
1366
1914
  t,
1367
1915
  schemas,
1368
1916
  referenceSchema
1369
1917
  ]);
1370
- const propIsNotType = useCallback6((props2) => props2.filter((p) => p.name !== "type"), []);
1918
+ const propIsNotType = useCallback8((props2) => props2.filter((p) => p.name !== "type"), []);
1371
1919
  if (!fieldSchema) {
1372
- log2.warn("invalid format", {
1920
+ log3.warn("invalid format", {
1373
1921
  props
1374
1922
  }, {
1375
- F: __dxlog_file3,
1923
+ F: __dxlog_file4,
1376
1924
  L: 174,
1377
1925
  S: void 0,
1378
1926
  C: (f, a) => f(...a)
1379
1927
  });
1380
1928
  return null;
1381
1929
  }
1382
- return /* @__PURE__ */ React13.createElement(Form, {
1930
+ return /* @__PURE__ */ React14.createElement(Form, {
1383
1931
  key: field.id,
1384
1932
  autoFocus: true,
1385
1933
  values: props,
@@ -1398,31 +1946,32 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1398
1946
  };
1399
1947
 
1400
1948
  // packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx
1401
- import React14, { useCallback as useCallback7, useMemo as useMemo8, useState as useState5 } from "react";
1402
- import { AST as AST4, Format, S as S2 } from "@dxos/echo-schema";
1949
+ import { Schema as Schema2, SchemaAST as SchemaAST5 } from "effect";
1950
+ import React15, { useCallback as useCallback9, useMemo as useMemo9, useState as useState6 } from "react";
1951
+ import { Format } from "@dxos/echo-schema";
1403
1952
  import { invariant as invariant3 } from "@dxos/invariant";
1404
1953
  import { IconButton as IconButton4, useTranslation as useTranslation7 } from "@dxos/react-ui";
1405
1954
  import { List as List2 } from "@dxos/react-ui-list";
1406
1955
  import { ghostHover, inputTextLabel, mx as mx9 } from "@dxos/react-ui-theme";
1407
1956
  import { FieldSchema, ViewProjection, VIEW_FIELD_LIMIT } from "@dxos/schema";
1408
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx";
1957
+ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx";
1409
1958
  var grid = "grid grid-cols-[32px_1fr_32px] min-bs-[2.5rem]";
1410
- var ViewMetaSchema = S2.Struct({
1411
- name: S2.String.annotations({
1412
- [AST4.TitleAnnotationId]: "View"
1959
+ var ViewMetaSchema = Schema2.Struct({
1960
+ name: Schema2.String.annotations({
1961
+ [SchemaAST5.TitleAnnotationId]: "View"
1413
1962
  }),
1414
1963
  typename: Format.URL.annotations({
1415
- [AST4.TitleAnnotationId]: "Typename"
1964
+ [SchemaAST5.TitleAnnotationId]: "Typename"
1416
1965
  })
1417
- }).pipe(S2.mutable);
1966
+ }).pipe(Schema2.mutable);
1418
1967
  var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading = false, onTypenameChanged, onDelete }) => {
1419
1968
  const { t } = useTranslation7(translationKey);
1420
- const projection = useMemo8(() => new ViewProjection(schema.jsonSchema, view), [
1969
+ const projection = useMemo9(() => new ViewProjection(schema.jsonSchema, view), [
1421
1970
  schema,
1422
1971
  view
1423
1972
  ]);
1424
- const [field, setField] = useState5();
1425
- const viewValues = useMemo8(() => {
1973
+ const [field, setField] = useState6();
1974
+ const viewValues = useMemo9(() => {
1426
1975
  return {
1427
1976
  name: view.name,
1428
1977
  // TODO(burdon): Need to warn user of possible consequences of editing.
@@ -1432,13 +1981,13 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1432
1981
  }, [
1433
1982
  view
1434
1983
  ]);
1435
- const handleSelect = useCallback7((field2) => {
1984
+ const handleSelect = useCallback9((field2) => {
1436
1985
  setField((f) => f === field2 ? void 0 : field2);
1437
1986
  }, []);
1438
- const handleAdd = useCallback7(() => {
1987
+ const handleAdd = useCallback9(() => {
1439
1988
  invariant3(!schema.readonly, void 0, {
1440
- F: __dxlog_file4,
1441
- L: 76,
1989
+ F: __dxlog_file5,
1990
+ L: 77,
1442
1991
  S: void 0,
1443
1992
  A: [
1444
1993
  "!schema.readonly",
@@ -1451,10 +2000,10 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1451
2000
  schema,
1452
2001
  view
1453
2002
  ]);
1454
- const handleUpdate = useCallback7(({ name, typename }) => {
2003
+ const handleUpdate = useCallback9(({ name, typename }) => {
1455
2004
  invariant3(!schema.readonly, void 0, {
1456
- F: __dxlog_file4,
1457
- L: 83,
2005
+ F: __dxlog_file5,
2006
+ L: 84,
1458
2007
  S: void 0,
1459
2008
  A: [
1460
2009
  "!schema.readonly",
@@ -1474,10 +2023,10 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1474
2023
  view,
1475
2024
  onTypenameChanged
1476
2025
  ]);
1477
- const handleDelete = useCallback7((fieldId) => {
2026
+ const handleDelete = useCallback9((fieldId) => {
1478
2027
  invariant3(!schema.readonly, void 0, {
1479
- F: __dxlog_file4,
1480
- L: 99,
2028
+ F: __dxlog_file5,
2029
+ L: 100,
1481
2030
  S: void 0,
1482
2031
  A: [
1483
2032
  "!schema.readonly",
@@ -1493,10 +2042,10 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1493
2042
  field,
1494
2043
  onDelete
1495
2044
  ]);
1496
- const handleMove = useCallback7((fromIndex, toIndex) => {
2045
+ const handleMove = useCallback9((fromIndex, toIndex) => {
1497
2046
  invariant3(!schema.readonly, void 0, {
1498
- F: __dxlog_file4,
1499
- L: 111,
2047
+ F: __dxlog_file5,
2048
+ L: 112,
1500
2049
  S: void 0,
1501
2050
  A: [
1502
2051
  "!schema.readonly",
@@ -1513,91 +2062,95 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1513
2062
  schema,
1514
2063
  view.fields
1515
2064
  ]);
1516
- const handleClose = useCallback7(() => setField(void 0), []);
2065
+ const handleClose = useCallback9(() => setField(void 0), []);
1517
2066
  const hiddenProperties = projection.getHiddenProperties();
1518
- const handleHide = useCallback7((fieldId) => {
2067
+ const handleHide = useCallback9((fieldId) => {
1519
2068
  setField(void 0);
1520
2069
  projection.hideFieldProjection(fieldId);
1521
2070
  }, [
1522
2071
  projection
1523
2072
  ]);
1524
- const handleShow = useCallback7((property) => {
2073
+ const handleShow = useCallback9((property) => {
1525
2074
  setField(void 0);
1526
2075
  projection.showFieldProjection(property);
1527
2076
  }, [
1528
2077
  projection
1529
2078
  ]);
1530
- return /* @__PURE__ */ React14.createElement("div", {
2079
+ return /* @__PURE__ */ React15.createElement("div", {
1531
2080
  role: "none",
1532
- className: mx9("flex flex-col w-full divide-y divide-separator", classNames)
1533
- }, /* @__PURE__ */ React14.createElement(Form, {
2081
+ className: mx9("grid grid-rows-[1fr_1fr] min-bs-0", classNames)
2082
+ }, /* @__PURE__ */ React15.createElement(Form, {
1534
2083
  autoSave: true,
1535
2084
  schema: ViewMetaSchema,
1536
2085
  values: viewValues,
1537
- onSave: schema.readonly ? void 0 : handleUpdate
1538
- }), /* @__PURE__ */ React14.createElement("div", null, /* @__PURE__ */ React14.createElement("div", {
2086
+ onSave: schema.readonly ? void 0 : handleUpdate,
2087
+ classNames: "min-bs-0 overflow-y-auto"
2088
+ }), /* @__PURE__ */ React15.createElement("div", {
2089
+ role: "none",
2090
+ className: "border-bs border-separator min-bs-0 overflow-y-auto"
2091
+ }, /* @__PURE__ */ React15.createElement("div", {
1539
2092
  role: "none",
1540
2093
  className: "p-2"
1541
- }, /* @__PURE__ */ React14.createElement("label", {
2094
+ }, /* @__PURE__ */ React15.createElement("label", {
1542
2095
  className: mx9(inputTextLabel)
1543
- }, t("fields label"))), /* @__PURE__ */ React14.createElement(List2.Root, {
2096
+ }, t("fields label"))), /* @__PURE__ */ React15.createElement(List2.Root, {
1544
2097
  items: view.fields,
1545
- isItem: S2.is(FieldSchema),
2098
+ isItem: Schema2.is(FieldSchema),
1546
2099
  getId: (field2) => field2.id,
1547
2100
  onMove: schema.readonly ? void 0 : handleMove
1548
- }, ({ items: fields }) => /* @__PURE__ */ React14.createElement(React14.Fragment, null, showHeading && /* @__PURE__ */ React14.createElement("div", {
2101
+ }, ({ items: fields }) => /* @__PURE__ */ React15.createElement(React15.Fragment, null, showHeading && /* @__PURE__ */ React15.createElement("div", {
1549
2102
  role: "heading",
1550
2103
  className: grid
1551
- }, /* @__PURE__ */ React14.createElement("div", null), /* @__PURE__ */ React14.createElement("div", {
2104
+ }, /* @__PURE__ */ React15.createElement("div", null), /* @__PURE__ */ React15.createElement("div", {
1552
2105
  className: "flex items-center text-sm"
1553
- }, t("field path label"))), /* @__PURE__ */ React14.createElement("div", {
2106
+ }, t("field path label"))), /* @__PURE__ */ React15.createElement("div", {
1554
2107
  role: "list",
1555
2108
  className: "flex flex-col w-full"
1556
- }, fields?.map((field2) => /* @__PURE__ */ React14.createElement(List2.Item, {
2109
+ }, fields?.map((field2) => /* @__PURE__ */ React15.createElement(List2.Item, {
1557
2110
  key: field2.id,
1558
2111
  item: field2,
1559
2112
  classNames: mx9(grid, ghostHover, "cursor-pointer")
1560
- }, /* @__PURE__ */ React14.createElement(List2.ItemDragHandle, null), /* @__PURE__ */ React14.createElement(List2.ItemTitle, {
2113
+ }, /* @__PURE__ */ React15.createElement(List2.ItemDragHandle, null), /* @__PURE__ */ React15.createElement(List2.ItemTitle, {
1561
2114
  onClick: () => handleSelect(field2)
1562
- }, field2.path), /* @__PURE__ */ React14.createElement("div", {
2115
+ }, field2.path), /* @__PURE__ */ React15.createElement("div", {
1563
2116
  className: "flex items-center gap-2 -ml-4"
1564
- }, /* @__PURE__ */ React14.createElement(List2.ItemButton, {
2117
+ }, /* @__PURE__ */ React15.createElement(List2.ItemButton, {
1565
2118
  icon: "ph--eye-slash--regular",
1566
2119
  disabled: view.fields.length <= 1,
1567
2120
  onClick: () => handleHide(field2.id)
1568
- }), !schema.readonly && /* @__PURE__ */ React14.createElement(List2.ItemDeleteButton, {
2121
+ }), !schema.readonly && /* @__PURE__ */ React15.createElement(List2.ItemDeleteButton, {
1569
2122
  icon: "ph--trash--regular",
1570
2123
  disabled: view.fields.length <= 1,
1571
2124
  onClick: () => handleDelete(field2.id)
1572
- }))))))), hiddenProperties.length > 0 && /* @__PURE__ */ React14.createElement("div", null, /* @__PURE__ */ React14.createElement("div", {
2125
+ }))))))), hiddenProperties.length > 0 && /* @__PURE__ */ React15.createElement("div", null, /* @__PURE__ */ React15.createElement("div", {
1573
2126
  role: "none",
1574
2127
  className: "p-2"
1575
- }, /* @__PURE__ */ React14.createElement("label", {
2128
+ }, /* @__PURE__ */ React15.createElement("label", {
1576
2129
  className: mx9(inputTextLabel)
1577
- }, t("hidden fields label"))), /* @__PURE__ */ React14.createElement(List2.Root, {
2130
+ }, t("hidden fields label"))), /* @__PURE__ */ React15.createElement(List2.Root, {
1578
2131
  items: hiddenProperties,
1579
2132
  isItem: (item) => typeof item === "string",
1580
2133
  getId: (property) => property
1581
- }, ({ items: properties }) => /* @__PURE__ */ React14.createElement("div", {
2134
+ }, ({ items: properties }) => /* @__PURE__ */ React15.createElement("div", {
1582
2135
  role: "list",
1583
2136
  className: "flex flex-col w-full"
1584
- }, properties?.map((property) => /* @__PURE__ */ React14.createElement(List2.Item, {
2137
+ }, properties?.map((property) => /* @__PURE__ */ React15.createElement(List2.Item, {
1585
2138
  key: property,
1586
2139
  item: property,
1587
2140
  classNames: mx9(grid, ghostHover, "cursor-pointer")
1588
- }, /* @__PURE__ */ React14.createElement("div", null), /* @__PURE__ */ React14.createElement(List2.ItemTitle, null, property), /* @__PURE__ */ React14.createElement(List2.ItemButton, {
2141
+ }, /* @__PURE__ */ React15.createElement("div", null), /* @__PURE__ */ React15.createElement(List2.ItemTitle, null, property), /* @__PURE__ */ React15.createElement(List2.ItemButton, {
1589
2142
  icon: "ph--eye--regular",
1590
2143
  onClick: () => handleShow(property)
1591
- }))))))), field && /* @__PURE__ */ React14.createElement(FieldEditor, {
2144
+ }))))))), field && /* @__PURE__ */ React15.createElement(FieldEditor, {
1592
2145
  key: field.id,
1593
2146
  view,
1594
2147
  projection,
1595
2148
  field,
1596
2149
  registry,
1597
2150
  onSave: handleClose
1598
- }), !readonly && !field && /* @__PURE__ */ React14.createElement("div", {
2151
+ }), !readonly && !field && /* @__PURE__ */ React15.createElement("div", {
1599
2152
  className: "flex p-2 justify-center"
1600
- }, /* @__PURE__ */ React14.createElement(IconButton4, {
2153
+ }, /* @__PURE__ */ React15.createElement(IconButton4, {
1601
2154
  icon: "ph--plus--regular",
1602
2155
  label: t("button add property"),
1603
2156
  onClick: schema.readonly ? void 0 : handleAdd,
@@ -1605,264 +2158,6 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1605
2158
  disabled: view.fields.length >= VIEW_FIELD_LIMIT
1606
2159
  })));
1607
2160
  };
1608
-
1609
- // packages/ui/react-ui-form/src/util/field.ts
1610
- import { FormatEnum as FormatEnum3, GeoLocation as GeoLocation2, TypeEnum } from "@dxos/echo-schema";
1611
- var parseValue = ({ type, format, value }) => {
1612
- if (value === void 0 || value === null || value === "") {
1613
- return void 0;
1614
- }
1615
- const parseScalar = (type2) => {
1616
- switch (type2) {
1617
- case TypeEnum.Boolean: {
1618
- if (typeof value === "string") {
1619
- const lowercaseValue = value.toLowerCase();
1620
- if (lowercaseValue === "0" || lowercaseValue === "false") {
1621
- return false;
1622
- } else if (lowercaseValue === "1" || lowercaseValue === "true") {
1623
- return true;
1624
- }
1625
- }
1626
- return Boolean(value);
1627
- }
1628
- case TypeEnum.Number: {
1629
- const cleaned = typeof value === "string" ? value.replace(/[^0-9.-]+/g, "") : value;
1630
- const num = Number(cleaned);
1631
- return Number.isNaN(num) ? null : num;
1632
- }
1633
- case TypeEnum.String:
1634
- case TypeEnum.Ref:
1635
- return String(value);
1636
- default: {
1637
- return value;
1638
- }
1639
- }
1640
- };
1641
- if (!format) {
1642
- return parseScalar(type);
1643
- }
1644
- switch (format) {
1645
- case FormatEnum3.Boolean:
1646
- return parseScalar(TypeEnum.Boolean);
1647
- case FormatEnum3.Number:
1648
- case FormatEnum3.Percent:
1649
- case FormatEnum3.Currency:
1650
- return parseScalar(TypeEnum.Number);
1651
- case FormatEnum3.String:
1652
- case FormatEnum3.Markdown: {
1653
- return parseScalar(TypeEnum.String);
1654
- }
1655
- case FormatEnum3.Ref:
1656
- throw new Error(`unexpected format: ${FormatEnum3.Ref}`);
1657
- case FormatEnum3.DateTime:
1658
- case FormatEnum3.Date:
1659
- case FormatEnum3.Time:
1660
- case FormatEnum3.Timestamp: {
1661
- const date = new Date(value);
1662
- return isNaN(date.getTime()) ? null : date;
1663
- }
1664
- case FormatEnum3.GeoPoint: {
1665
- if (typeof value === "string") {
1666
- const cleaned = value.replace(/[^0-9.,-]+/g, "");
1667
- const parts = cleaned.split(",");
1668
- if (parts.length === 2) {
1669
- const lat = parseFloat(parts[0]);
1670
- const long = parseFloat(parts[1]);
1671
- if (!isNaN(lat) && !isNaN(long)) {
1672
- return GeoLocation2.toGeoPoint({
1673
- latitude: lat,
1674
- longitude: long
1675
- });
1676
- }
1677
- }
1678
- }
1679
- return [
1680
- 0,
1681
- 0
1682
- ];
1683
- }
1684
- default: {
1685
- return value;
1686
- }
1687
- }
1688
- };
1689
- var cellClassesForFieldType = ({ type, format }) => {
1690
- if (!format) {
1691
- switch (type) {
1692
- case TypeEnum.Number:
1693
- return [
1694
- "text-right",
1695
- "font-mono"
1696
- ];
1697
- case TypeEnum.Boolean:
1698
- return [
1699
- "text-right",
1700
- "font-mono"
1701
- ];
1702
- case TypeEnum.String:
1703
- return void 0;
1704
- case TypeEnum.Ref:
1705
- return void 0;
1706
- default: {
1707
- return void 0;
1708
- }
1709
- }
1710
- }
1711
- switch (format) {
1712
- case FormatEnum3.Markdown:
1713
- return void 0;
1714
- case FormatEnum3.Time:
1715
- case FormatEnum3.Timestamp:
1716
- case FormatEnum3.DateTime:
1717
- case FormatEnum3.Date:
1718
- case FormatEnum3.Duration:
1719
- return [
1720
- "font-mono",
1721
- "text-right"
1722
- ];
1723
- case FormatEnum3.Currency:
1724
- return [
1725
- "text-right"
1726
- ];
1727
- case FormatEnum3.JSON:
1728
- case FormatEnum3.DID:
1729
- return [
1730
- "font-mono"
1731
- ];
1732
- default:
1733
- return void 0;
1734
- }
1735
- };
1736
- var pathNotUniqueError = (path) => ({
1737
- path: "path",
1738
- message: `'${path}' is already present`
1739
- });
1740
-
1741
- // packages/ui/react-ui-form/src/util/formatting.ts
1742
- import { format as formatDate } from "date-fns/format";
1743
- import { FormatEnum as FormatEnum4, GeoLocation as GeoLocation3, TypeEnum as TypeEnum2 } from "@dxos/echo-schema";
1744
- var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
1745
- const formatScalar = (type2) => {
1746
- switch (type2) {
1747
- case TypeEnum2.Boolean:
1748
- return value.toLocaleString().toUpperCase();
1749
- case TypeEnum2.Number:
1750
- return value.toLocaleString(locale);
1751
- case TypeEnum2.String:
1752
- case TypeEnum2.Ref:
1753
- return String(value);
1754
- default: {
1755
- return String(value);
1756
- }
1757
- }
1758
- };
1759
- if (!format) {
1760
- return formatScalar(type);
1761
- }
1762
- switch (format) {
1763
- case FormatEnum4.Boolean: {
1764
- return formatScalar(TypeEnum2.Boolean);
1765
- }
1766
- case FormatEnum4.Number: {
1767
- return formatScalar(TypeEnum2.Number);
1768
- }
1769
- case FormatEnum4.String:
1770
- case FormatEnum4.Ref: {
1771
- return formatScalar(TypeEnum2.String);
1772
- }
1773
- case FormatEnum4.Percent: {
1774
- return `${value * 100}%`;
1775
- }
1776
- case FormatEnum4.Currency: {
1777
- return value.toLocaleString(locale, {
1778
- style: "currency",
1779
- currency: "USD",
1780
- minimumFractionDigits: 2,
1781
- maximumFractionDigits: 2
1782
- });
1783
- }
1784
- case FormatEnum4.Date: {
1785
- return formatDate(new Date(value), "yyyy-MM-dd");
1786
- }
1787
- case FormatEnum4.Time: {
1788
- return formatDate(new Date(value), "HH:mm:ss");
1789
- }
1790
- case FormatEnum4.DateTime: {
1791
- return formatDate(new Date(value), "yyyy-MM-dd HH:mm:ss");
1792
- }
1793
- case FormatEnum4.GeoPoint: {
1794
- if (value === null || value === void 0) {
1795
- return "";
1796
- }
1797
- if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
1798
- const { latitude, longitude } = GeoLocation3.fromGeoPoint(value);
1799
- return `${latitude},${longitude}`;
1800
- }
1801
- return String(value);
1802
- }
1803
- default: {
1804
- if (value === null || value === "undefined") {
1805
- return "";
1806
- }
1807
- return String(value);
1808
- }
1809
- }
1810
- };
1811
- var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1812
- const formatScalar = (type2) => {
1813
- switch (type2) {
1814
- case TypeEnum2.Boolean:
1815
- case TypeEnum2.Number:
1816
- case TypeEnum2.String:
1817
- case TypeEnum2.Ref:
1818
- return String(value);
1819
- default:
1820
- return String(value);
1821
- }
1822
- };
1823
- if (!format) {
1824
- return formatScalar(type);
1825
- }
1826
- switch (format) {
1827
- case FormatEnum4.Boolean:
1828
- case FormatEnum4.Number:
1829
- case FormatEnum4.String:
1830
- case FormatEnum4.Ref: {
1831
- return formatScalar(type);
1832
- }
1833
- case FormatEnum4.Percent: {
1834
- return String(value * 100);
1835
- }
1836
- case FormatEnum4.Currency: {
1837
- return String(value);
1838
- }
1839
- case FormatEnum4.DateTime: {
1840
- const date = new Date(value);
1841
- return date.toISOString();
1842
- }
1843
- case FormatEnum4.Date: {
1844
- const date = new Date(value);
1845
- return date.toISOString().split("T")[0];
1846
- }
1847
- case FormatEnum4.Time: {
1848
- const date = new Date(value);
1849
- return date.toISOString().split("T")[1].split(".")[0];
1850
- }
1851
- case FormatEnum4.GeoPoint: {
1852
- if (value === null || value === void 0) {
1853
- return "";
1854
- }
1855
- if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
1856
- const { latitude, longitude } = GeoLocation3.fromGeoPoint(value);
1857
- return `${latitude},${longitude}`;
1858
- }
1859
- return String(value);
1860
- }
1861
- default: {
1862
- return String(value);
1863
- }
1864
- }
1865
- };
1866
2161
  export {
1867
2162
  BooleanInput,
1868
2163
  ControlFrame,
@@ -1890,14 +2185,18 @@ export {
1890
2185
  ViewEditor,
1891
2186
  cellClassesForFieldType,
1892
2187
  controlItemClasses,
2188
+ findArrayElementType,
1893
2189
  formatForDisplay,
1894
2190
  formatForEditing,
2191
+ getRefProps,
1895
2192
  parseValue,
1896
2193
  pathNotUniqueError,
1897
2194
  translations_default as translations,
1898
2195
  useForm,
1899
2196
  useFormContext,
1900
2197
  useFormValues,
1901
- useInputProps
2198
+ useInputProps,
2199
+ useQueryRefOptions,
2200
+ useRefQueryLookupHandler
1902
2201
  };
1903
2202
  //# sourceMappingURL=index.mjs.map