@dxos/react-ui-form 0.8.2-main.f11618f → 0.8.2-main.fbd8ed0

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 (81) hide show
  1. package/dist/lib/browser/index.mjs +731 -573
  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 +748 -598
  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 +731 -573
  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 +2 -2
  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 +10 -16
  62. package/src/components/Form/Defaults.tsx +4 -1
  63. package/src/components/Form/Form.stories.tsx +48 -42
  64. package/src/components/Form/Form.tsx +4 -4
  65. package/src/components/Form/FormContent.tsx +49 -22
  66. package/src/components/Form/FormContext.tsx +3 -1
  67. package/src/components/Form/Input.tsx +3 -9
  68. package/src/components/Form/RefField.tsx +147 -101
  69. package/src/components/Form/custom/SelectOptionsInput.stories.tsx +6 -5
  70. package/src/components/Form/factory.tsx +1 -1
  71. package/src/components/Form/index.ts +0 -1
  72. package/src/components/ViewEditor/ViewEditor.stories.tsx +5 -4
  73. package/src/components/ViewEditor/ViewEditor.tsx +23 -20
  74. package/src/components/deprecated/Form.tsx +6 -6
  75. package/src/hooks/index.ts +3 -1
  76. package/src/hooks/useForm.ts +4 -3
  77. package/src/hooks/useQueryRefOptions.ts +53 -0
  78. package/src/hooks/useRefQueryLookupHandler.ts +41 -0
  79. package/src/util/index.ts +3 -1
  80. package/src/util/refs.ts +38 -0
  81. package/src/util/schema.ts +14 -0
@@ -181,8 +181,8 @@ var ControlFrameItem = ({ title, description, children }) => {
181
181
  };
182
182
 
183
183
  // packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx
184
- import React14, { useCallback as useCallback6, useEffect as useEffect8, useMemo as useMemo7, useState as useState5 } from "react";
185
- import { FormatEnum as FormatEnum2, FormatEnums, formatToType } from "@dxos/echo-schema";
184
+ import React14, { useCallback as useCallback8, useEffect as useEffect8, useMemo as useMemo7, useState as useState5 } from "react";
185
+ import { FormatEnum as FormatEnum5, FormatEnums, formatToType } from "@dxos/echo-schema";
186
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";
@@ -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 }) => {
@@ -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
  });
