@dxos/react-ui-form 0.8.2-main.5885341 → 0.8.2-main.600d381

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 (80) hide show
  1. package/dist/lib/browser/index.mjs +720 -557
  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 +734 -579
  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 +720 -557
  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 +4 -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 +33 -32
  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 +3 -3
  20. package/dist/types/src/components/Form/FormContent.d.ts.map +1 -1
  21. package/dist/types/src/components/Form/FormContext.d.ts.map +1 -1
  22. package/dist/types/src/components/Form/Input.d.ts.map +1 -1
  23. package/dist/types/src/components/Form/RefField.d.ts +7 -18
  24. package/dist/types/src/components/Form/RefField.d.ts.map +1 -1
  25. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts.map +1 -1
  26. package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts.map +1 -1
  27. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts.map +1 -1
  28. package/dist/types/src/components/Form/custom/TupleInput.d.ts.map +1 -1
  29. package/dist/types/src/components/Form/factory.d.ts +1 -1
  30. package/dist/types/src/components/Form/factory.d.ts.map +1 -1
  31. package/dist/types/src/components/Form/index.d.ts.map +1 -1
  32. package/dist/types/src/components/ViewEditor/Test.stories.d.ts.map +1 -1
  33. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
  34. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
  35. package/dist/types/src/components/deprecated/Form.d.ts +2 -2
  36. package/dist/types/src/components/deprecated/Form.d.ts.map +1 -1
  37. package/dist/types/src/components/deprecated/Form.stories.d.ts.map +1 -1
  38. package/dist/types/src/components/deprecated/FormInput.d.ts.map +1 -1
  39. package/dist/types/src/components/testing.d.ts.map +1 -1
  40. package/dist/types/src/hooks/index.d.ts +2 -0
  41. package/dist/types/src/hooks/index.d.ts.map +1 -1
  42. package/dist/types/src/hooks/useForm.d.ts +2 -2
  43. package/dist/types/src/hooks/useForm.d.ts.map +1 -1
  44. package/dist/types/src/hooks/useQueryRefOptions.d.ts +23 -0
  45. package/dist/types/src/hooks/useQueryRefOptions.d.ts.map +1 -0
  46. package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts +8 -0
  47. package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts.map +1 -0
  48. package/dist/types/src/util/field.d.ts.map +1 -1
  49. package/dist/types/src/util/formatting.d.ts.map +1 -1
  50. package/dist/types/src/util/index.d.ts +2 -0
  51. package/dist/types/src/util/index.d.ts.map +1 -1
  52. package/dist/types/src/util/refs.d.ts +9 -0
  53. package/dist/types/src/util/refs.d.ts.map +1 -0
  54. package/dist/types/src/util/schema.d.ts +3 -0
  55. package/dist/types/src/util/schema.d.ts.map +1 -0
  56. package/dist/types/tsconfig.tsbuildinfo +1 -1
  57. package/package.json +25 -24
  58. package/src/components/ControlSection/ControlSection.stories.tsx +1 -1
  59. package/src/components/FieldEditor/FieldEditor.stories.tsx +1 -1
  60. package/src/components/Form/ArrayField.tsx +5 -6
  61. package/src/components/Form/Defaults.tsx +4 -1
  62. package/src/components/Form/Form.stories.tsx +48 -42
  63. package/src/components/Form/Form.tsx +4 -4
  64. package/src/components/Form/FormContent.tsx +49 -22
  65. package/src/components/Form/FormContext.tsx +3 -1
  66. package/src/components/Form/Input.tsx +3 -9
  67. package/src/components/Form/RefField.tsx +145 -100
  68. package/src/components/Form/custom/SelectOptionsInput.stories.tsx +6 -5
  69. package/src/components/Form/factory.tsx +1 -1
  70. package/src/components/Form/index.ts +0 -1
  71. package/src/components/ViewEditor/ViewEditor.stories.tsx +4 -3
  72. package/src/components/ViewEditor/ViewEditor.tsx +9 -8
  73. package/src/components/deprecated/Form.tsx +6 -6
  74. package/src/hooks/index.ts +3 -1
  75. package/src/hooks/useForm.ts +3 -3
  76. package/src/hooks/useQueryRefOptions.ts +53 -0
  77. package/src/hooks/useRefQueryLookupHandler.ts +41 -0
  78. package/src/util/index.ts +3 -1
  79. package/src/util/refs.ts +38 -0
  80. package/src/util/schema.ts +14 -0
