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