@@ -736,7 +741,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
736
741
  } catch (err) {
737
742
  log.catch(err, void 0, {
738
743
  F: __dxlog_file,
739
- L: 212,
744
+ L: 213,
740
745
  S: void 0,
741
746
  C: (f, a) => f(...a)
742
747
  });
@@ -807,7 +812,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
807
812
  var createKeySet = (obj, value) => {
808
813
  invariant(obj, void 0, {
809
814
  F: __dxlog_file,
810
- L: 274,
815
+ L: 275,
811
816
  S: void 0,
812
817
  A: [
813
818
  "obj",
@@ -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,252 +1000,587 @@ 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
1005
  import React12, { 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";
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 } 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: 39,
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 {};
965
- }
966
- return Object.fromEntries(getSchemaProperties(typeLiteral, {}).map((prop) => [
967
- prop.name,
968
- prop.defaultValue
969
- ]));
970
- };
971
- const newValue = useMemo4(() => {
972
- if (type === "object" && elementType) {
973
- return getDefaultObjectValue(elementType);
974
- } else {
975
- return SimpleType.getDefaultValue(type);
976
- }
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
- }
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
- };
1046
1020
 
1047
- // packages/ui/react-ui-form/src/components/Form/RefField.tsx
1048
- import React11, { useEffect as useEffect6, useState as useState4 } from "react";
1049
- import { Expando, getTypeAnnotation, ReferenceAnnotationId } from "@dxos/echo-schema";
1050
- import { findAnnotation } from "@dxos/effect";
1051
- import { DXN } from "@dxos/keys";
1052
- import { refFromDXN, RefImpl } from "@dxos/live-object";
1053
- import { log as log2 } from "@dxos/log";
1054
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/Form/RefField.tsx";
1055
- var RefField = ({ ast, type, label, readonly, placeholder, inline, onQueryRefOptions, inputProps }) => {
1056
- const { getValue: getValue3, onValueChange, ...restInputProps } = inputProps;
1057
- const refTypeInfo = findAnnotation(ast, ReferenceAnnotationId);
1058
- const [refOptions, setRefOptions] = useState4([]);
1059
- const [loading, setLoading] = useState4(false);
1060
- useEffect6(() => {
1061
- if (!refTypeInfo || !onQueryRefOptions) {
1062
- return;
1063
- }
1064
- const fetchOptions = async () => {
1065
- setLoading(true);
1066
- try {
1067
- const options = await onQueryRefOptions(refTypeInfo);
1068
- setRefOptions(options.map((option) => ({
1069
- label: option.label,
1070
- value: option.dxn.toString()
1071
- })));
1072
- } catch (error) {
1073
- log2.error("Failed to fetch ref options:", error, {
1074
- F: __dxlog_file3,
1075
- L: 68,
1076
- S: void 0,
1077
- C: (f, a) => f(...a)
1078
- });
1079
- setRefOptions([]);
1080
- } finally {
1081
- setLoading(false);
1082
- }
1083
- };
1084
- void fetchOptions();
1085
- }, [
1086
- refTypeInfo,
1087
- onQueryRefOptions
1088
- ]);
1089
- if (!refTypeInfo) {
1090
- return null;
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;
1091
1026
  }
1092
- if (refTypeInfo.typename === getTypeAnnotation(Expando)?.typename || !onQueryRefOptions) {
1093
- const handleOnValueChange = (_type, dxnString) => {
1094
- const dxn = DXN.tryParse(dxnString);
1095
- if (dxn) {
1096
- onValueChange?.("object", refFromDXN(dxn));
1097
- } else if (dxnString === "") {
1098
- onValueChange?.("object", void 0);
1099
- } else {
1100
- onValueChange?.("string", dxnString);
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);
1101
1039
  }
1102
- };
1103
- const handleGetValue2 = () => {
1104
- const formValue = getValue3();
1105
- if (typeof formValue === "string") {
1106
- return formValue;
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;
1107
1044
  }
1108
- if (formValue instanceof RefImpl) {
1109
- return formValue.dxn.toString();
1045
+ case TypeEnum.String:
1046
+ case TypeEnum.Ref:
1047
+ return String(value);
1048
+ default: {
1049
+ return value;
1110
1050
  }
1111
- return void 0;
1112
- };
1113
- return /* @__PURE__ */ React11.createElement(TextInput, {
1114
- type,
1115
- label,
1116
- disabled: readonly,
1117
- placeholder,
1118
- inputOnly: inline,
1119
- getValue: handleGetValue2,
1120
- onValueChange: handleOnValueChange,
1121
- ...restInputProps
1122
- });
1123
- }
1124
- const handleGetValue = () => {
1125
- const formValue = getValue3();
1126
- if (formValue instanceof RefImpl) {
1127
- return formValue.dxn.toString();
1128
1051
  }
1129
- return void 0;
1130
- };
1131
- const handleValueChanged = (_type, dxnString) => {
1132
- const dxn = DXN.parse(dxnString);
1133
- const ref = refFromDXN(dxn);
1134
- onValueChange("object", ref);
1135
1052
  };
1136
- return /* @__PURE__ */ React11.createElement(SelectInput, {
1137
- type,
1138
- label,
1139
- disabled: readonly || loading,
1140
- placeholder: loading ? "Loading options..." : placeholder,
1141
- inputOnly: inline,
1142
- getValue: handleGetValue,
1143
- onValueChange: handleValueChanged,
1144
- options: refOptions,
1145
- ...restInputProps
1146
- });
1147
- };
1148
-
1149
- // packages/ui/react-ui-form/src/components/Form/factory.tsx
1150
- import { FormatEnum } from "@dxos/echo-schema";
1151
- var getInputComponent = (type, format) => {
1152
- switch (format) {
1153
- case FormatEnum.GeoPoint:
1154
- return GeoPointInput;
1155
- case FormatEnum.Markdown:
1156
- return MarkdownInput;
1053
+ if (!format) {
1054
+ return parseScalar(type);
1157
1055
  }
1158
- switch (type) {
1159
- case "string":
1160
- return TextInput;
1161
- case "number":
1162
- return NumberInput;
1163
- case "boolean":
1164
- return BooleanInput;
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;
1098
+ }
1165
1099
  }
1166
1100
  };
1167
-
1168
- // packages/ui/react-ui-form/src/components/Form/FormContent.tsx
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
+ }
1123
+ switch (format) {
1124
+ case FormatEnum.Markdown:
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;
1146
+ }
1147
+ };
1148
+ var pathNotUniqueError = (path) => ({
1149
+ path: "path",
1150
+ message: `'${path}' is already present`
1151
+ });
1152
+
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 getDefaultValue = () => type === "object" && elementType ? getDefaultObjectValue(elementType) : SimpleType.getDefaultValue(type);
1358
+ const handleAdd = useCallback6(() => {
1359
+ inputProps.onValueChange(type, [
1360
+ ...values,
1361
+ getDefaultValue()
1362
+ ]);
1363
+ }, [
1364
+ type,
1365
+ elementType,
1366
+ inputProps,
1367
+ values
1368
+ ]);
1369
+ const handleRemove = useCallback6((index) => {
1370
+ const newValues = values.filter((_, i) => i !== index);
1371
+ inputProps.onValueChange(type, newValues);
1372
+ }, [
1373
+ type,
1374
+ inputProps,
1375
+ values
1376
+ ]);
1377
+ if (!elementType) {
1378
+ return null;
1379
+ }
1380
+ return /* @__PURE__ */ React10.createElement("div", {
1381
+ role: "none",
1382
+ className: mx6(padding)
1383
+ }, /* @__PURE__ */ React10.createElement(InputHeader, null, label), /* @__PURE__ */ React10.createElement("div", {
1384
+ role: "none",
1385
+ className: "flex flex-col gap-1"
1386
+ }, values.map((_value, index) => /* @__PURE__ */ React10.createElement("div", {
1387
+ key: index,
1388
+ role: "none",
1389
+ className: "flex items-center gap-1"
1390
+ }, /* @__PURE__ */ React10.createElement("div", {
1391
+ role: "none",
1392
+ className: "flex-1"
1393
+ }, /* @__PURE__ */ React10.createElement(FormField, {
1394
+ property: {
1395
+ ...property,
1396
+ array: false,
1397
+ ast: elementType
1398
+ },
1399
+ path: [
1400
+ ...path ?? [],
1401
+ index
1402
+ ],
1403
+ readonly,
1404
+ inline: true,
1405
+ Custom,
1406
+ lookupComponent
1407
+ })), /* @__PURE__ */ React10.createElement(IconButton3, {
1408
+ icon: "ph--trash--regular",
1409
+ iconOnly: true,
1410
+ label: t("button remove"),
1411
+ onClick: () => handleRemove(index)
1412
+ })))), /* @__PURE__ */ React10.createElement("div", {
1413
+ role: "none",
1414
+ className: "flex justify-between items-center plb-1"
1415
+ }, /* @__PURE__ */ React10.createElement(IconButton3, {
1416
+ icon: "ph--plus--regular",
1417
+ iconOnly: true,
1418
+ label: t("button add"),
1419
+ onClick: handleAdd
1420
+ })));
1421
+ };
1422
+
1423
+ // packages/ui/react-ui-form/src/components/Form/RefField.tsx
1424
+ import React11, { useCallback as useCallback7, useMemo as useMemo4 } from "react";
1425
+ import { Expando, getTypeAnnotation, Ref, ReferenceAnnotationId as ReferenceAnnotationId2 } from "@dxos/echo-schema";
1426
+ import { findAnnotation as findAnnotation2 } from "@dxos/effect";
1427
+ import { DXN } from "@dxos/keys";
1428
+ import { Input as Input7 } from "@dxos/react-ui";
1429
+ import { TagPicker } from "@dxos/react-ui-tag-picker";
1430
+ import { isNonNullable as isNonNullable2 } from "@dxos/util";
1431
+ var RefField = ({ type, label, disabled, placeholder, inputOnly, array, ast, getValue: getValue3, onBlur, onQueryRefOptions, onValueChange, ...restInputProps }) => {
1432
+ const refTypeInfo = useMemo4(() => ast ? findAnnotation2(ast, ReferenceAnnotationId2) : void 0, [
1433
+ ast
1434
+ ]);
1435
+ const { options: availableOptions, loading: _loading } = useQueryRefOptions({
1436
+ refTypeInfo,
1437
+ onQueryRefOptions
1438
+ });
1439
+ if (refTypeInfo && refTypeInfo?.typename === getTypeAnnotation(Expando)?.typename || !onQueryRefOptions) {
1440
+ return /* @__PURE__ */ React11.createElement(RefFieldFallback, {
1441
+ type,
1442
+ label,
1443
+ placeholder,
1444
+ disabled,
1445
+ inputOnly,
1446
+ getValue: getValue3,
1447
+ onBlur,
1448
+ onValueChange,
1449
+ ...restInputProps
1450
+ });
1451
+ }
1452
+ const handleGetValue = useCallback7(() => {
1453
+ const formValue = getValue3();
1454
+ const unknownToRefOption = (val) => {
1455
+ if (Ref.isRef(val)) {
1456
+ const dxnString = val.dxn.toString();
1457
+ const matchingOption = availableOptions.find((option2) => option2.id === dxnString);
1458
+ if (matchingOption) {
1459
+ return matchingOption;
1460
+ }
1461
+ }
1462
+ return void 0;
1463
+ };
1464
+ if (array && Array.isArray(formValue)) {
1465
+ return formValue.map(unknownToRefOption).filter(isNonNullable2) ?? [];
1466
+ }
1467
+ const option = unknownToRefOption(formValue);
1468
+ if (option) {
1469
+ return [
1470
+ option
1471
+ ];
1472
+ }
1473
+ return [];
1474
+ }, [
1475
+ getValue3,
1476
+ availableOptions,
1477
+ array
1478
+ ]);
1479
+ const handleSearch = useCallback7((text, ids) => availableOptions.filter((option) => !ids.includes(option.id)).filter((option) => option.label.toLowerCase().includes(text.toLowerCase())).map((option) => ({
1480
+ id: option.id,
1481
+ label: option.label,
1482
+ hue: option.hue
1483
+ })), [
1484
+ availableOptions
1485
+ ]);
1486
+ const handleUpdate = useCallback7((ids) => {
1487
+ if (ids.length === 0) {
1488
+ onValueChange("object", void 0);
1489
+ return;
1490
+ }
1491
+ const refs = ids.map((id) => {
1492
+ const item = availableOptions.find((option) => option.id === id);
1493
+ if (item) {
1494
+ const dxn = DXN.parse(item.id);
1495
+ return Ref.fromDXN(dxn);
1496
+ }
1497
+ return null;
1498
+ }).filter(isNonNullable2);
1499
+ if (array) {
1500
+ onValueChange("object", refs);
1501
+ } else {
1502
+ onValueChange("object", refs[0]);
1503
+ }
1504
+ }, [
1505
+ availableOptions,
1506
+ array,
1507
+ onValueChange
1508
+ ]);
1509
+ const tagPickerMode = useMemo4(() => array ? "multi-select" : "single-select", [
1510
+ array
1511
+ ]);
1512
+ if (!refTypeInfo) {
1513
+ return null;
1514
+ }
1515
+ const { status, error } = restInputProps.getStatus();
1516
+ return /* @__PURE__ */ React11.createElement(Input7.Root, {
1517
+ validationValence: status
1518
+ }, !inputOnly && /* @__PURE__ */ React11.createElement(InputHeader, {
1519
+ error
1520
+ }, /* @__PURE__ */ React11.createElement(Input7.Label, null, label)), /* @__PURE__ */ React11.createElement("div", {
1521
+ "data-no-submit": true
1522
+ }, /* @__PURE__ */ React11.createElement(TagPicker, {
1523
+ items: handleGetValue(),
1524
+ mode: tagPickerMode,
1525
+ onBlur: (event) => onBlur(event),
1526
+ onUpdate: handleUpdate,
1527
+ onSearch: handleSearch,
1528
+ classNames: "rounded-sm bg-input p-1.5"
1529
+ })), inputOnly && /* @__PURE__ */ React11.createElement(Input7.DescriptionAndValidation, null, error));
1530
+ };
1531
+ var RefFieldFallback = ({ type, label, disabled, placeholder, inputOnly, getValue: getValue3, onValueChange, ...restInputProps }) => {
1532
+ const handleOnValueChange = (_type, dxnString) => {
1533
+ const dxn = DXN.tryParse(dxnString);
1534
+ if (dxn) {
1535
+ onValueChange?.("object", Ref.fromDXN(dxn));
1536
+ } else if (dxnString === "") {
1537
+ onValueChange?.("object", void 0);
1538
+ } else {
1539
+ onValueChange?.("string", dxnString);
1540
+ }
1541
+ };
1542
+ const handleGetValue = () => {
1543
+ const formValue = getValue3();
1544
+ if (typeof formValue === "string") {
1545
+ return formValue;
1546
+ }
1547
+ if (Ref.isRef(formValue)) {
1548
+ return formValue.dxn.toString();
1549
+ }
1550
+ return void 0;
1551
+ };
1552
+ return /* @__PURE__ */ React11.createElement(TextInput, {
1553
+ type,
1554
+ label,
1555
+ disabled,
1556
+ placeholder,
1557
+ inputOnly,
1558
+ getValue: handleGetValue,
1559
+ onValueChange: handleOnValueChange,
1560
+ ...restInputProps
1561
+ });
1562
+ };
1563
+
1564
+ // packages/ui/react-ui-form/src/components/Form/factory.tsx
1565
+ import { FormatEnum as FormatEnum4 } from "@dxos/echo-schema";
1566
+ var getInputComponent = (type, format) => {
1567
+ switch (format) {
1568
+ case FormatEnum4.GeoPoint:
1569
+ return GeoPointInput;
1570
+ case FormatEnum4.Markdown:
1571
+ return MarkdownInput;
1572
+ }
1573
+ switch (type) {
1574
+ case "string":
1575
+ return TextInput;
1576
+ case "number":
1577
+ return NumberInput;
1578
+ case "boolean":
1579
+ return BooleanInput;
1580
+ }
1581
+ };
1582
+
1583
+ // packages/ui/react-ui-form/src/components/Form/FormContent.tsx
1169
1584
  var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupComponent, Custom }) => {
1170
1585
  const inputProps = useInputProps(path);
1171
1586
  const { ast, name, type, format, title, description, options, examples, array } = property;
@@ -1179,7 +1594,7 @@ var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupCo
1179
1594
  ]);