@@ -183,8 +183,8 @@ var ControlFrameItem = ({ title, description, children }) => {
183
183
  };
184
184
 
185
185
  // packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx
186
- import React14, { useCallback as useCallback6, useEffect as useEffect8, useMemo as useMemo7, useState as useState5 } from "react";
187
- import { FormatEnum as FormatEnum2, FormatEnums, formatToType } from "@dxos/echo-schema";
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
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";
@@ -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 React13, { useEffect as useEffect7, 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,243 +1002,588 @@ 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 React12, { 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: 39,
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 {};
967
- }
968
- return Object.fromEntries(getSchemaProperties(typeLiteral, {}).map((prop) => [
969
- prop.name,
970
- prop.defaultValue
971
- ]));
972
- };
973
- const newValue = useMemo4(() => {
974
- if (type === "object" && elementType) {
975
- return getDefaultObjectValue(elementType);
976
- } else {
977
- return SimpleType.getDefaultValue(type);
978
- }
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
- }
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
- };
1048
1022
 
1049
- // packages/ui/react-ui-form/src/components/Form/RefField.tsx
1050
- import React11, { useEffect as useEffect6, useState as useState4 } from "react";
1051
- import { Expando, getTypeAnnotation, Ref, ReferenceAnnotationId } from "@dxos/echo-schema";
1052
- import { findAnnotation } from "@dxos/effect";
1053
- import { DXN } from "@dxos/keys";
1054
- import { refFromDXN } from "@dxos/live-object";
1055
- import { log as log2 } from "@dxos/log";
1056
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/Form/RefField.tsx";
1057
- var RefField = ({ ast, type, label, readonly, placeholder, inline, onQueryRefOptions, inputProps }) => {
1058
- const { getValue: getValue3, onValueChange, ...restInputProps } = inputProps;
1059
- const refTypeInfo = findAnnotation(ast, ReferenceAnnotationId);
1060
- const [refOptions, setRefOptions] = useState4([]);
1061
- const [loading, setLoading] = useState4(false);
1062
- useEffect6(() => {
1063
- if (!refTypeInfo || !onQueryRefOptions) {
1064
- return;
1065
- }
1066
- const fetchOptions = async () => {
1067
- setLoading(true);
1068
- try {
1069
- const options = await onQueryRefOptions(refTypeInfo);
1070
- setRefOptions(options.map((option) => ({
1071
- label: option.label,
1072
- value: option.dxn.toString()
1073
- })));
1074
- } catch (error) {
1075
- log2.error("Failed to fetch ref options:", error, {
1076
- F: __dxlog_file3,
1077
- L: 69,
1078
- S: void 0,
1079
- C: (f, a) => f(...a)
1080
- });
1081
- setRefOptions([]);
1082
- } finally {
1083
- setLoading(false);
1084
- }
1085
- };
1086
- void fetchOptions();
1087
- }, [
1088
- refTypeInfo,
1089
- onQueryRefOptions
1090
- ]);
1091
- if (!refTypeInfo) {
1092
- return null;
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;
1093
1028
  }
1094
- if (refTypeInfo.typename === getTypeAnnotation(Expando)?.typename || !onQueryRefOptions) {
1095
- const handleOnValueChange = (_type, dxnString) => {
1096
- const dxn = DXN.tryParse(dxnString);
1097
- if (dxn) {
1098
- onValueChange?.("object", refFromDXN(dxn));
1099
- } else if (dxnString === "") {
1100
- onValueChange?.("object", void 0);
1101
- } else {
1102
- onValueChange?.("string", dxnString);
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);
1103
1041
  }
1104
- };
1105
- const handleGetValue2 = () => {
1106
- const formValue = getValue3();
1107
- if (typeof formValue === "string") {
1108
- return formValue;
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;
1109
1046
  }
1110
- if (Ref.isRef(formValue)) {
1111
- return formValue.dxn.toString();
1047
+ case TypeEnum.String:
1048
+ case TypeEnum.Ref:
1049
+ return String(value);
1050
+ default: {
1051
+ return value;
1112
1052
  }
1113
- return void 0;
1114
- };
1115
- return /* @__PURE__ */ React11.createElement(TextInput, {
1116
- type,
1117
- label,
1118
- disabled: readonly,
1119
- placeholder,
1120
- inputOnly: inline,
1121
- getValue: handleGetValue2,
1122
- onValueChange: handleOnValueChange,
1123
- ...restInputProps
1124
- });
1125
- }
1126
- const handleGetValue = () => {
1127
- const formValue = getValue3();
1128
- if (Ref.isRef(formValue)) {
1129
- return formValue.dxn.toString();
1130
1053
  }
1131
- return void 0;
1132
- };
1133
- const handleValueChanged = (_type, dxnString) => {
1134
- const dxn = DXN.parse(dxnString);
1135
- const ref = refFromDXN(dxn);
1136
- onValueChange("object", ref);
1137
1054
  };
1138
- return /* @__PURE__ */ React11.createElement(SelectInput, {
1139
- type,
1140
- label,
1141
- disabled: readonly || loading,
1142
- placeholder: loading ? "Loading options..." : placeholder,
1143
- inputOnly: inline,
1144
- getValue: handleGetValue,
1145
- onValueChange: handleValueChanged,
1146
- options: refOptions,
1147
- ...restInputProps
1148
- });
1149
- };
1150
-
1151
- // packages/ui/react-ui-form/src/components/Form/factory.tsx
1152
- import { FormatEnum } from "@dxos/echo-schema";
1153
- var getInputComponent = (type, format) => {
1055
+ if (!format) {
1056
+ return parseScalar(type);
1057
+ }
1154
1058
  switch (format) {
1155
- case FormatEnum.GeoPoint:
1156
- return GeoPointInput;
1157
- case FormatEnum.Markdown:
1158
- return MarkdownInput;
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;
1100
+ }
1159
1101
  }
