@dxos/react-ui-form 0.8.2-main.2f9c567 → 0.8.2-main.30e4dbb
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/index.mjs +672 -543
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +564 -442
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +672 -543
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/ControlSection/ControlSection.d.ts.map +1 -1
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
- package/dist/types/src/components/Form/ArrayField.d.ts.map +1 -1
- package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.d.ts +1 -2
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormActions.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormContent.d.ts +1 -1
- package/dist/types/src/components/Form/FormContent.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormContext.d.ts.map +1 -1
- package/dist/types/src/components/Form/Input.d.ts.map +1 -1
- package/dist/types/src/components/Form/RefField.d.ts +6 -18
- package/dist/types/src/components/Form/RefField.d.ts.map +1 -1
- package/dist/types/src/components/Form/custom/GeoPointInput.d.ts.map +1 -1
- package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts.map +1 -1
- package/dist/types/src/components/Form/custom/TupleInput.d.ts.map +1 -1
- package/dist/types/src/components/Form/factory.d.ts +1 -1
- package/dist/types/src/components/Form/factory.d.ts.map +1 -1
- package/dist/types/src/components/Form/index.d.ts +0 -1
- package/dist/types/src/components/Form/index.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/Test.stories.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
- package/dist/types/src/components/deprecated/Form.d.ts.map +1 -1
- package/dist/types/src/components/deprecated/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/deprecated/FormInput.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +1 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useForm.d.ts.map +1 -1
- package/dist/types/src/hooks/useQueryRefOptions.d.ts +23 -0
- package/dist/types/src/hooks/useQueryRefOptions.d.ts.map +1 -0
- package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts +1 -1
- package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts.map +1 -1
- package/dist/types/src/util/field.d.ts.map +1 -1
- package/dist/types/src/util/formatting.d.ts.map +1 -1
- package/dist/types/src/util/index.d.ts +2 -0
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/refs.d.ts +9 -0
- package/dist/types/src/util/refs.d.ts.map +1 -0
- package/dist/types/src/util/schema.d.ts +3 -0
- package/dist/types/src/util/schema.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +25 -24
- package/src/components/ControlSection/ControlSection.stories.tsx +1 -1
- package/src/components/FieldEditor/FieldEditor.stories.tsx +1 -1
- package/src/components/Form/ArrayField.tsx +2 -2
- package/src/components/Form/Form.stories.tsx +2 -1
- package/src/components/Form/Form.tsx +1 -2
- package/src/components/Form/FormContent.tsx +44 -16
- package/src/components/Form/FormContext.tsx +3 -1
- package/src/components/Form/Input.tsx +3 -9
- package/src/components/Form/RefField.tsx +144 -99
- package/src/components/Form/custom/SelectOptionsInput.stories.tsx +1 -1
- package/src/components/Form/factory.tsx +1 -1
- package/src/components/Form/index.ts +0 -1
- package/src/components/ViewEditor/ViewEditor.stories.tsx +1 -1
- package/src/hooks/index.ts +2 -1
- package/src/hooks/useQueryRefOptions.ts +53 -0
- package/src/hooks/useRefQueryLookupHandler.ts +2 -4
- package/src/util/index.ts +3 -1
- package/src/util/refs.ts +38 -0
- 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
|
|
187
|
-
import { FormatEnum as
|
|
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.
|
|
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
|
-
}))
|
|
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
|
|
@@ -613,7 +613,7 @@ var MarkdownInput = ({ type, label, inputOnly, disabled, placeholder, getStatus,
|
|
|
613
613
|
};
|
|
614
614
|
|
|
615
615
|
// packages/ui/react-ui-form/src/components/Form/Form.tsx
|
|
616
|
-
import React13, { useEffect as useEffect7, useMemo as
|
|
616
|
+
import React13, { useEffect as useEffect7, useMemo as useMemo7, useRef as useRef3 } from "react";
|
|
617
617
|
import { mx as mx8 } from "@dxos/react-ui-theme";
|
|
618
618
|
|
|
619
619
|
// packages/ui/react-ui-form/src/components/Form/FormActions.tsx
|
|
@@ -622,7 +622,7 @@ import { IconButton as IconButton2, useTranslation as useTranslation4 } from "@d
|
|
|
622
622
|
import { mx as mx5 } from "@dxos/react-ui-theme";
|
|
623
623
|
|
|
624
624
|
// packages/ui/react-ui-form/src/components/Form/FormContext.tsx
|
|
625
|
-
import React8, { createContext, useContext, useEffect as
|
|
625
|
+
import React8, { createContext, useContext, useEffect as useEffect6, useMemo as useMemo3 } from "react";
|
|
626
626
|
import { raise } from "@dxos/debug";
|
|
627
627
|
import { getValue as getValue2 } from "@dxos/echo-schema";
|
|
628
628
|
import { createJsonPath as createJsonPath2 } from "@dxos/effect";
|
|
@@ -865,6 +865,52 @@ var useRefQueryLookupHandler = ({ space }) => {
|
|
|
865
865
|
return handleRefQueryLookup;
|
|
866
866
|
};
|
|
867
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
|
+
|
|
868
914
|
// packages/ui/react-ui-form/src/components/Form/FormContext.tsx
|
|
869
915
|
var FormContext = /* @__PURE__ */ createContext(void 0);
|
|
870
916
|
var useFormContext = () => {
|
|
@@ -895,7 +941,7 @@ var useInputProps = (path = []) => {
|
|
|
895
941
|
};
|
|
896
942
|
var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
|
|
897
943
|
const form = useForm(formOptions);
|
|
898
|
-
|
|
944
|
+
useEffect6(() => {
|
|
899
945
|
if (!formRef?.current) {
|
|
900
946
|
return;
|
|
901
947
|
}
|
|
@@ -903,7 +949,7 @@ var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
|
|
|
903
949
|
const keyIsEnter = event.key === "Enter";
|
|
904
950
|
const modifierUsed = event.ctrlKey || event.altKey || event.metaKey || event.shiftKey;
|
|
905
951
|
const inputIsTextarea = event.target.tagName.toLowerCase() === "textarea";
|
|
906
|
-
const inputOptOut = event.target.hasAttribute("data-no-submit");
|
|
952
|
+
const inputOptOut = event.target.hasAttribute("data-no-submit") || event.target.closest("[data-no-submit]") !== null;
|
|
907
953
|
const shouldSubmitRegularInput = !inputIsTextarea && keyIsEnter && !modifierUsed;
|
|
908
954
|
const shouldSubmitTextarea = inputIsTextarea && keyIsEnter && event.metaKey;
|
|
909
955
|
if ((shouldSubmitRegularInput || shouldSubmitTextarea) && !inputOptOut) {
|
|
@@ -956,258 +1002,605 @@ var FormActions = ({ onCancel, readonly }) => {
|
|
|
956
1002
|
};
|
|
957
1003
|
|
|
958
1004
|
// packages/ui/react-ui-form/src/components/Form/FormContent.tsx
|
|
959
|
-
import { Schema, SchemaAST as
|
|
1005
|
+
import { Schema, SchemaAST as SchemaAST4, pipe as pipe2 } from "effect";
|
|
960
1006
|
import { capitalize as capitalize2 } from "effect/String";
|
|
961
|
-
import React12, { useMemo as
|
|
962
|
-
import { createJsonPath as createJsonPath3, findNode as
|
|
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";
|
|
963
1009
|
import { mx as mx7 } from "@dxos/react-ui-theme";
|
|
964
1010
|
import { getSchemaProperties as getSchemaProperties2 } from "@dxos/schema";
|
|
965
1011
|
import { isNotFalsy } from "@dxos/util";
|
|
966
1012
|
|
|
967
1013
|
// packages/ui/react-ui-form/src/components/Form/ArrayField.tsx
|
|
968
|
-
import { SchemaAST as
|
|
1014
|
+
import { SchemaAST as SchemaAST3, pipe } from "effect";
|
|
969
1015
|
import { capitalize } from "effect/String";
|
|
970
1016
|
import React10, { useCallback as useCallback6, useMemo as useMemo4 } from "react";
|
|
971
|
-
import { findNode, getDiscriminatedType, isDiscriminatedUnion, SimpleType } from "@dxos/effect";
|
|
1017
|
+
import { findNode as findNode2, getDiscriminatedType, isDiscriminatedUnion, SimpleType } from "@dxos/effect";
|
|
972
1018
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
973
1019
|
import { IconButton as IconButton3, useTranslation as useTranslation5 } from "@dxos/react-ui";
|
|
974
1020
|
import { mx as mx6 } from "@dxos/react-ui-theme";
|
|
975
1021
|
import { getSchemaProperties } from "@dxos/schema";
|
|
976
|
-
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/Form/ArrayField.tsx";
|
|
977
|
-
var padding = "px-2";
|
|
978
|
-
var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponent }) => {
|
|
979
|
-
const { t } = useTranslation5(translationKey);
|
|
980
|
-
const { ast, name, type, title } = property;
|
|
981
|
-
const values = useFormValues(path ?? []) ?? [];
|
|
982
|
-
invariant2(Array.isArray(values), `Values at path ${path?.join(".")} must be an array.`, {
|
|
983
|
-
F: __dxlog_file2,
|
|
984
|
-
L: 38,
|
|
985
|
-
S: void 0,
|
|
986
|
-
A: [
|
|
987
|
-
"Array.isArray(values)",
|
|
988
|
-
"`Values at path ${path?.join('.')} must be an array.`"
|
|
989
|
-
]
|
|
990
|
-
});
|
|
991
|
-
const label = title ?? pipe(name, capitalize);
|
|
992
|
-
const tupleType = findNode(ast, SchemaAST2.isTupleType);
|
|
993
|
-
const elementType = tupleType?.rest[0]?.type;
|
|
994
|
-
const getDefaultObjectValue = (typeNode) => {
|
|
995
|
-
const baseNode = findNode(typeNode, isDiscriminatedUnion);
|
|
996
|
-
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, {}) : findNode(typeNode, SchemaAST2.isTypeLiteral);
|
|
997
|
-
if (!typeLiteral) {
|
|
998
|
-
return {};
|
|
999
|
-
}
|
|
1000
|
-
return Object.fromEntries(getSchemaProperties(typeLiteral, {}).map((prop) => [
|
|
1001
|
-
prop.name,
|
|
1002
|
-
prop.defaultValue
|
|
1003
|
-
]));
|
|
1004
|
-
};
|
|
1005
|
-
const newValue = useMemo4(() => {
|
|
1006
|
-
if (type === "object" && elementType) {
|
|
1007
|
-
return getDefaultObjectValue(elementType);
|
|
1008
|
-
} else {
|
|
1009
|
-
return SimpleType.getDefaultValue(type);
|
|
1010
|
-
}
|
|
1011
|
-
}, [
|
|
1012
|
-
type,
|
|
1013
|
-
elementType
|
|
1014
|
-
]);
|
|
1015
|
-
const handleAdd = useCallback6(() => {
|
|
1016
|
-
inputProps.onValueChange(type, [
|
|
1017
|
-
...values,
|
|
1018
|
-
newValue
|
|
1019
|
-
]);
|
|
1020
|
-
}, [
|
|
1021
|
-
type,
|
|
1022
|
-
elementType,
|
|
1023
|
-
inputProps,
|
|
1024
|
-
newValue,
|
|
1025
|
-
values
|
|
1026
|
-
]);
|
|
1027
|
-
const handleRemove = useCallback6((index) => {
|
|
1028
|
-
const newValues = values.filter((_, i) => i !== index);
|
|
1029
|
-
inputProps.onValueChange(type, newValues);
|
|
1030
|
-
}, [
|
|
1031
|
-
type,
|
|
1032
|
-
inputProps,
|
|
1033
|
-
values
|
|
1034
|
-
]);
|
|
1035
|
-
if (!elementType) {
|
|
1036
|
-
return null;
|
|
1037
|
-
}
|
|
1038
|
-
return /* @__PURE__ */ React10.createElement("div", {
|
|
1039
|
-
role: "none",
|
|
1040
|
-
className: mx6(padding)
|
|
1041
|
-
}, /* @__PURE__ */ React10.createElement(InputHeader, null, label), /* @__PURE__ */ React10.createElement("div", {
|
|
1042
|
-
role: "none",
|
|
1043
|
-
className: "flex flex-col gap-1"
|
|
1044
|
-
}, values.map((_value, index) => /* @__PURE__ */ React10.createElement("div", {
|
|
1045
|
-
key: index,
|
|
1046
|
-
role: "none",
|
|
1047
|
-
className: "flex items-center gap-1"
|
|
1048
|
-
}, /* @__PURE__ */ React10.createElement("div", {
|
|
1049
|
-
role: "none",
|
|
1050
|
-
className: "flex-1"
|
|
1051
|
-
}, /* @__PURE__ */ React10.createElement(FormField, {
|
|
1052
|
-
property: {
|
|
1053
|
-
...property,
|
|
1054
|
-
array: false,
|
|
1055
|
-
ast: elementType
|
|
1056
|
-
},
|
|
1057
|
-
path: [
|
|
1058
|
-
...path ?? [],
|
|
1059
|
-
index
|
|
1060
|
-
],
|
|
1061
|
-
readonly,
|
|
1062
|
-
inline: true,
|
|
1063
|
-
Custom,
|
|
1064
|
-
lookupComponent
|
|
1065
|
-
})), /* @__PURE__ */ React10.createElement(IconButton3, {
|
|
1066
|
-
icon: "ph--trash--regular",
|
|
1067
|
-
iconOnly: true,
|
|
1068
|
-
label: t("button remove"),
|
|
1069
|
-
onClick: () => handleRemove(index)
|
|
1070
|
-
})))), /* @__PURE__ */ React10.createElement("div", {
|
|
1071
|
-
role: "none",
|
|
1072
|
-
className: "flex justify-between items-center plb-1"
|
|
1073
|
-
}, /* @__PURE__ */ React10.createElement(IconButton3, {
|
|
1074
|
-
icon: "ph--plus--regular",
|
|
1075
|
-
iconOnly: true,
|
|
1076
|
-
label: t("button add"),
|
|
1077
|
-
onClick: handleAdd
|
|
1078
|
-
})));
|
|
1079
|
-
};
|
|
1080
1022
|
|
|
1081
|
-
// packages/ui/react-ui-form/src/
|
|
1082
|
-
import
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
import { refFromDXN } from "@dxos/live-object";
|
|
1087
|
-
import { log as log2 } from "@dxos/log";
|
|
1088
|
-
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/Form/RefField.tsx";
|
|
1089
|
-
var RefField = ({ ast, type, label, readonly, placeholder, inline, onQueryRefOptions, inputProps }) => {
|
|
1090
|
-
const { getValue: getValue3, onValueChange, ...restInputProps } = inputProps;
|
|
1091
|
-
const refTypeInfo = findAnnotation(ast, ReferenceAnnotationId);
|
|
1092
|
-
const [refOptions, setRefOptions] = useState4([]);
|
|
1093
|
-
const [loading, setLoading] = useState4(false);
|
|
1094
|
-
useEffect6(() => {
|
|
1095
|
-
if (!refTypeInfo || !onQueryRefOptions) {
|
|
1096
|
-
return;
|
|
1097
|
-
}
|
|
1098
|
-
const fetchOptions = async () => {
|
|
1099
|
-
setLoading(true);
|
|
1100
|
-
try {
|
|
1101
|
-
const options = await onQueryRefOptions(refTypeInfo);
|
|
1102
|
-
setRefOptions(options.map((option) => ({
|
|
1103
|
-
label: option.label,
|
|
1104
|
-
value: option.dxn.toString()
|
|
1105
|
-
})));
|
|
1106
|
-
} catch (error) {
|
|
1107
|
-
log2.error("Failed to fetch ref options:", error, {
|
|
1108
|
-
F: __dxlog_file3,
|
|
1109
|
-
L: 69,
|
|
1110
|
-
S: void 0,
|
|
1111
|
-
C: (f, a) => f(...a)
|
|
1112
|
-
});
|
|
1113
|
-
setRefOptions([]);
|
|
1114
|
-
} finally {
|
|
1115
|
-
setLoading(false);
|
|
1116
|
-
}
|
|
1117
|
-
};
|
|
1118
|
-
void fetchOptions();
|
|
1119
|
-
}, [
|
|
1120
|
-
refTypeInfo,
|
|
1121
|
-
onQueryRefOptions
|
|
1122
|
-
]);
|
|
1123
|
-
if (!refTypeInfo) {
|
|
1124
|
-
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;
|
|
1125
1028
|
}
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
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);
|
|
1135
1041
|
}
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
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;
|
|
1141
1046
|
}
|
|
1142
|
-
|
|
1143
|
-
|
|
1047
|
+
case TypeEnum.String:
|
|
1048
|
+
case TypeEnum.Ref:
|
|
1049
|
+
return String(value);
|
|
1050
|
+
default: {
|
|
1051
|
+
return value;
|
|
1144
1052
|
}
|
|
1145
|
-
return void 0;
|
|
1146
|
-
};
|
|
1147
|
-
return /* @__PURE__ */ React11.createElement(TextInput, {
|
|
1148
|
-
type,
|
|
1149
|
-
label,
|
|
1150
|
-
disabled: readonly,
|
|
1151
|
-
placeholder,
|
|
1152
|
-
inputOnly: inline,
|
|
1153
|
-
getValue: handleGetValue2,
|
|
1154
|
-
onValueChange: handleOnValueChange,
|
|
1155
|
-
...restInputProps
|
|
1156
|
-
});
|
|
1157
|
-
}
|
|
1158
|
-
const handleGetValue = () => {
|
|
1159
|
-
const formValue = getValue3();
|
|
1160
|
-
if (Ref.isRef(formValue)) {
|
|
1161
|
-
return formValue.dxn.toString();
|
|
1162
1053
|
}
|
|
1163
|
-
return void 0;
|
|
1164
1054
|
};
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
const ref = refFromDXN(dxn);
|
|
1168
|
-
onValueChange("object", ref);
|
|
1169
|
-
};
|
|
1170
|
-
return /* @__PURE__ */ React11.createElement(SelectInput, {
|
|
1171
|
-
type,
|
|
1172
|
-
label,
|
|
1173
|
-
disabled: readonly || loading,
|
|
1174
|
-
placeholder: loading ? "Loading options..." : placeholder,
|
|
1175
|
-
inputOnly: inline,
|
|
1176
|
-
getValue: handleGetValue,
|
|
1177
|
-
onValueChange: handleValueChanged,
|
|
1178
|
-
options: refOptions,
|
|
1179
|
-
...restInputProps
|
|
1180
|
-
});
|
|
1181
|
-
};
|
|
1182
|
-
|
|
1183
|
-
// packages/ui/react-ui-form/src/components/Form/factory.tsx
|
|
1184
|
-
import { FormatEnum } from "@dxos/echo-schema";
|
|
1185
|
-
var getInputComponent = (type, format) => {
|
|
1186
|
-
switch (format) {
|
|
1187
|
-
case FormatEnum.GeoPoint:
|
|
1188
|
-
return GeoPointInput;
|
|
1189
|
-
case FormatEnum.Markdown:
|
|
1190
|
-
return MarkdownInput;
|
|
1055
|
+
if (!format) {
|
|
1056
|
+
return parseScalar(type);
|
|
1191
1057
|
}
|
|
1192
|
-
switch (
|
|
1193
|
-
case
|
|
1194
|
-
return
|
|
1195
|
-
case
|
|
1196
|
-
|
|
1197
|
-
case
|
|
1198
|
-
return
|
|
1058
|
+
switch (format) {
|
|
1059
|
+
case FormatEnum.Boolean:
|
|
1060
|
+
return parseScalar(TypeEnum.Boolean);
|
|
1061
|
+
case FormatEnum.Number:
|
|
1062
|
+
case FormatEnum.Percent:
|
|
1063
|
+
case FormatEnum.Currency:
|
|
1064
|
+
return parseScalar(TypeEnum.Number);
|
|
1065
|
+
case FormatEnum.String:
|
|
1066
|
+
case FormatEnum.Markdown: {
|
|
1067
|
+
return parseScalar(TypeEnum.String);
|
|
1068
|
+
}
|
|
1069
|
+
case FormatEnum.Ref:
|
|
1070
|
+
throw new Error(`unexpected format: ${FormatEnum.Ref}`);
|
|
1071
|
+
case FormatEnum.DateTime:
|
|
1072
|
+
case FormatEnum.Date:
|
|
1073
|
+
case FormatEnum.Time:
|
|
1074
|
+
case FormatEnum.Timestamp: {
|
|
1075
|
+
const date = new Date(value);
|
|
1076
|
+
return isNaN(date.getTime()) ? null : date;
|
|
1077
|
+
}
|
|
1078
|
+
case FormatEnum.GeoPoint: {
|
|
1079
|
+
if (typeof value === "string") {
|
|
1080
|
+
const cleaned = value.replace(/[^0-9.,-]+/g, "");
|
|
1081
|
+
const parts = cleaned.split(",");
|
|
1082
|
+
if (parts.length === 2) {
|
|
1083
|
+
const lat = parseFloat(parts[0]);
|
|
1084
|
+
const long = parseFloat(parts[1]);
|
|
1085
|
+
if (!isNaN(lat) && !isNaN(long)) {
|
|
1086
|
+
return GeoLocation2.toGeoPoint({
|
|
1087
|
+
latitude: lat,
|
|
1088
|
+
longitude: long
|
|
1089
|
+
});
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
return [
|
|
1094
|
+
0,
|
|
1095
|
+
0
|
|
1096
|
+
];
|
|
1097
|
+
}
|
|
1098
|
+
default: {
|
|
1099
|
+
return value;
|
|
1100
|
+
}
|
|
1199
1101
|
}
|
|
1200
1102
|
};
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
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":
|
|
1587
|
+
return TextInput;
|
|
1588
|
+
case "number":
|
|
1589
|
+
return NumberInput;
|
|
1590
|
+
case "boolean":
|
|
1591
|
+
return BooleanInput;
|
|
1592
|
+
}
|
|
1593
|
+
};
|
|
1594
|
+
|
|
1595
|
+
// packages/ui/react-ui-form/src/components/Form/FormContent.tsx
|
|
1596
|
+
var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupComponent, Custom }) => {
|
|
1204
1597
|
const inputProps = useInputProps(path);
|
|
1205
1598
|
const { ast, name, type, format, title, description, options, examples, array } = property;
|
|
1206
|
-
const label =
|
|
1599
|
+
const label = useMemo6(() => title ?? pipe2(name, capitalize2), [
|
|
1207
1600
|
title,
|
|
1208
1601
|
name
|
|
1209
1602
|
]);
|
|
1210
|
-
const placeholder =
|
|
1603
|
+
const placeholder = useMemo6(() => examples?.length ? `Example: "${examples[0]}"` : description, [
|
|
1211
1604
|
examples,
|
|
1212
1605
|
description
|
|
1213
1606
|
]);
|
|
@@ -1241,6 +1634,21 @@ var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupCo
|
|
|
1241
1634
|
...inputProps
|
|
1242
1635
|
});
|
|
1243
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
|
+
}
|
|
1244
1652
|
if (array) {
|
|
1245
1653
|
return /* @__PURE__ */ React12.createElement(ArrayField, {
|
|
1246
1654
|
property,
|
|
@@ -1281,21 +1689,9 @@ var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupCo
|
|
|
1281
1689
|
...inputProps
|
|
1282
1690
|
}));
|
|
1283
1691
|
}
|
|
1284
|
-
if (format === "ref") {
|
|
1285
|
-
return /* @__PURE__ */ React12.createElement(RefField, {
|
|
1286
|
-
ast,
|
|
1287
|
-
type,
|
|
1288
|
-
label,
|
|
1289
|
-
readonly,
|
|
1290
|
-
placeholder,
|
|
1291
|
-
inline,
|
|
1292
|
-
onQueryRefOptions,
|
|
1293
|
-
inputProps
|
|
1294
|
-
});
|
|
1295
|
-
}
|
|
1296
1692
|
if (type === "object") {
|
|
1297
|
-
const baseNode =
|
|
1298
|
-
const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, inputProps.getValue()) :
|
|
1693
|
+
const baseNode = findNode3(ast, isDiscriminatedUnion2);
|
|
1694
|
+
const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, inputProps.getValue()) : findNode3(ast, SchemaAST4.isTypeLiteral);
|
|
1299
1695
|
if (typeLiteral) {
|
|
1300
1696
|
return /* @__PURE__ */ React12.createElement("div", {
|
|
1301
1697
|
role: "none"
|
|
@@ -1315,7 +1711,7 @@ var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupCo
|
|
|
1315
1711
|
};
|
|
1316
1712
|
var FormFields = ({ schema, path, filter, sort, readonly, onQueryRefOptions, lookupComponent, Custom }) => {
|
|
1317
1713
|
const values = useFormValues(path);
|
|
1318
|
-
const properties =
|
|
1714
|
+
const properties = useMemo6(() => {
|
|
1319
1715
|
const props = getSchemaProperties2(schema.ast, values);
|
|
1320
1716
|
const filtered = filter ? filter(props) : props;
|
|
1321
1717
|
return sort ? filtered.sort((a, b) => sort.indexOf(a.name) - sort.indexOf(b.name)) : filtered;
|
|
@@ -1347,7 +1743,7 @@ var FormFields = ({ schema, path, filter, sort, readonly, onQueryRefOptions, loo
|
|
|
1347
1743
|
// packages/ui/react-ui-form/src/components/Form/Form.tsx
|
|
1348
1744
|
var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, onQueryRefOptions, lookupComponent, Custom }) => {
|
|
1349
1745
|
const formRef = useRef3(null);
|
|
1350
|
-
const onValid =
|
|
1746
|
+
const onValid = useMemo7(() => autoSave ? onSave : void 0, [
|
|
1351
1747
|
autoSave,
|
|
1352
1748
|
onSave
|
|
1353
1749
|
]);
|
|
@@ -1428,7 +1824,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
1428
1824
|
const [{ fieldSchema }, setFieldSchema] = useState5({
|
|
1429
1825
|
fieldSchema: getFormatSchema(props?.format)
|
|
1430
1826
|
});
|
|
1431
|
-
const handleValuesChanged =
|
|
1827
|
+
const handleValuesChanged = useCallback8((_props) => {
|
|
1432
1828
|
setFieldSchema((prev) => {
|
|
1433
1829
|
const fieldSchema2 = getFormatSchema(_props.format);
|
|
1434
1830
|
if (prev.fieldSchema === fieldSchema2) {
|
|
@@ -1463,7 +1859,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
1463
1859
|
props.format,
|
|
1464
1860
|
props.referenceSchema
|
|
1465
1861
|
]);
|
|
1466
|
-
const handleValidate =
|
|
1862
|
+
const handleValidate = useCallback8(({ property }) => {
|
|
1467
1863
|
if (property && view.fields.find((f) => f.path === property && f.path !== field.path)) {
|
|
1468
1864
|
return [
|
|
1469
1865
|
{
|
|
@@ -1476,7 +1872,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
1476
1872
|
view.fields,
|
|
1477
1873
|
field
|
|
1478
1874
|
]);
|
|
1479
|
-
const handleSave =
|
|
1875
|
+
const handleSave = useCallback8((props2) => {
|
|
1480
1876
|
projection.setFieldProjection({
|
|
1481
1877
|
field,
|
|
1482
1878
|
props: props2
|
|
@@ -1487,16 +1883,16 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
1487
1883
|
field,
|
|
1488
1884
|
onSave
|
|
1489
1885
|
]);
|
|
1490
|
-
const handleCancel =
|
|
1886
|
+
const handleCancel = useCallback8(() => {
|
|
1491
1887
|
requestAnimationFrame(() => onCancel?.());
|
|
1492
1888
|
onSave();
|
|
1493
1889
|
}, [
|
|
1494
1890
|
onSave
|
|
1495
1891
|
]);
|
|
1496
|
-
const Custom =
|
|
1892
|
+
const Custom = useMemo8(() => ({
|
|
1497
1893
|
["format"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
|
|
1498
1894
|
...props2,
|
|
1499
|
-
options: FormatEnums.filter((value) => value !==
|
|
1895
|
+
options: FormatEnums.filter((value) => value !== FormatEnum5.None).map((value) => ({
|
|
1500
1896
|
value,
|
|
1501
1897
|
label: t(`format ${value}`)
|
|
1502
1898
|
}))
|
|
@@ -1519,7 +1915,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
1519
1915
|
schemas,
|
|
1520
1916
|
referenceSchema
|
|
1521
1917
|
]);
|
|
1522
|
-
const propIsNotType =
|
|
1918
|
+
const propIsNotType = useCallback8((props2) => props2.filter((p) => p.name !== "type"), []);
|
|
1523
1919
|
if (!fieldSchema) {
|
|
1524
1920
|
log3.warn("invalid format", {
|
|
1525
1921
|
props
|
|
@@ -1550,8 +1946,8 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
1550
1946
|
};
|
|
1551
1947
|
|
|
1552
1948
|
// packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx
|
|
1553
|
-
import { Schema as Schema2, SchemaAST as
|
|
1554
|
-
import React15, { useCallback as
|
|
1949
|
+
import { Schema as Schema2, SchemaAST as SchemaAST5 } from "effect";
|
|
1950
|
+
import React15, { useCallback as useCallback9, useMemo as useMemo9, useState as useState6 } from "react";
|
|
1555
1951
|
import { Format } from "@dxos/echo-schema";
|
|
1556
1952
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
1557
1953
|
import { IconButton as IconButton4, useTranslation as useTranslation7 } from "@dxos/react-ui";
|
|
@@ -1562,20 +1958,20 @@ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/c
|
|
|
1562
1958
|
var grid = "grid grid-cols-[32px_1fr_32px] min-bs-[2.5rem]";
|
|
1563
1959
|
var ViewMetaSchema = Schema2.Struct({
|
|
1564
1960
|
name: Schema2.String.annotations({
|
|
1565
|
-
[
|
|
1961
|
+
[SchemaAST5.TitleAnnotationId]: "View"
|
|
1566
1962
|
}),
|
|
1567
1963
|
typename: Format.URL.annotations({
|
|
1568
|
-
[
|
|
1964
|
+
[SchemaAST5.TitleAnnotationId]: "Typename"
|
|
1569
1965
|
})
|
|
1570
1966
|
}).pipe(Schema2.mutable);
|
|
1571
1967
|
var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading = false, onTypenameChanged, onDelete }) => {
|
|
1572
1968
|
const { t } = useTranslation7(translationKey);
|
|
1573
|
-
const projection =
|
|
1969
|
+
const projection = useMemo9(() => new ViewProjection(schema.jsonSchema, view), [
|
|
1574
1970
|
schema,
|
|
1575
1971
|
view
|
|
1576
1972
|
]);
|
|
1577
1973
|
const [field, setField] = useState6();
|
|
1578
|
-
const viewValues =
|
|
1974
|
+
const viewValues = useMemo9(() => {
|
|
1579
1975
|
return {
|
|
1580
1976
|
name: view.name,
|
|
1581
1977
|
// TODO(burdon): Need to warn user of possible consequences of editing.
|
|
@@ -1585,10 +1981,10 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
1585
1981
|
}, [
|
|
1586
1982
|
view
|
|
1587
1983
|
]);
|
|
1588
|
-
const handleSelect =
|
|
1984
|
+
const handleSelect = useCallback9((field2) => {
|
|
1589
1985
|
setField((f) => f === field2 ? void 0 : field2);
|
|
1590
1986
|
}, []);
|
|
1591
|
-
const handleAdd =
|
|
1987
|
+
const handleAdd = useCallback9(() => {
|
|
1592
1988
|
invariant3(!schema.readonly, void 0, {
|
|
1593
1989
|
F: __dxlog_file5,
|
|
1594
1990
|
L: 77,
|
|
@@ -1604,7 +2000,7 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
1604
2000
|
schema,
|
|
1605
2001
|
view
|
|
1606
2002
|
]);
|
|
1607
|
-
const handleUpdate =
|
|
2003
|
+
const handleUpdate = useCallback9(({ name, typename }) => {
|
|
1608
2004
|
invariant3(!schema.readonly, void 0, {
|
|
1609
2005
|
F: __dxlog_file5,
|
|
1610
2006
|
L: 84,
|
|
@@ -1627,7 +2023,7 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
1627
2023
|
view,
|
|
1628
2024
|
onTypenameChanged
|
|
1629
2025
|
]);
|
|
1630
|
-
const handleDelete =
|
|
2026
|
+
const handleDelete = useCallback9((fieldId) => {
|
|
1631
2027
|
invariant3(!schema.readonly, void 0, {
|
|
1632
2028
|
F: __dxlog_file5,
|
|
1633
2029
|
L: 100,
|
|
@@ -1646,7 +2042,7 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
1646
2042
|
field,
|
|
1647
2043
|
onDelete
|
|
1648
2044
|
]);
|
|
1649
|
-
const handleMove =
|
|
2045
|
+
const handleMove = useCallback9((fromIndex, toIndex) => {
|
|
1650
2046
|
invariant3(!schema.readonly, void 0, {
|
|
1651
2047
|
F: __dxlog_file5,
|
|
1652
2048
|
L: 112,
|
|
@@ -1666,15 +2062,15 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
1666
2062
|
schema,
|
|
1667
2063
|
view.fields
|
|
1668
2064
|
]);
|
|
1669
|
-
const handleClose =
|
|
2065
|
+
const handleClose = useCallback9(() => setField(void 0), []);
|
|
1670
2066
|
const hiddenProperties = projection.getHiddenProperties();
|
|
1671
|
-
const handleHide =
|
|
2067
|
+
const handleHide = useCallback9((fieldId) => {
|
|
1672
2068
|
setField(void 0);
|
|
1673
2069
|
projection.hideFieldProjection(fieldId);
|
|
1674
2070
|
}, [
|
|
1675
2071
|
projection
|
|
1676
2072
|
]);
|
|
1677
|
-
const handleShow =
|
|
2073
|
+
const handleShow = useCallback9((property) => {
|
|
1678
2074
|
setField(void 0);
|
|
1679
2075
|
projection.showFieldProjection(property);
|
|
1680
2076
|
}, [
|
|
@@ -1762,276 +2158,6 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
1762
2158
|
disabled: view.fields.length >= VIEW_FIELD_LIMIT
|
|
1763
2159
|
})));
|
|
1764
2160
|
};
|
|
1765
|
-
|
|
1766
|
-
// packages/ui/react-ui-form/src/util/field.ts
|
|
1767
|
-
import { FormatEnum as FormatEnum3, GeoLocation as GeoLocation2, TypeEnum } from "@dxos/echo-schema";
|
|
1768
|
-
var parseValue = ({ type, format, value }) => {
|
|
1769
|
-
if (value === void 0 || value === null || value === "") {
|
|
1770
|
-
return void 0;
|
|
1771
|
-
}
|
|
1772
|
-
const parseScalar = (type2) => {
|
|
1773
|
-
switch (type2) {
|
|
1774
|
-
case TypeEnum.Boolean: {
|
|
1775
|
-
if (typeof value === "string") {
|
|
1776
|
-
const lowercaseValue = value.toLowerCase();
|
|
1777
|
-
if (lowercaseValue === "0" || lowercaseValue === "false") {
|
|
1778
|
-
return false;
|
|
1779
|
-
} else if (lowercaseValue === "1" || lowercaseValue === "true") {
|
|
1780
|
-
return true;
|
|
1781
|
-
}
|
|
1782
|
-
}
|
|
1783
|
-
return Boolean(value);
|
|
1784
|
-
}
|
|
1785
|
-
case TypeEnum.Number: {
|
|
1786
|
-
const cleaned = typeof value === "string" ? value.replace(/[^0-9.-]+/g, "") : value;
|
|
1787
|
-
const num = Number(cleaned);
|
|
1788
|
-
return Number.isNaN(num) ? null : num;
|
|
1789
|
-
}
|
|
1790
|
-
case TypeEnum.String:
|
|
1791
|
-
case TypeEnum.Ref:
|
|
1792
|
-
return String(value);
|
|
1793
|
-
default: {
|
|
1794
|
-
return value;
|
|
1795
|
-
}
|
|
1796
|
-
}
|
|
1797
|
-
};
|
|
1798
|
-
if (!format) {
|
|
1799
|
-
return parseScalar(type);
|
|
1800
|
-
}
|
|
1801
|
-
switch (format) {
|
|
1802
|
-
case FormatEnum3.Boolean:
|
|
1803
|
-
return parseScalar(TypeEnum.Boolean);
|
|
1804
|
-
case FormatEnum3.Number:
|
|
1805
|
-
case FormatEnum3.Percent:
|
|
1806
|
-
case FormatEnum3.Currency:
|
|
1807
|
-
return parseScalar(TypeEnum.Number);
|
|
1808
|
-
case FormatEnum3.String:
|
|
1809
|
-
case FormatEnum3.Markdown: {
|
|
1810
|
-
return parseScalar(TypeEnum.String);
|
|
1811
|
-
}
|
|
1812
|
-
case FormatEnum3.Ref:
|
|
1813
|
-
throw new Error(`unexpected format: ${FormatEnum3.Ref}`);
|
|
1814
|
-
case FormatEnum3.DateTime:
|
|
1815
|
-
case FormatEnum3.Date:
|
|
1816
|
-
case FormatEnum3.Time:
|
|
1817
|
-
case FormatEnum3.Timestamp: {
|
|
1818
|
-
const date = new Date(value);
|
|
1819
|
-
return isNaN(date.getTime()) ? null : date;
|
|
1820
|
-
}
|
|
1821
|
-
case FormatEnum3.GeoPoint: {
|
|
1822
|
-
if (typeof value === "string") {
|
|
1823
|
-
const cleaned = value.replace(/[^0-9.,-]+/g, "");
|
|
1824
|
-
const parts = cleaned.split(",");
|
|
1825
|
-
if (parts.length === 2) {
|
|
1826
|
-
const lat = parseFloat(parts[0]);
|
|
1827
|
-
const long = parseFloat(parts[1]);
|
|
1828
|
-
if (!isNaN(lat) && !isNaN(long)) {
|
|
1829
|
-
return GeoLocation2.toGeoPoint({
|
|
1830
|
-
latitude: lat,
|
|
1831
|
-
longitude: long
|
|
1832
|
-
});
|
|
1833
|
-
}
|
|
1834
|
-
}
|
|
1835
|
-
}
|
|
1836
|
-
return [
|
|
1837
|
-
0,
|
|
1838
|
-
0
|
|
1839
|
-
];
|
|
1840
|
-
}
|
|
1841
|
-
default: {
|
|
1842
|
-
return value;
|
|
1843
|
-
}
|
|
1844
|
-
}
|
|
1845
|
-
};
|
|
1846
|
-
var cellClassesForFieldType = ({ type, format }) => {
|
|
1847
|
-
if (!format) {
|
|
1848
|
-
switch (type) {
|
|
1849
|
-
case TypeEnum.Number:
|
|
1850
|
-
return [
|
|
1851
|
-
"text-right",
|
|
1852
|
-
"font-mono"
|
|
1853
|
-
];
|
|
1854
|
-
case TypeEnum.Boolean:
|
|
1855
|
-
return [
|
|
1856
|
-
"text-right",
|
|
1857
|
-
"font-mono"
|
|
1858
|
-
];
|
|
1859
|
-
case TypeEnum.String:
|
|
1860
|
-
return void 0;
|
|
1861
|
-
case TypeEnum.Ref:
|
|
1862
|
-
return void 0;
|
|
1863
|
-
default: {
|
|
1864
|
-
return void 0;
|
|
1865
|
-
}
|
|
1866
|
-
}
|
|
1867
|
-
}
|
|
1868
|
-
switch (format) {
|
|
1869
|
-
case FormatEnum3.Markdown:
|
|
1870
|
-
return void 0;
|
|
1871
|
-
case FormatEnum3.Time:
|
|
1872
|
-
case FormatEnum3.Timestamp:
|
|
1873
|
-
case FormatEnum3.DateTime:
|
|
1874
|
-
case FormatEnum3.Date:
|
|
1875
|
-
case FormatEnum3.Duration:
|
|
1876
|
-
return [
|
|
1877
|
-
"font-mono",
|
|
1878
|
-
"text-right"
|
|
1879
|
-
];
|
|
1880
|
-
case FormatEnum3.Currency:
|
|
1881
|
-
return [
|
|
1882
|
-
"text-right"
|
|
1883
|
-
];
|
|
1884
|
-
case FormatEnum3.JSON:
|
|
1885
|
-
case FormatEnum3.DID:
|
|
1886
|
-
return [
|
|
1887
|
-
"font-mono"
|
|
1888
|
-
];
|
|
1889
|
-
default:
|
|
1890
|
-
return void 0;
|
|
1891
|
-
}
|
|
1892
|
-
};
|
|
1893
|
-
var pathNotUniqueError = (path) => ({
|
|
1894
|
-
path: "path",
|
|
1895
|
-
message: `'${path}' is already present`
|
|
1896
|
-
});
|
|
1897
|
-
|
|
1898
|
-
// packages/ui/react-ui-form/src/util/formatting.ts
|
|
1899
|
-
import { format as formatDate } from "date-fns/format";
|
|
1900
|
-
import { FormatEnum as FormatEnum4, GeoLocation as GeoLocation3, TypeEnum as TypeEnum2 } from "@dxos/echo-schema";
|
|
1901
|
-
var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
|
|
1902
|
-
const formatScalar = (type2) => {
|
|
1903
|
-
switch (type2) {
|
|
1904
|
-
case TypeEnum2.Boolean:
|
|
1905
|
-
return value.toLocaleString().toUpperCase();
|
|
1906
|
-
case TypeEnum2.Number:
|
|
1907
|
-
return value.toLocaleString(locale);
|
|
1908
|
-
case TypeEnum2.String:
|
|
1909
|
-
case TypeEnum2.Ref:
|
|
1910
|
-
return String(value);
|
|
1911
|
-
default: {
|
|
1912
|
-
return String(value);
|
|
1913
|
-
}
|
|
1914
|
-
}
|
|
1915
|
-
};
|
|
1916
|
-
if (!format) {
|
|
1917
|
-
return formatScalar(type);
|
|
1918
|
-
}
|
|
1919
|
-
switch (format) {
|
|
1920
|
-
case FormatEnum4.Boolean: {
|
|
1921
|
-
return formatScalar(TypeEnum2.Boolean);
|
|
1922
|
-
}
|
|
1923
|
-
case FormatEnum4.Number: {
|
|
1924
|
-
return formatScalar(TypeEnum2.Number);
|
|
1925
|
-
}
|
|
1926
|
-
case FormatEnum4.String:
|
|
1927
|
-
case FormatEnum4.Ref: {
|
|
1928
|
-
return formatScalar(TypeEnum2.String);
|
|
1929
|
-
}
|
|
1930
|
-
case FormatEnum4.Percent: {
|
|
1931
|
-
return `${value * 100}%`;
|
|
1932
|
-
}
|
|
1933
|
-
case FormatEnum4.Currency: {
|
|
1934
|
-
return value.toLocaleString(locale, {
|
|
1935
|
-
style: "currency",
|
|
1936
|
-
currency: "USD",
|
|
1937
|
-
minimumFractionDigits: 2,
|
|
1938
|
-
maximumFractionDigits: 2
|
|
1939
|
-
});
|
|
1940
|
-
}
|
|
1941
|
-
case FormatEnum4.Date: {
|
|
1942
|
-
try {
|
|
1943
|
-
return formatDate(new Date(value), "yyyy-MM-dd");
|
|
1944
|
-
} catch (error) {
|
|
1945
|
-
return "Invalid Date";
|
|
1946
|
-
}
|
|
1947
|
-
}
|
|
1948
|
-
case FormatEnum4.Time: {
|
|
1949
|
-
try {
|
|
1950
|
-
return formatDate(new Date(value), "HH:mm:ss");
|
|
1951
|
-
} catch (error) {
|
|
1952
|
-
return "Invalid Time";
|
|
1953
|
-
}
|
|
1954
|
-
}
|
|
1955
|
-
case FormatEnum4.DateTime: {
|
|
1956
|
-
try {
|
|
1957
|
-
return formatDate(new Date(value), "yyyy-MM-dd HH:mm:ss");
|
|
1958
|
-
} catch (error) {
|
|
1959
|
-
return "Invalid DateTime";
|
|
1960
|
-
}
|
|
1961
|
-
}
|
|
1962
|
-
case FormatEnum4.GeoPoint: {
|
|
1963
|
-
if (value === null || value === void 0) {
|
|
1964
|
-
return "";
|
|
1965
|
-
}
|
|
1966
|
-
if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
|
|
1967
|
-
const { latitude, longitude } = GeoLocation3.fromGeoPoint(value);
|
|
1968
|
-
return `${latitude},${longitude}`;
|
|
1969
|
-
}
|
|
1970
|
-
return String(value);
|
|
1971
|
-
}
|
|
1972
|
-
default: {
|
|
1973
|
-
if (value === null || value === "undefined") {
|
|
1974
|
-
return "";
|
|
1975
|
-
}
|
|
1976
|
-
return String(value);
|
|
1977
|
-
}
|
|
1978
|
-
}
|
|
1979
|
-
};
|
|
1980
|
-
var formatForEditing = ({ type, format, value, locale = void 0 }) => {
|
|
1981
|
-
const formatScalar = (type2) => {
|
|
1982
|
-
switch (type2) {
|
|
1983
|
-
case TypeEnum2.Boolean:
|
|
1984
|
-
case TypeEnum2.Number:
|
|
1985
|
-
case TypeEnum2.String:
|
|
1986
|
-
case TypeEnum2.Ref:
|
|
1987
|
-
return String(value);
|
|
1988
|
-
default:
|
|
1989
|
-
return String(value);
|
|
1990
|
-
}
|
|
1991
|
-
};
|
|
1992
|
-
if (!format) {
|
|
1993
|
-
return formatScalar(type);
|
|
1994
|
-
}
|
|
1995
|
-
switch (format) {
|
|
1996
|
-
case FormatEnum4.Boolean:
|
|
1997
|
-
case FormatEnum4.Number:
|
|
1998
|
-
case FormatEnum4.String:
|
|
1999
|
-
case FormatEnum4.Ref: {
|
|
2000
|
-
return formatScalar(type);
|
|
2001
|
-
}
|
|
2002
|
-
case FormatEnum4.Percent: {
|
|
2003
|
-
return String(value * 100);
|
|
2004
|
-
}
|
|
2005
|
-
case FormatEnum4.Currency: {
|
|
2006
|
-
return String(value);
|
|
2007
|
-
}
|
|
2008
|
-
case FormatEnum4.DateTime: {
|
|
2009
|
-
const date = new Date(value);
|
|
2010
|
-
return date.toISOString();
|
|
2011
|
-
}
|
|
2012
|
-
case FormatEnum4.Date: {
|
|
2013
|
-
const date = new Date(value);
|
|
2014
|
-
return date.toISOString().split("T")[0];
|
|
2015
|
-
}
|
|
2016
|
-
case FormatEnum4.Time: {
|
|
2017
|
-
const date = new Date(value);
|
|
2018
|
-
return date.toISOString().split("T")[1].split(".")[0];
|
|
2019
|
-
}
|
|
2020
|
-
case FormatEnum4.GeoPoint: {
|
|
2021
|
-
if (value === null || value === void 0) {
|
|
2022
|
-
return "";
|
|
2023
|
-
}
|
|
2024
|
-
if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
|
|
2025
|
-
const { latitude, longitude } = GeoLocation3.fromGeoPoint(value);
|
|
2026
|
-
return `${latitude},${longitude}`;
|
|
2027
|
-
}
|
|
2028
|
-
return String(value);
|
|
2029
|
-
}
|
|
2030
|
-
default: {
|
|
2031
|
-
return String(value);
|
|
2032
|
-
}
|
|
2033
|
-
}
|
|
2034
|
-
};
|
|
2035
2161
|
export {
|
|
2036
2162
|
BooleanInput,
|
|
2037
2163
|
ControlFrame,
|
|
@@ -2059,8 +2185,10 @@ export {
|
|
|
2059
2185
|
ViewEditor,
|
|
2060
2186
|
cellClassesForFieldType,
|
|
2061
2187
|
controlItemClasses,
|
|
2188
|
+
findArrayElementType,
|
|
2062
2189
|
formatForDisplay,
|
|
2063
2190
|
formatForEditing,
|
|
2191
|
+
getRefProps,
|
|
2064
2192
|
parseValue,
|
|
2065
2193
|
pathNotUniqueError,
|
|
2066
2194
|
translations_default as translations,
|
|
@@ -2068,6 +2196,7 @@ export {
|
|
|
2068
2196
|
useFormContext,
|
|
2069
2197
|
useFormValues,
|
|
2070
2198
|
useInputProps,
|
|
2199
|
+
useQueryRefOptions,
|
|
2071
2200
|
useRefQueryLookupHandler
|
|
2072
2201
|
};
|
|
2073
2202
|
//# sourceMappingURL=index.mjs.map
|