1180
1595
  const FoundComponent = lookupComponent?.({
1181
1596
  prop: name,
1182
- schema: S.make(ast),
1597
+ schema: Schema.make(ast),
1183
1598
  inputProps: {
1184
1599
  type,
1185
1600
  format,
@@ -1207,6 +1622,21 @@ var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupCo
1207
1622
  ...inputProps
1208
1623
  });
1209
1624
  }
1625
+ const refProps = getRefProps(property);
1626
+ if (refProps) {
1627
+ return /* @__PURE__ */ React12.createElement(RefField, {
1628
+ ast: refProps.ast,
1629
+ array: refProps.isArray,
1630
+ type,
1631
+ format,
1632
+ label,
1633
+ placeholder,
1634
+ disabled: readonly,
1635
+ inputOnly: inline,
1636
+ onQueryRefOptions,
1637
+ ...inputProps
1638
+ });
1639
+ }
1210
1640
  if (array) {
1211
1641
  return /* @__PURE__ */ React12.createElement(ArrayField, {
1212
1642
  property,
@@ -1247,28 +1677,16 @@ var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupCo
1247
1677
  ...inputProps
1248
1678
  }));
1249
1679
  }
1250
- if (format === "ref") {
1251
- return /* @__PURE__ */ React12.createElement(RefField, {
1252
- ast,
1253
- type,
1254
- label,
1255
- readonly,
1256
- placeholder,
1257
- inline,
1258
- onQueryRefOptions,
1259
- inputProps
1260
- });
1261
- }
1262
1680
  if (type === "object") {
1263
- const baseNode = findNode2(ast, isDiscriminatedUnion2);
1264
- const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, inputProps.getValue()) : findNode2(ast, AST3.isTypeLiteral);
1681
+ const baseNode = findNode3(ast, isDiscriminatedUnion2);
1682
+ const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, inputProps.getValue()) : findNode3(ast, SchemaAST4.isTypeLiteral);
1265
1683
  if (typeLiteral) {
1266
1684
  return /* @__PURE__ */ React12.createElement("div", {
1267
1685
  role: "none"
1268
1686
  }, !inline && /* @__PURE__ */ React12.createElement("h3", {
1269
1687
  className: "text-lg mbs-2 mbe-1"
1270
1688
  }, label), /* @__PURE__ */ React12.createElement(FormFields, {
1271
- schema: S.make(typeLiteral),
1689
+ schema: Schema.make(typeLiteral),
1272
1690
  path,
1273
1691
  readonly,
1274
1692
  onQueryRefOptions,
@@ -1394,7 +1812,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1394
1812
  const [{ fieldSchema }, setFieldSchema] = useState5({
1395
1813
  fieldSchema: getFormatSchema(props?.format)
1396
1814
  });
1397
- const handleValuesChanged = useCallback6((_props) => {
1815
+ const handleValuesChanged = useCallback8((_props) => {
1398
1816
  setFieldSchema((prev) => {
1399
1817
  const fieldSchema2 = getFormatSchema(_props.format);
1400
1818
  if (prev.fieldSchema === fieldSchema2) {
@@ -1429,7 +1847,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1429
1847
  props.format,
1430
1848
  props.referenceSchema
1431
1849
  ]);
1432
- const handleValidate = useCallback6(({ property }) => {
1850
+ const handleValidate = useCallback8(({ property }) => {
1433
1851
  if (property && view.fields.find((f) => f.path === property && f.path !== field.path)) {
1434
1852
  return [
1435
1853
  {
@@ -1442,7 +1860,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1442
1860
  view.fields,
1443
1861
  field
1444
1862
  ]);
1445
- const handleSave = useCallback6((props2) => {
1863
+ const handleSave = useCallback8((props2) => {
1446
1864
  projection.setFieldProjection({
1447
1865
  field,
1448
1866
  props: props2
@@ -1453,7 +1871,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1453
1871
  field,
1454
1872
  onSave
1455
1873
  ]);
1456
- const handleCancel = useCallback6(() => {
1874
+ const handleCancel = useCallback8(() => {
1457
1875
  requestAnimationFrame(() => onCancel?.());
1458
1876
  onSave();
1459
1877
  }, [
@@ -1462,7 +1880,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1462
1880
  const Custom = useMemo7(() => ({
1463
1881
  ["format"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
1464
1882
  ...props2,
1465
- options: FormatEnums.filter((value) => value !== FormatEnum2.None).map((value) => ({
1883
+ options: FormatEnums.filter((value) => value !== FormatEnum5.None).map((value) => ({
1466
1884
  value,
1467
1885
  label: t(`format ${value}`)
1468
1886
  }))
@@ -1485,7 +1903,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1485
1903
  schemas,
1486
1904
  referenceSchema
1487
1905
  ]);
1488
- const propIsNotType = useCallback6((props2) => props2.filter((p) => p.name !== "type"), []);
1906
+ const propIsNotType = useCallback8((props2) => props2.filter((p) => p.name !== "type"), []);
1489
1907
  if (!fieldSchema) {
1490
1908
  log3.warn("invalid format", {
1491
1909
  props
@@ -1516,8 +1934,9 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
1516
1934
  };
1517
1935
 
1518
1936
  // packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx
1519
- import React15, { useCallback as useCallback7, useMemo as useMemo8, useState as useState6 } from "react";
1520
- import { AST as AST4, Format, S as S2 } from "@dxos/echo-schema";
1937
+ import { Schema as Schema2, SchemaAST as SchemaAST5 } from "effect";
1938
+ import React15, { useCallback as useCallback9, useMemo as useMemo8, useState as useState6 } from "react";
1939
+ import { Format, isMutable, toJsonSchema } from "@dxos/echo-schema";
1521
1940
  import { invariant as invariant3 } from "@dxos/invariant";
1522
1941
  import { IconButton as IconButton4, useTranslation as useTranslation7 } from "@dxos/react-ui";
1523
1942
  import { List as List2 } from "@dxos/react-ui-list";
@@ -1525,21 +1944,22 @@ import { ghostHover, inputTextLabel, mx as mx9 } from "@dxos/react-ui-theme";
1525
1944
  import { FieldSchema, ViewProjection, VIEW_FIELD_LIMIT } from "@dxos/schema";
1526
1945
  var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx";
1527
1946
  var grid = "grid grid-cols-[32px_1fr_32px] min-bs-[2.5rem]";
1528
- var ViewMetaSchema = S2.Struct({
1529
- name: S2.String.annotations({
1530
- [AST4.TitleAnnotationId]: "View"
1947
+ var ViewMetaSchema = Schema2.Struct({
1948
+ name: Schema2.String.annotations({
1949
+ [SchemaAST5.TitleAnnotationId]: "View"
1531
1950
  }),
1532
1951
  typename: Format.URL.annotations({
1533
- [AST4.TitleAnnotationId]: "Typename"
1952
+ [SchemaAST5.TitleAnnotationId]: "Typename"
1534
1953
  })
1535
- }).pipe(S2.mutable);
1954
+ }).pipe(Schema2.mutable);
1536
1955
  var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading = false, onTypenameChanged, onDelete }) => {
1537
1956
  const { t } = useTranslation7(translationKey);
1538
- const projection = useMemo8(() => new ViewProjection(schema.jsonSchema, view), [
1957
+ const projection = useMemo8(() => new ViewProjection(toJsonSchema(schema), view), [
1539
1958
  schema,
1540
1959
  view
1541
1960
  ]);
1542
1961
  const [field, setField] = useState6();
1962
+ const immutable = readonly || !isMutable(schema);
1543
1963
  const viewValues = useMemo8(() => {
1544
1964
  return {
1545
1965
  name: view.name,
@@ -1550,16 +1970,16 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1550
1970
  }, [
1551
1971
  view
1552
1972
  ]);
1553
- const handleSelect = useCallback7((field2) => {
1973
+ const handleSelect = useCallback9((field2) => {
1554
1974
  setField((f) => f === field2 ? void 0 : field2);
1555
1975
  }, []);
1556
- const handleAdd = useCallback7(() => {
1557
- invariant3(!schema.readonly, void 0, {
1976
+ const handleAdd = useCallback9(() => {
1977
+ invariant3(!immutable, void 0, {
1558
1978
  F: __dxlog_file5,
1559
- L: 76,
1979
+ L: 78,
1560
1980
  S: void 0,
1561
1981
  A: [
1562
- "!schema.readonly",
1982
+ "!immutable",
1563
1983
  ""
1564
1984
  ]
1565
1985
  });
@@ -1569,13 +1989,13 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1569
1989
  schema,
1570
1990
  view
1571
1991
  ]);
1572
- const handleUpdate = useCallback7(({ name, typename }) => {
1573
- invariant3(!schema.readonly, void 0, {
1992
+ const handleUpdate = useCallback9(({ name, typename }) => {
1993
+ invariant3(!immutable, void 0, {
1574
1994
  F: __dxlog_file5,
1575
- L: 83,
1995
+ L: 85,
1576
1996
  S: void 0,
1577
1997
  A: [
1578
- "!schema.readonly",
1998
+ "!immutable",
1579
1999
  ""
1580
2000
  ]
1581
2001
  });
@@ -1592,13 +2012,13 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1592
2012
  view,
1593
2013
  onTypenameChanged
1594
2014
  ]);
1595
- const handleDelete = useCallback7((fieldId) => {
1596
- invariant3(!schema.readonly, void 0, {
2015
+ const handleDelete = useCallback9((fieldId) => {
2016
+ invariant3(!immutable, void 0, {
1597
2017
  F: __dxlog_file5,
1598
- L: 99,
2018
+ L: 101,
1599
2019
  S: void 0,
1600
2020
  A: [
1601
- "!schema.readonly",
2021
+ "!immutable",
1602
2022
  ""
1603
2023
  ]
1604
2024
  });
@@ -1611,13 +2031,13 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1611
2031
  field,
1612
2032
  onDelete
1613
2033
  ]);
1614
- const handleMove = useCallback7((fromIndex, toIndex) => {
1615
- invariant3(!schema.readonly, void 0, {
2034
+ const handleMove = useCallback9((fromIndex, toIndex) => {
2035
+ invariant3(!immutable, void 0, {
1616
2036
  F: __dxlog_file5,
1617
- L: 111,
2037
+ L: 113,
1618
2038
  S: void 0,
1619
2039
  A: [
1620
- "!schema.readonly",
2040
+ "!immutable",
1621
2041
  ""
1622
2042
  ]
1623
2043
  });
@@ -1631,15 +2051,15 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1631
2051
  schema,
1632
2052
  view.fields
1633
2053
  ]);
1634
- const handleClose = useCallback7(() => setField(void 0), []);
2054
+ const handleClose = useCallback9(() => setField(void 0), []);
1635
2055
  const hiddenProperties = projection.getHiddenProperties();
1636
- const handleHide = useCallback7((fieldId) => {
2056
+ const handleHide = useCallback9((fieldId) => {
1637
2057
  setField(void 0);
1638
2058
  projection.hideFieldProjection(fieldId);
1639
2059
  }, [
1640
2060
  projection
1641
2061
  ]);
1642
- const handleShow = useCallback7((property) => {
2062
+ const handleShow = useCallback9((property) => {
1643
2063
  setField(void 0);
1644
2064
  projection.showFieldProjection(property);
1645
2065
  }, [
@@ -1647,22 +2067,26 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1647
2067
  ]);
1648
2068
  return /* @__PURE__ */ React15.createElement("div", {
1649
2069
  role: "none",
1650
- className: mx9("flex flex-col w-full divide-y divide-separator", classNames)
2070
+ className: mx9("grid grid-rows-[1fr_1fr] min-bs-0", classNames)
1651
2071
  }, /* @__PURE__ */ React15.createElement(Form, {
1652
2072
  autoSave: true,
1653
2073
  schema: ViewMetaSchema,
1654
2074
  values: viewValues,
1655
- onSave: schema.readonly ? void 0 : handleUpdate
1656
- }), /* @__PURE__ */ React15.createElement("div", null, /* @__PURE__ */ React15.createElement("div", {
2075
+ onSave: immutable ? void 0 : handleUpdate,
2076
+ classNames: "min-bs-0 overflow-y-auto"
2077
+ }), /* @__PURE__ */ React15.createElement("div", {
2078
+ role: "none",
2079
+ className: "border-bs border-separator min-bs-0 overflow-y-auto"
2080
+ }, /* @__PURE__ */ React15.createElement("div", {
1657
2081
  role: "none",
1658
2082
  className: "p-2"
1659
2083
  }, /* @__PURE__ */ React15.createElement("label", {
1660
2084
  className: mx9(inputTextLabel)
1661
2085
  }, t("fields label"))), /* @__PURE__ */ React15.createElement(List2.Root, {
1662
2086
  items: view.fields,
1663
- isItem: S2.is(FieldSchema),
2087
+ isItem: Schema2.is(FieldSchema),
1664
2088
  getId: (field2) => field2.id,
1665
- onMove: schema.readonly ? void 0 : handleMove
2089
+ onMove: immutable ? void 0 : handleMove
1666
2090
  }, ({ items: fields }) => /* @__PURE__ */ React15.createElement(React15.Fragment, null, showHeading && /* @__PURE__ */ React15.createElement("div", {
1667
2091
  role: "heading",
1668
2092
  className: grid
@@ -1683,7 +2107,7 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1683
2107
  icon: "ph--eye-slash--regular",
1684
2108
  disabled: view.fields.length <= 1,
1685
2109
  onClick: () => handleHide(field2.id)
1686
- }), !schema.readonly && /* @__PURE__ */ React15.createElement(List2.ItemDeleteButton, {
2110
+ }), !immutable && /* @__PURE__ */ React15.createElement(List2.ItemDeleteButton, {
1687
2111
  icon: "ph--trash--regular",
1688
2112
  disabled: view.fields.length <= 1,
1689
2113
  onClick: () => handleDelete(field2.id)
@@ -1718,281 +2142,11 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1718
2142
  }, /* @__PURE__ */ React15.createElement(IconButton4, {
1719
2143
  icon: "ph--plus--regular",
1720
2144
  label: t("button add property"),
1721
- onClick: schema.readonly ? void 0 : handleAdd,
2145
+ onClick: immutable ? void 0 : handleAdd,
1722
2146
  // TODO(burdon): Show field limit in ux (not tooltip).
1723
2147
  disabled: view.fields.length >= VIEW_FIELD_LIMIT
1724
2148
  })));
1725
2149
  };
1726
-
1727
- // packages/ui/react-ui-form/src/util/field.ts
1728
- import { FormatEnum as FormatEnum3, GeoLocation as GeoLocation2, TypeEnum } from "@dxos/echo-schema";
1729
- var parseValue = ({ type, format, value }) => {
1730
- if (value === void 0 || value === null || value === "") {
1731
- return void 0;
1732
- }
1733
- const parseScalar = (type2) => {
1734
- switch (type2) {
1735
- case TypeEnum.Boolean: {
1736
- if (typeof value === "string") {
1737
- const lowercaseValue = value.toLowerCase();
1738
- if (lowercaseValue === "0" || lowercaseValue === "false") {
1739
- return false;
1740
- } else if (lowercaseValue === "1" || lowercaseValue === "true") {
1741
- return true;
1742
- }
1743
- }
1744
- return Boolean(value);
1745
- }
1746
- case TypeEnum.Number: {
1747
- const cleaned = typeof value === "string" ? value.replace(/[^0-9.-]+/g, "") : value;
1748
- const num = Number(cleaned);
1749
- return Number.isNaN(num) ? null : num;
1750
- }
1751
- case TypeEnum.String:
1752
- case TypeEnum.Ref:
1753
- return String(value);
1754
- default: {
1755
- return value;
1756
- }
1757
- }
1758
- };
1759
- if (!format) {
1760
- return parseScalar(type);
1761
- }
1762
- switch (format) {
1763
- case FormatEnum3.Boolean:
1764
- return parseScalar(TypeEnum.Boolean);
1765
- case FormatEnum3.Number:
1766
- case FormatEnum3.Percent:
1767
- case FormatEnum3.Currency:
1768
- return parseScalar(TypeEnum.Number);
1769
- case FormatEnum3.String:
1770
- case FormatEnum3.Markdown: {
1771
- return parseScalar(TypeEnum.String);
1772
- }
1773
- case FormatEnum3.Ref:
1774
- throw new Error(`unexpected format: ${FormatEnum3.Ref}`);
1775
- case FormatEnum3.DateTime:
1776
- case FormatEnum3.Date:
1777
- case FormatEnum3.Time:
1778
- case FormatEnum3.Timestamp: {
1779
- const date = new Date(value);
1780
- return isNaN(date.getTime()) ? null : date;
1781
- }
1782
- case FormatEnum3.GeoPoint: {
1783
- if (typeof value === "string") {
1784
- const cleaned = value.replace(/[^0-9.,-]+/g, "");
1785
- const parts = cleaned.split(",");
1786
- if (parts.length === 2) {
1787
- const lat = parseFloat(parts[0]);
1788
- const long = parseFloat(parts[1]);
1789
- if (!isNaN(lat) && !isNaN(long)) {
1790
- return GeoLocation2.toGeoPoint({
1791
- latitude: lat,
1792
- longitude: long
1793
- });
1794
- }
1795
- }
1796
- }
1797
- return [
1798
- 0,
1799
- 0
1800
- ];
1801
- }
1802
- default: {
1803
- return value;
1804
- }
1805
- }
1806
- };
1807
- var cellClassesForFieldType = ({ type, format }) => {
1808
- if (!format) {
1809
- switch (type) {
1810
- case TypeEnum.Number:
1811
- return [
1812
- "text-right",
1813
- "font-mono"
1814
- ];
1815
- case TypeEnum.Boolean:
1816
- return [
1817
- "text-right",
1818
- "font-mono"
1819
- ];
1820
- case TypeEnum.String:
1821
- return void 0;
1822
- case TypeEnum.Ref:
1823
- return void 0;
1824
- default: {
1825
- return void 0;
1826
- }
1827
- }
1828
- }
1829
- switch (format) {
1830
- case FormatEnum3.Markdown:
1831
- return void 0;
1832
- case FormatEnum3.Time:
1833
- case FormatEnum3.Timestamp:
1834
- case FormatEnum3.DateTime:
1835
- case FormatEnum3.Date:
1836
- case FormatEnum3.Duration:
1837
- return [
1838
- "font-mono",
1839
- "text-right"
1840
- ];
1841
- case FormatEnum3.Currency:
1842
- return [
1843
- "text-right"
1844
- ];
1845
- case FormatEnum3.JSON:
1846
- case FormatEnum3.DID:
1847
- return [
1848
- "font-mono"
1849
- ];
1850
- default:
1851
- return void 0;
1852
- }
1853
- };
1854
- var pathNotUniqueError = (path) => ({
1855
- path: "path",
1856
- message: `'${path}' is already present`
1857
- });
1858
-
1859
- // packages/ui/react-ui-form/src/util/formatting.ts
1860
- import { format as formatDate } from "date-fns/format";
1861
- import { FormatEnum as FormatEnum4, GeoLocation as GeoLocation3, TypeEnum as TypeEnum2 } from "@dxos/echo-schema";
1862
- var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
1863
- const formatScalar = (type2) => {
1864
- switch (type2) {
1865
- case TypeEnum2.Boolean:
1866
- return value.toLocaleString().toUpperCase();
1867
- case TypeEnum2.Number:
1868
- return value.toLocaleString(locale);
1869
- case TypeEnum2.String:
1870
- case TypeEnum2.Ref:
1871
- return String(value);
1872
- default: {
1873
- return String(value);
1874
- }
1875
- }
1876
- };
1877
- if (!format) {
1878
- return formatScalar(type);
1879
- }
1880
- switch (format) {
1881
- case FormatEnum4.Boolean: {
1882
- return formatScalar(TypeEnum2.Boolean);
1883
- }
1884
- case FormatEnum4.Number: {
1885
- return formatScalar(TypeEnum2.Number);
1886
- }
1887
- case FormatEnum4.String:
1888
- case FormatEnum4.Ref: {
1889
- return formatScalar(TypeEnum2.String);
1890
- }
1891
- case FormatEnum4.Percent: {
1892
- return `${value * 100}%`;
1893
- }
1894
- case FormatEnum4.Currency: {
1895
- return value.toLocaleString(locale, {
1896
- style: "currency",
1897
- currency: "USD",
1898
- minimumFractionDigits: 2,
1899
- maximumFractionDigits: 2
1900
- });
1901
- }
1902
- case FormatEnum4.Date: {
1903
- try {
1904
- return formatDate(new Date(value), "yyyy-MM-dd");
1905
- } catch (error) {
1906
- return "Invalid Date";
1907
- }
1908
- }
1909
- case FormatEnum4.Time: {
1910
- try {
1911
- return formatDate(new Date(value), "HH:mm:ss");
1912
- } catch (error) {
1913
- return "Invalid Time";
1914
- }
1915
- }
1916
- case FormatEnum4.DateTime: {
1917
- try {
1918
- return formatDate(new Date(value), "yyyy-MM-dd HH:mm:ss");
1919
- } catch (error) {
1920
- return "Invalid DateTime";
1921
- }
1922
- }
1923
- case FormatEnum4.GeoPoint: {
1924
- if (value === null || value === void 0) {
1925
- return "";
1926
- }
1927
- if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
1928
- const { latitude, longitude } = GeoLocation3.fromGeoPoint(value);
1929
- return `${latitude},${longitude}`;
1930
- }
1931
- return String(value);
1932
- }
1933
- default: {
1934
- if (value === null || value === "undefined") {
1935
- return "";
1936
- }
1937
- return String(value);
1938
- }
1939
- }
1940
- };
1941
- var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1942
- const formatScalar = (type2) => {
1943
- switch (type2) {
1944
- case TypeEnum2.Boolean:
1945
- case TypeEnum2.Number:
1946
- case TypeEnum2.String:
1947
- case TypeEnum2.Ref:
1948
- return String(value);
1949
- default:
1950
- return String(value);
1951
- }
1952
- };
1953
- if (!format) {
1954
- return formatScalar(type);
1955
- }
1956
- switch (format) {
1957
- case FormatEnum4.Boolean:
1958
- case FormatEnum4.Number:
1959
- case FormatEnum4.String:
1960
- case FormatEnum4.Ref: {
1961
- return formatScalar(type);
1962
- }
1963
- case FormatEnum4.Percent: {
1964
- return String(value * 100);
1965
- }
1966
- case FormatEnum4.Currency: {
1967
- return String(value);
1968
- }
1969
- case FormatEnum4.DateTime: {
1970
- const date = new Date(value);
1971
- return date.toISOString();
1972
- }
1973
- case FormatEnum4.Date: {
1974
- const date = new Date(value);
1975
- return date.toISOString().split("T")[0];
1976
- }
1977
- case FormatEnum4.Time: {
1978
- const date = new Date(value);
1979
- return date.toISOString().split("T")[1].split(".")[0];
1980
- }
1981
- case FormatEnum4.GeoPoint: {
1982
- if (value === null || value === void 0) {
1983
- return "";
1984
- }
1985
- if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
1986
- const { latitude, longitude } = GeoLocation3.fromGeoPoint(value);
1987
- return `${latitude},${longitude}`;
1988
- }
1989
- return String(value);
1990
- }
1991
- default: {
1992
- return String(value);
1993
- }
1994
- }
1995
- };
1996
2150
  export {
1997
2151
  BooleanInput,
1998
2152
  ControlFrame,
@@ -2020,14 +2174,18 @@ export {
2020
2174
  ViewEditor,
2021
2175
  cellClassesForFieldType,
2022
2176
  controlItemClasses,
2177
+ findArrayElementType,
2023
2178
  formatForDisplay,
2024
2179
  formatForEditing,
2180
+ getRefProps,
2025
2181
  parseValue,
2026
2182
  pathNotUniqueError,
2027
2183
  translations_default as translations,
2028
2184
  useForm,
2029
2185
  useFormContext,
2030
2186
  useFormValues,
2031
- useInputProps
2187
+ useInputProps,
2188
+ useQueryRefOptions,
2189
+ useRefQueryLookupHandler
2032
2190
  };
2033
2191
  //# sourceMappingURL=index.mjs.map