1160
- switch (type) {
1161
- case "string":
1102
+ };
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
+ }
1125
+ switch (format) {
1126
+ case FormatEnum.Markdown:
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;
1148
+ }
1149
+ };
1150
+ var pathNotUniqueError = (path) => ({
1151
+ path: "path",
1152
+ message: `'${path}' is already present`
1153
+ });
1154
+
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":
1162
1587
  return TextInput;
1163
1588
  case "number":
1164
1589
  return NumberInput;
@@ -1171,17 +1596,17 @@ var getInputComponent = (type, format) => {
1171
1596
  var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupComponent, Custom }) => {
1172
1597
  const inputProps = useInputProps(path);
1173
1598
  const { ast, name, type, format, title, description, options, examples, array } = property;
1174
- const label = useMemo5(() => title ?? pipe2(name, capitalize2), [
1599
+ const label = useMemo6(() => title ?? pipe2(name, capitalize2), [
1175
1600
  title,
1176
1601
  name
1177
1602
  ]);
1178
- const placeholder = useMemo5(() => examples?.length ? `Example: "${examples[0]}"` : description, [
1603
+ const placeholder = useMemo6(() => examples?.length ? `Example: "${examples[0]}"` : description, [
1179
1604
  examples,
1180
1605
  description
1181
1606
  ]);
1182
1607
  const FoundComponent = lookupComponent?.({
1183
1608
  prop: name,
1184
- schema: S.make(ast),
1609
+ schema: Schema.make(ast),
1185
1610
  inputProps: {
1186
1611
  type,
1187
1612
  format,
@@ -1209,6 +1634,21 @@ var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupCo
1209
1634
  ...inputProps
1210
1635
  });
1211
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
+ }
1212
1652
  if (array) {
1213
1653
  return /* @__PURE__ */ React12.createElement(ArrayField, {
1214
1654
  property,
@@ -1249,28 +1689,16 @@ var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupCo
1249
1689
  ...inputProps
1250
1690
  }));
1251
1691
  }
1252
- if (format === "ref") {
1253
- return /* @__PURE__ */ React12.createElement(RefField, {
1254
- ast,
1255
- type,
1256
- label,
1257
- readonly,
1258
- placeholder,
1259
- inline,
1260
- onQueryRefOptions,
1261
- inputProps
1262
- });
1263
- }
1264
1692
  if (type === "object") {
1265
- const baseNode = findNode2(ast, isDiscriminatedUnion2);
1266
- 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);
1267
1695
  if (typeLiteral) {
1268
1696
  return /* @__PURE__ */ React12.createElement("div", {
1269
1697
  role: "none"
1270
1698
  }, !inline && /* @__PURE__ */ React12.createElement("h3", {
1271
1699
  className: "text-lg mbs-2 mbe-1"
1272
1700
  }, label), /* @__PURE__ */ React12.createElement(FormFields, {
1273
- schema: S.make(typeLiteral),
1701
+ schema: Schema.make(typeLiteral),
1274
1702
  path,
1275
1703
  readonly,
1276
1704
  onQueryRefOptions,
@@ -1283,7 +1711,7 @@ var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupCo
1283
1711
  };
1284
1712
  var FormFields = ({ schema, path, filter, sort, readonly, onQueryRefOptions, lookupComponent, Custom }) => {
1285
1713
  const values = useFormValues(path);
1286
- const properties = useMemo5(() => {
1714
+ const properties = useMemo6(() => {
1287
1715
  const props = getSchemaProperties2(schema.ast, values);
1288
1716
  const filtered = filter ? filter(props) : props;
1289
1717
  return sort ? filtered.sort((a, b) => sort.indexOf(a.name) - sort.indexOf(b.name)) : filtered;
@@ -1315,7 +1743,7 @@ var FormFields = ({ schema, path, filter, sort, readonly, onQueryRefOptions, loo
1315
1743
  // packages/ui/react-ui-form/src/components/Form/Form.tsx
1316
1744
  var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, onQueryRefOptions, lookupComponent, Custom }) => {
1317
1745
  const formRef = useRef3(null);
1318
- const onValid = useMemo6(() => autoSave ? onSave : void 0, [
1746
+ const onValid = useMemo7(() => autoSave ? onSave : void 0, [
1319
1747
  autoSave,
1320
1748
  onSave
1321
1749
  ]);
@@ -1396,7 +1824,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1396
1824
  const [{ fieldSchema }, setFieldSchema] = useState5({
1397
1825
  fieldSchema: getFormatSchema(props?.format)
1398
1826
  });
1399
- const handleValuesChanged = useCallback6((_props) => {
1827
+ const handleValuesChanged = useCallback8((_props) => {
1400
1828
  setFieldSchema((prev) => {
1401
1829
  const fieldSchema2 = getFormatSchema(_props.format);
1402
1830
  if (prev.fieldSchema === fieldSchema2) {
@@ -1431,7 +1859,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1431
1859
  props.format,
1432
1860
  props.referenceSchema
1433
1861
  ]);
1434
- const handleValidate = useCallback6(({ property }) => {
1862
+ const handleValidate = useCallback8(({ property }) => {
1435
1863
  if (property && view.fields.find((f) => f.path === property && f.path !== field.path)) {
1436
1864
  return [
1437
1865
  {
@@ -1444,7 +1872,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1444
1872
  view.fields,
1445
1873
  field
1446
1874
  ]);
1447
- const handleSave = useCallback6((props2) => {
1875
+ const handleSave = useCallback8((props2) => {
1448
1876
  projection.setFieldProjection({
1449
1877
  field,
1450
1878
  props: props2
@@ -1455,16 +1883,16 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1455
1883
  field,
1456
1884
  onSave
1457
1885
  ]);
1458
- const handleCancel = useCallback6(() => {
1886
+ const handleCancel = useCallback8(() => {
1459
1887
  requestAnimationFrame(() => onCancel?.());
1460
1888
  onSave();
1461
1889
  }, [
1462
1890
  onSave
1463
1891
  ]);
1464
- const Custom = useMemo7(() => ({
1892
+ const Custom = useMemo8(() => ({
1465
1893
  ["format"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
1466
1894
  ...props2,
1467
- options: FormatEnums.filter((value) => value !== FormatEnum2.None).map((value) => ({
1895
+ options: FormatEnums.filter((value) => value !== FormatEnum5.None).map((value) => ({
1468
1896
  value,
1469
1897
  label: t(`format ${value}`)
1470
1898
  }))
@@ -1487,7 +1915,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1487
1915
  schemas,
1488
1916
  referenceSchema
1489
1917
  ]);
1490
- const propIsNotType = useCallback6((props2) => props2.filter((p) => p.name !== "type"), []);
1918
+ const propIsNotType = useCallback8((props2) => props2.filter((p) => p.name !== "type"), []);
1491
1919
  if (!fieldSchema) {
1492
1920
  log3.warn("invalid format", {
1493
1921
  props
@@ -1518,8 +1946,9 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1518
1946
  };
1519
1947
 
1520
1948
  // packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx
1521
- import React15, { useCallback as useCallback7, useMemo as useMemo8, useState as useState6 } from "react";
1522
- 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";
1523
1952
  import { invariant as invariant3 } from "@dxos/invariant";
1524
1953
  import { IconButton as IconButton4, useTranslation as useTranslation7 } from "@dxos/react-ui";
1525
1954
  import { List as List2 } from "@dxos/react-ui-list";
@@ -1527,22 +1956,22 @@ import { ghostHover, inputTextLabel, mx as mx9 } from "@dxos/react-ui-theme";
1527
1956
  import { FieldSchema, ViewProjection, VIEW_FIELD_LIMIT } from "@dxos/schema";
1528
1957
  var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx";
1529
1958
  var grid = "grid grid-cols-[32px_1fr_32px] min-bs-[2.5rem]";
1530
- var ViewMetaSchema = S2.Struct({
1531
- name: S2.String.annotations({
1532
- [AST4.TitleAnnotationId]: "View"
1959
+ var ViewMetaSchema = Schema2.Struct({
1960
+ name: Schema2.String.annotations({
1961
+ [SchemaAST5.TitleAnnotationId]: "View"
1533
1962
  }),
1534
1963
  typename: Format.URL.annotations({
1535
- [AST4.TitleAnnotationId]: "Typename"
1964
+ [SchemaAST5.TitleAnnotationId]: "Typename"
1536
1965
  })
1537
- }).pipe(S2.mutable);
1966
+ }).pipe(Schema2.mutable);
1538
1967
  var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading = false, onTypenameChanged, onDelete }) => {
1539
1968
  const { t } = useTranslation7(translationKey);
1540
- const projection = useMemo8(() => new ViewProjection(schema.jsonSchema, view), [
1969
+ const projection = useMemo9(() => new ViewProjection(schema.jsonSchema, view), [
1541
1970
  schema,
1542
1971
  view
1543
1972
  ]);
1544
1973
  const [field, setField] = useState6();
1545
- const viewValues = useMemo8(() => {
1974
+ const viewValues = useMemo9(() => {
1546
1975
  return {
1547
1976
  name: view.name,
1548
1977
  // TODO(burdon): Need to warn user of possible consequences of editing.
@@ -1552,13 +1981,13 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1552
1981
  }, [
1553
1982
  view
1554
1983
  ]);
1555
- const handleSelect = useCallback7((field2) => {
1984
+ const handleSelect = useCallback9((field2) => {
1556
1985
  setField((f) => f === field2 ? void 0 : field2);
1557
1986
  }, []);
1558
- const handleAdd = useCallback7(() => {
1987
+ const handleAdd = useCallback9(() => {
1559
1988
  invariant3(!schema.readonly, void 0, {
1560
1989
  F: __dxlog_file5,
1561
- L: 76,
1990
+ L: 77,
1562
1991
  S: void 0,
1563
1992
  A: [
1564
1993
  "!schema.readonly",
@@ -1571,10 +2000,10 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1571
2000
  schema,
1572
2001
  view
1573
2002
  ]);
1574
- const handleUpdate = useCallback7(({ name, typename }) => {
2003
+ const handleUpdate = useCallback9(({ name, typename }) => {
1575
2004
  invariant3(!schema.readonly, void 0, {
1576
2005
  F: __dxlog_file5,
1577
- L: 83,
2006
+ L: 84,
1578
2007
  S: void 0,
1579
2008
  A: [
1580
2009
  "!schema.readonly",
@@ -1594,10 +2023,10 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1594
2023
  view,
1595
2024
  onTypenameChanged
1596
2025
  ]);
1597
- const handleDelete = useCallback7((fieldId) => {
2026
+ const handleDelete = useCallback9((fieldId) => {
1598
2027
  invariant3(!schema.readonly, void 0, {
1599
2028
  F: __dxlog_file5,
1600
- L: 99,
2029
+ L: 100,
1601
2030
  S: void 0,
1602
2031
  A: [
1603
2032
  "!schema.readonly",
@@ -1613,10 +2042,10 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1613
2042
  field,
1614
2043
  onDelete
1615
2044
  ]);
1616
- const handleMove = useCallback7((fromIndex, toIndex) => {
2045
+ const handleMove = useCallback9((fromIndex, toIndex) => {
1617
2046
  invariant3(!schema.readonly, void 0, {
1618
2047
  F: __dxlog_file5,
1619
- L: 111,
2048
+ L: 112,
1620
2049
  S: void 0,
1621
2050
  A: [
1622
2051
  "!schema.readonly",
@@ -1633,15 +2062,15 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1633
2062
  schema,
1634
2063
  view.fields
1635
2064
  ]);
1636
- const handleClose = useCallback7(() => setField(void 0), []);
2065
+ const handleClose = useCallback9(() => setField(void 0), []);
1637
2066
  const hiddenProperties = projection.getHiddenProperties();
1638
- const handleHide = useCallback7((fieldId) => {
2067
+ const handleHide = useCallback9((fieldId) => {
1639
2068
  setField(void 0);
1640
2069
  projection.hideFieldProjection(fieldId);
1641
2070
  }, [
1642
2071
  projection
1643
2072
  ]);
1644
- const handleShow = useCallback7((property) => {
2073
+ const handleShow = useCallback9((property) => {
1645
2074
  setField(void 0);
1646
2075
  projection.showFieldProjection(property);
1647
2076
  }, [
@@ -1666,7 +2095,7 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1666
2095
  className: mx9(inputTextLabel)
1667
2096
  }, t("fields label"))), /* @__PURE__ */ React15.createElement(List2.Root, {
1668
2097
  items: view.fields,
1669
- isItem: S2.is(FieldSchema),
2098
+ isItem: Schema2.is(FieldSchema),
1670
2099
  getId: (field2) => field2.id,
1671
2100
  onMove: schema.readonly ? void 0 : handleMove
1672
2101
  }, ({ items: fields }) => /* @__PURE__ */ React15.createElement(React15.Fragment, null, showHeading && /* @__PURE__ */ React15.createElement("div", {
@@ -1729,276 +2158,6 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1729
2158
  disabled: view.fields.length >= VIEW_FIELD_LIMIT
1730
2159
  })));
1731
2160
  };
1732
-
1733
- // packages/ui/react-ui-form/src/util/field.ts
1734
- import { FormatEnum as FormatEnum3, GeoLocation as GeoLocation2, TypeEnum } from "@dxos/echo-schema";
1735
- var parseValue = ({ type, format, value }) => {
1736
- if (value === void 0 || value === null || value === "") {
1737
- return void 0;
1738
- }
1739
- const parseScalar = (type2) => {
1740
- switch (type2) {
1741
- case TypeEnum.Boolean: {
1742
- if (typeof value === "string") {
1743
- const lowercaseValue = value.toLowerCase();
1744
- if (lowercaseValue === "0" || lowercaseValue === "false") {
1745
- return false;
1746
- } else if (lowercaseValue === "1" || lowercaseValue === "true") {
1747
- return true;
1748
- }
1749
- }
1750
- return Boolean(value);
1751
- }
1752
- case TypeEnum.Number: {
1753
- const cleaned = typeof value === "string" ? value.replace(/[^0-9.-]+/g, "") : value;
1754
- const num = Number(cleaned);
1755
- return Number.isNaN(num) ? null : num;
1756
- }
1757
- case TypeEnum.String:
1758
- case TypeEnum.Ref:
1759
- return String(value);
1760
- default: {
1761
- return value;
1762
- }
1763
- }
1764
- };
1765
- if (!format) {
1766
- return parseScalar(type);
1767
- }
1768
- switch (format) {
1769
- case FormatEnum3.Boolean:
1770
- return parseScalar(TypeEnum.Boolean);
1771
- case FormatEnum3.Number:
1772
- case FormatEnum3.Percent:
1773
- case FormatEnum3.Currency:
1774
- return parseScalar(TypeEnum.Number);
1775
- case FormatEnum3.String:
1776
- case FormatEnum3.Markdown: {
1777
- return parseScalar(TypeEnum.String);
1778
- }
1779
- case FormatEnum3.Ref:
1780
- throw new Error(`unexpected format: ${FormatEnum3.Ref}`);
1781
- case FormatEnum3.DateTime:
1782
- case FormatEnum3.Date:
1783
- case FormatEnum3.Time:
1784
- case FormatEnum3.Timestamp: {
1785
- const date = new Date(value);
1786
- return isNaN(date.getTime()) ? null : date;
1787
- }
1788
- case FormatEnum3.GeoPoint: {
1789
- if (typeof value === "string") {
1790
- const cleaned = value.replace(/[^0-9.,-]+/g, "");
1791
- const parts = cleaned.split(",");
1792
- if (parts.length === 2) {
1793
- const lat = parseFloat(parts[0]);
1794
- const long = parseFloat(parts[1]);
1795
- if (!isNaN(lat) && !isNaN(long)) {
1796
- return GeoLocation2.toGeoPoint({
1797
- latitude: lat,
1798
- longitude: long
1799
- });
1800
- }
1801
- }
1802
- }
1803
- return [
1804
- 0,
1805
- 0
1806
- ];
1807
- }
1808
- default: {
1809
- return value;
1810
- }
1811
- }
1812
- };
1813
- var cellClassesForFieldType = ({ type, format }) => {
1814
- if (!format) {
1815
- switch (type) {
1816
- case TypeEnum.Number:
1817
- return [
1818
- "text-right",
1819
- "font-mono"
1820
- ];
1821
- case TypeEnum.Boolean:
1822
- return [
1823
- "text-right",
1824
- "font-mono"
1825
- ];
1826
- case TypeEnum.String:
1827
- return void 0;
1828
- case TypeEnum.Ref:
1829
- return void 0;
1830
- default: {
1831
- return void 0;
1832
- }
1833
- }
1834
- }
1835
- switch (format) {
1836
- case FormatEnum3.Markdown:
1837
- return void 0;
1838
- case FormatEnum3.Time:
1839
- case FormatEnum3.Timestamp:
1840
- case FormatEnum3.DateTime:
1841
- case FormatEnum3.Date:
1842
- case FormatEnum3.Duration:
1843
- return [
1844
- "font-mono",
1845
- "text-right"
1846
- ];
1847
- case FormatEnum3.Currency:
1848
- return [
1849
- "text-right"
1850
- ];
1851
- case FormatEnum3.JSON:
1852
- case FormatEnum3.DID:
1853
- return [
1854
- "font-mono"
1855
- ];
1856
- default:
1857
- return void 0;
1858
- }
1859
- };
1860
- var pathNotUniqueError = (path) => ({
1861
- path: "path",
1862
- message: `'${path}' is already present`
1863
- });
1864
-
1865
- // packages/ui/react-ui-form/src/util/formatting.ts
1866
- import { format as formatDate } from "date-fns/format";
1867
- import { FormatEnum as FormatEnum4, GeoLocation as GeoLocation3, TypeEnum as TypeEnum2 } from "@dxos/echo-schema";
1868
- var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
1869
- const formatScalar = (type2) => {
1870
- switch (type2) {
1871
- case TypeEnum2.Boolean:
1872
- return value.toLocaleString().toUpperCase();
1873
- case TypeEnum2.Number:
1874
- return value.toLocaleString(locale);
1875
- case TypeEnum2.String:
1876
- case TypeEnum2.Ref:
1877
- return String(value);
1878
- default: {
1879
- return String(value);
1880
- }
1881
- }
1882
- };
1883
- if (!format) {
1884
- return formatScalar(type);
1885
- }
1886
- switch (format) {
1887
- case FormatEnum4.Boolean: {
1888
- return formatScalar(TypeEnum2.Boolean);
1889
- }
1890
- case FormatEnum4.Number: {
1891
- return formatScalar(TypeEnum2.Number);
1892
- }
1893
- case FormatEnum4.String:
1894
- case FormatEnum4.Ref: {
1895
- return formatScalar(TypeEnum2.String);
1896
- }
1897
- case FormatEnum4.Percent: {
1898
- return `${value * 100}%`;
1899
- }
1900
- case FormatEnum4.Currency: {
1901
- return value.toLocaleString(locale, {
1902
- style: "currency",
1903
- currency: "USD",
1904
- minimumFractionDigits: 2,
1905
- maximumFractionDigits: 2
1906
- });
1907
- }
1908
- case FormatEnum4.Date: {
1909
- try {
1910
- return formatDate(new Date(value), "yyyy-MM-dd");
1911
- } catch (error) {
1912
- return "Invalid Date";
1913
- }
1914
- }
1915
- case FormatEnum4.Time: {
1916
- try {
1917
- return formatDate(new Date(value), "HH:mm:ss");
1918
- } catch (error) {
1919
- return "Invalid Time";
1920
- }
1921
- }
1922
- case FormatEnum4.DateTime: {
1923
- try {
1924
- return formatDate(new Date(value), "yyyy-MM-dd HH:mm:ss");
1925
- } catch (error) {
1926
- return "Invalid DateTime";
1927
- }
1928
- }
1929
- case FormatEnum4.GeoPoint: {
1930
- if (value === null || value === void 0) {
1931
- return "";
1932
- }
1933
- if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
1934
- const { latitude, longitude } = GeoLocation3.fromGeoPoint(value);
1935
- return `${latitude},${longitude}`;
1936
- }
1937
- return String(value);
1938
- }
1939
- default: {
1940
- if (value === null || value === "undefined") {
1941
- return "";
1942
- }
1943
- return String(value);
1944
- }
1945
- }
1946
- };
1947
- var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1948
- const formatScalar = (type2) => {
1949
- switch (type2) {
1950
- case TypeEnum2.Boolean:
1951
- case TypeEnum2.Number:
1952
- case TypeEnum2.String:
1953
- case TypeEnum2.Ref:
1954
- return String(value);
1955
- default:
1956
- return String(value);
1957
- }
1958
- };
1959
- if (!format) {
1960
- return formatScalar(type);
1961
- }
1962
- switch (format) {
1963
- case FormatEnum4.Boolean:
1964
- case FormatEnum4.Number:
1965
- case FormatEnum4.String:
1966
- case FormatEnum4.Ref: {
1967
- return formatScalar(type);
1968
- }
1969
- case FormatEnum4.Percent: {
1970
- return String(value * 100);
1971
- }
1972
- case FormatEnum4.Currency: {
1973
- return String(value);
1974
- }
1975
- case FormatEnum4.DateTime: {
1976
- const date = new Date(value);
1977
- return date.toISOString();
1978
- }
1979
- case FormatEnum4.Date: {
1980
- const date = new Date(value);
1981
- return date.toISOString().split("T")[0];
1982
- }
1983
- case FormatEnum4.Time: {
1984
- const date = new Date(value);
1985
- return date.toISOString().split("T")[1].split(".")[0];
1986
- }
1987
- case FormatEnum4.GeoPoint: {
1988
- if (value === null || value === void 0) {
1989
- return "";
1990
- }
1991
- if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
1992
- const { latitude, longitude } = GeoLocation3.fromGeoPoint(value);
1993
- return `${latitude},${longitude}`;
1994
- }
1995
- return String(value);
1996
- }
1997
- default: {
1998
- return String(value);
1999
- }
2000
- }
2001
- };
2002
2161
  export {
2003
2162
  BooleanInput,
2004
2163
  ControlFrame,
@@ -2026,14 +2185,18 @@ export {
2026
2185
  ViewEditor,
2027
2186
  cellClassesForFieldType,
2028
2187
  controlItemClasses,
2188
+ findArrayElementType,
2029
2189
  formatForDisplay,
2030
2190
  formatForEditing,
2191
+ getRefProps,
2031
2192
  parseValue,
2032
2193
  pathNotUniqueError,
2033
2194
  translations_default as translations,
2034
2195
  useForm,
2035
2196
  useFormContext,
2036
2197
  useFormValues,
2037
- useInputProps
2198
+ useInputProps,
2199
+ useQueryRefOptions,
2200
+ useRefQueryLookupHandler
2038
2201
  };
2039
2202
  //# sourceMappingURL=index.mjs.map