@dxos/react-ui-form 0.8.2-main.5ca3450 → 0.8.2-main.600d381
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/Form/ArrayField.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/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/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/hooks/index.d.ts +1 -0
- package/dist/types/src/hooks/index.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/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/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
|
@@ -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
|
|
185
|
-
import { FormatEnum as
|
|
184
|
+
import React14, { useCallback as useCallback8, useEffect as useEffect8, useMemo as useMemo8, useState as useState5 } from "react";
|
|
185
|
+
import { FormatEnum as FormatEnum5, FormatEnums, formatToType } from "@dxos/echo-schema";
|
|
186
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.
|
|
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
|
-
}))
|
|
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
|
|
@@ -611,7 +611,7 @@ var MarkdownInput = ({ type, label, inputOnly, disabled, placeholder, getStatus,
|
|
|
611
611
|
};
|
|
612
612
|
|
|
613
613
|
// packages/ui/react-ui-form/src/components/Form/Form.tsx
|
|
614
|
-
import React13, { useEffect as useEffect7, useMemo as
|
|
614
|
+
import React13, { useEffect as useEffect7, useMemo as useMemo7, useRef as useRef3 } from "react";
|
|
615
615
|
import { mx as mx8 } from "@dxos/react-ui-theme";
|
|
616
616
|
|
|
617
617
|
// packages/ui/react-ui-form/src/components/Form/FormActions.tsx
|
|
@@ -620,7 +620,7 @@ import { IconButton as IconButton2, useTranslation as useTranslation4 } from "@d
|
|
|
620
620
|
import { mx as mx5 } from "@dxos/react-ui-theme";
|
|
621
621
|
|
|
622
622
|
// packages/ui/react-ui-form/src/components/Form/FormContext.tsx
|
|
623
|
-
import React8, { createContext, useContext, useEffect as
|
|
623
|
+
import React8, { createContext, useContext, useEffect as useEffect6, useMemo as useMemo3 } from "react";
|
|
624
624
|
import { raise } from "@dxos/debug";
|
|
625
625
|
import { getValue as getValue2 } from "@dxos/echo-schema";
|
|
626
626
|
import { createJsonPath as createJsonPath2 } from "@dxos/effect";
|
|
@@ -863,6 +863,52 @@ var useRefQueryLookupHandler = ({ space }) => {
|
|
|
863
863
|
return handleRefQueryLookup;
|
|
864
864
|
};
|
|
865
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
|
+
|
|
866
912
|
// packages/ui/react-ui-form/src/components/Form/FormContext.tsx
|
|
867
913
|
var FormContext = /* @__PURE__ */ createContext(void 0);
|
|
868
914
|
var useFormContext = () => {
|
|
@@ -893,7 +939,7 @@ var useInputProps = (path = []) => {
|
|
|
893
939
|
};
|
|
894
940
|
var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
|
|
895
941
|
const form = useForm(formOptions);
|
|
896
|
-
|
|
942
|
+
useEffect6(() => {
|
|
897
943
|
if (!formRef?.current) {
|
|
898
944
|
return;
|
|
899
945
|
}
|
|
@@ -901,7 +947,7 @@ var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
|
|
|
901
947
|
const keyIsEnter = event.key === "Enter";
|
|
902
948
|
const modifierUsed = event.ctrlKey || event.altKey || event.metaKey || event.shiftKey;
|
|
903
949
|
const inputIsTextarea = event.target.tagName.toLowerCase() === "textarea";
|
|
904
|
-
const inputOptOut = event.target.hasAttribute("data-no-submit");
|
|
950
|
+
const inputOptOut = event.target.hasAttribute("data-no-submit") || event.target.closest("[data-no-submit]") !== null;
|
|
905
951
|
const shouldSubmitRegularInput = !inputIsTextarea && keyIsEnter && !modifierUsed;
|
|
906
952
|
const shouldSubmitTextarea = inputIsTextarea && keyIsEnter && event.metaKey;
|
|
907
953
|
if ((shouldSubmitRegularInput || shouldSubmitTextarea) && !inputOptOut) {
|
|
@@ -954,258 +1000,605 @@ var FormActions = ({ onCancel, readonly }) => {
|
|
|
954
1000
|
};
|
|
955
1001
|
|
|
956
1002
|
// packages/ui/react-ui-form/src/components/Form/FormContent.tsx
|
|
957
|
-
import { Schema, SchemaAST as
|
|
1003
|
+
import { Schema, SchemaAST as SchemaAST4, pipe as pipe2 } from "effect";
|
|
958
1004
|
import { capitalize as capitalize2 } from "effect/String";
|
|
959
|
-
import React12, { useMemo as
|
|
960
|
-
import { createJsonPath as createJsonPath3, findNode as
|
|
1005
|
+
import React12, { useMemo as useMemo6 } from "react";
|
|
1006
|
+
import { createJsonPath as createJsonPath3, findNode as findNode3, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2 } from "@dxos/effect";
|
|
961
1007
|
import { mx as mx7 } from "@dxos/react-ui-theme";
|
|
962
1008
|
import { getSchemaProperties as getSchemaProperties2 } from "@dxos/schema";
|
|
963
1009
|
import { isNotFalsy } from "@dxos/util";
|
|
964
1010
|
|
|
965
1011
|
// packages/ui/react-ui-form/src/components/Form/ArrayField.tsx
|
|
966
|
-
import { SchemaAST as
|
|
1012
|
+
import { SchemaAST as SchemaAST3, pipe } from "effect";
|
|
967
1013
|
import { capitalize } from "effect/String";
|
|
968
1014
|
import React10, { useCallback as useCallback6, useMemo as useMemo4 } from "react";
|
|
969
|
-
import { findNode, getDiscriminatedType, isDiscriminatedUnion, SimpleType } from "@dxos/effect";
|
|
1015
|
+
import { findNode as findNode2, getDiscriminatedType, isDiscriminatedUnion, SimpleType } from "@dxos/effect";
|
|
970
1016
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
971
1017
|
import { IconButton as IconButton3, useTranslation as useTranslation5 } from "@dxos/react-ui";
|
|
972
1018
|
import { mx as mx6 } from "@dxos/react-ui-theme";
|
|
973
1019
|
import { getSchemaProperties } from "@dxos/schema";
|
|
974
|
-
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/Form/ArrayField.tsx";
|
|
975
|
-
var padding = "px-2";
|
|
976
|
-
var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponent }) => {
|
|
977
|
-
const { t } = useTranslation5(translationKey);
|
|
978
|
-
const { ast, name, type, title } = property;
|
|
979
|
-
const values = useFormValues(path ?? []) ?? [];
|
|
980
|
-
invariant2(Array.isArray(values), `Values at path ${path?.join(".")} must be an array.`, {
|
|
981
|
-
F: __dxlog_file2,
|
|
982
|
-
L: 38,
|
|
983
|
-
S: void 0,
|
|
984
|
-
A: [
|
|
985
|
-
"Array.isArray(values)",
|
|
986
|
-
"`Values at path ${path?.join('.')} must be an array.`"
|
|
987
|
-
]
|
|
988
|
-
});
|
|
989
|
-
const label = title ?? pipe(name, capitalize);
|
|
990
|
-
const tupleType = findNode(ast, SchemaAST2.isTupleType);
|
|
991
|
-
const elementType = tupleType?.rest[0]?.type;
|
|
992
|
-
const getDefaultObjectValue = (typeNode) => {
|
|
993
|
-
const baseNode = findNode(typeNode, isDiscriminatedUnion);
|
|
994
|
-
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, {}) : findNode(typeNode, SchemaAST2.isTypeLiteral);
|
|
995
|
-
if (!typeLiteral) {
|
|
996
|
-
return {};
|
|
997
|
-
}
|
|
998
|
-
return Object.fromEntries(getSchemaProperties(typeLiteral, {}).map((prop) => [
|
|
999
|
-
prop.name,
|
|
1000
|
-
prop.defaultValue
|
|
1001
|
-
]));
|
|
1002
|
-
};
|
|
1003
|
-
const newValue = useMemo4(() => {
|
|
1004
|
-
if (type === "object" && elementType) {
|
|
1005
|
-
return getDefaultObjectValue(elementType);
|
|
1006
|
-
} else {
|
|
1007
|
-
return SimpleType.getDefaultValue(type);
|
|
1008
|
-
}
|
|
1009
|
-
}, [
|
|
1010
|
-
type,
|
|
1011
|
-
elementType
|
|
1012
|
-
]);
|
|
1013
|
-
const handleAdd = useCallback6(() => {
|
|
1014
|
-
inputProps.onValueChange(type, [
|
|
1015
|
-
...values,
|
|
1016
|
-
newValue
|
|
1017
|
-
]);
|
|
1018
|
-
}, [
|
|
1019
|
-
type,
|
|
1020
|
-
elementType,
|
|
1021
|
-
inputProps,
|
|
1022
|
-
newValue,
|
|
1023
|
-
values
|
|
1024
|
-
]);
|
|
1025
|
-
const handleRemove = useCallback6((index) => {
|
|
1026
|
-
const newValues = values.filter((_, i) => i !== index);
|
|
1027
|
-
inputProps.onValueChange(type, newValues);
|
|
1028
|
-
}, [
|
|
1029
|
-
type,
|
|
1030
|
-
inputProps,
|
|
1031
|
-
values
|
|
1032
|
-
]);
|
|
1033
|
-
if (!elementType) {
|
|
1034
|
-
return null;
|
|
1035
|
-
}
|
|
1036
|
-
return /* @__PURE__ */ React10.createElement("div", {
|
|
1037
|
-
role: "none",
|
|
1038
|
-
className: mx6(padding)
|
|
1039
|
-
}, /* @__PURE__ */ React10.createElement(InputHeader, null, label), /* @__PURE__ */ React10.createElement("div", {
|
|
1040
|
-
role: "none",
|
|
1041
|
-
className: "flex flex-col gap-1"
|
|
1042
|
-
}, values.map((_value, index) => /* @__PURE__ */ React10.createElement("div", {
|
|
1043
|
-
key: index,
|
|
1044
|
-
role: "none",
|
|
1045
|
-
className: "flex items-center gap-1"
|
|
1046
|
-
}, /* @__PURE__ */ React10.createElement("div", {
|
|
1047
|
-
role: "none",
|
|
1048
|
-
className: "flex-1"
|
|
1049
|
-
}, /* @__PURE__ */ React10.createElement(FormField, {
|
|
1050
|
-
property: {
|
|
1051
|
-
...property,
|
|
1052
|
-
array: false,
|
|
1053
|
-
ast: elementType
|
|
1054
|
-
},
|
|
1055
|
-
path: [
|
|
1056
|
-
...path ?? [],
|
|
1057
|
-
index
|
|
1058
|
-
],
|
|
1059
|
-
readonly,
|
|
1060
|
-
inline: true,
|
|
1061
|
-
Custom,
|
|
1062
|
-
lookupComponent
|
|
1063
|
-
})), /* @__PURE__ */ React10.createElement(IconButton3, {
|
|
1064
|
-
icon: "ph--trash--regular",
|
|
1065
|
-
iconOnly: true,
|
|
1066
|
-
label: t("button remove"),
|
|
1067
|
-
onClick: () => handleRemove(index)
|
|
1068
|
-
})))), /* @__PURE__ */ React10.createElement("div", {
|
|
1069
|
-
role: "none",
|
|
1070
|
-
className: "flex justify-between items-center plb-1"
|
|
1071
|
-
}, /* @__PURE__ */ React10.createElement(IconButton3, {
|
|
1072
|
-
icon: "ph--plus--regular",
|
|
1073
|
-
iconOnly: true,
|
|
1074
|
-
label: t("button add"),
|
|
1075
|
-
onClick: handleAdd
|
|
1076
|
-
})));
|
|
1077
|
-
};
|
|
1078
1020
|
|
|
1079
|
-
// packages/ui/react-ui-form/src/
|
|
1080
|
-
import
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
import { refFromDXN } from "@dxos/live-object";
|
|
1085
|
-
import { log as log2 } from "@dxos/log";
|
|
1086
|
-
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/Form/RefField.tsx";
|
|
1087
|
-
var RefField = ({ ast, type, label, readonly, placeholder, inline, onQueryRefOptions, inputProps }) => {
|
|
1088
|
-
const { getValue: getValue3, onValueChange, ...restInputProps } = inputProps;
|
|
1089
|
-
const refTypeInfo = findAnnotation(ast, ReferenceAnnotationId);
|
|
1090
|
-
const [refOptions, setRefOptions] = useState4([]);
|
|
1091
|
-
const [loading, setLoading] = useState4(false);
|
|
1092
|
-
useEffect6(() => {
|
|
1093
|
-
if (!refTypeInfo || !onQueryRefOptions) {
|
|
1094
|
-
return;
|
|
1095
|
-
}
|
|
1096
|
-
const fetchOptions = async () => {
|
|
1097
|
-
setLoading(true);
|
|
1098
|
-
try {
|
|
1099
|
-
const options = await onQueryRefOptions(refTypeInfo);
|
|
1100
|
-
setRefOptions(options.map((option) => ({
|
|
1101
|
-
label: option.label,
|
|
1102
|
-
value: option.dxn.toString()
|
|
1103
|
-
})));
|
|
1104
|
-
} catch (error) {
|
|
1105
|
-
log2.error("Failed to fetch ref options:", error, {
|
|
1106
|
-
F: __dxlog_file3,
|
|
1107
|
-
L: 69,
|
|
1108
|
-
S: void 0,
|
|
1109
|
-
C: (f, a) => f(...a)
|
|
1110
|
-
});
|
|
1111
|
-
setRefOptions([]);
|
|
1112
|
-
} finally {
|
|
1113
|
-
setLoading(false);
|
|
1114
|
-
}
|
|
1115
|
-
};
|
|
1116
|
-
void fetchOptions();
|
|
1117
|
-
}, [
|
|
1118
|
-
refTypeInfo,
|
|
1119
|
-
onQueryRefOptions
|
|
1120
|
-
]);
|
|
1121
|
-
if (!refTypeInfo) {
|
|
1122
|
-
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;
|
|
1123
1026
|
}
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
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);
|
|
1133
1039
|
}
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
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;
|
|
1139
1044
|
}
|
|
1140
|
-
|
|
1141
|
-
|
|
1045
|
+
case TypeEnum.String:
|
|
1046
|
+
case TypeEnum.Ref:
|
|
1047
|
+
return String(value);
|
|
1048
|
+
default: {
|
|
1049
|
+
return value;
|
|
1142
1050
|
}
|
|
1143
|
-
return void 0;
|
|
1144
|
-
};
|
|
1145
|
-
return /* @__PURE__ */ React11.createElement(TextInput, {
|
|
1146
|
-
type,
|
|
1147
|
-
label,
|
|
1148
|
-
disabled: readonly,
|
|
1149
|
-
placeholder,
|
|
1150
|
-
inputOnly: inline,
|
|
1151
|
-
getValue: handleGetValue2,
|
|
1152
|
-
onValueChange: handleOnValueChange,
|
|
1153
|
-
...restInputProps
|
|
1154
|
-
});
|
|
1155
|
-
}
|
|
1156
|
-
const handleGetValue = () => {
|
|
1157
|
-
const formValue = getValue3();
|
|
1158
|
-
if (Ref.isRef(formValue)) {
|
|
1159
|
-
return formValue.dxn.toString();
|
|
1160
1051
|
}
|
|
1161
|
-
return void 0;
|
|
1162
1052
|
};
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
const ref = refFromDXN(dxn);
|
|
1166
|
-
onValueChange("object", ref);
|
|
1167
|
-
};
|
|
1168
|
-
return /* @__PURE__ */ React11.createElement(SelectInput, {
|
|
1169
|
-
type,
|
|
1170
|
-
label,
|
|
1171
|
-
disabled: readonly || loading,
|
|
1172
|
-
placeholder: loading ? "Loading options..." : placeholder,
|
|
1173
|
-
inputOnly: inline,
|
|
1174
|
-
getValue: handleGetValue,
|
|
1175
|
-
onValueChange: handleValueChanged,
|
|
1176
|
-
options: refOptions,
|
|
1177
|
-
...restInputProps
|
|
1178
|
-
});
|
|
1179
|
-
};
|
|
1180
|
-
|
|
1181
|
-
// packages/ui/react-ui-form/src/components/Form/factory.tsx
|
|
1182
|
-
import { FormatEnum } from "@dxos/echo-schema";
|
|
1183
|
-
var getInputComponent = (type, format) => {
|
|
1184
|
-
switch (format) {
|
|
1185
|
-
case FormatEnum.GeoPoint:
|
|
1186
|
-
return GeoPointInput;
|
|
1187
|
-
case FormatEnum.Markdown:
|
|
1188
|
-
return MarkdownInput;
|
|
1053
|
+
if (!format) {
|
|
1054
|
+
return parseScalar(type);
|
|
1189
1055
|
}
|
|
1190
|
-
switch (
|
|
1191
|
-
case
|
|
1192
|
-
return
|
|
1193
|
-
case
|
|
1194
|
-
|
|
1195
|
-
case
|
|
1196
|
-
return
|
|
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
|
+
}
|
|
1197
1099
|
}
|
|
1198
1100
|
};
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
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 newValue = useMemo4(() => {
|
|
1358
|
+
if (type === "object" && elementType) {
|
|
1359
|
+
return getDefaultObjectValue(elementType);
|
|
1360
|
+
} else {
|
|
1361
|
+
return SimpleType.getDefaultValue(type);
|
|
1362
|
+
}
|
|
1363
|
+
}, [
|
|
1364
|
+
type,
|
|
1365
|
+
elementType
|
|
1366
|
+
]);
|
|
1367
|
+
const handleAdd = useCallback6(() => {
|
|
1368
|
+
inputProps.onValueChange(type, [
|
|
1369
|
+
...values,
|
|
1370
|
+
newValue
|
|
1371
|
+
]);
|
|
1372
|
+
}, [
|
|
1373
|
+
type,
|
|
1374
|
+
elementType,
|
|
1375
|
+
inputProps,
|
|
1376
|
+
newValue,
|
|
1377
|
+
values
|
|
1378
|
+
]);
|
|
1379
|
+
const handleRemove = useCallback6((index) => {
|
|
1380
|
+
const newValues = values.filter((_, i) => i !== index);
|
|
1381
|
+
inputProps.onValueChange(type, newValues);
|
|
1382
|
+
}, [
|
|
1383
|
+
type,
|
|
1384
|
+
inputProps,
|
|
1385
|
+
values
|
|
1386
|
+
]);
|
|
1387
|
+
if (!elementType) {
|
|
1388
|
+
return null;
|
|
1389
|
+
}
|
|
1390
|
+
return /* @__PURE__ */ React10.createElement("div", {
|
|
1391
|
+
role: "none",
|
|
1392
|
+
className: mx6(padding)
|
|
1393
|
+
}, /* @__PURE__ */ React10.createElement(InputHeader, null, label), /* @__PURE__ */ React10.createElement("div", {
|
|
1394
|
+
role: "none",
|
|
1395
|
+
className: "flex flex-col gap-1"
|
|
1396
|
+
}, values.map((_value, index) => /* @__PURE__ */ React10.createElement("div", {
|
|
1397
|
+
key: index,
|
|
1398
|
+
role: "none",
|
|
1399
|
+
className: "flex items-center gap-1"
|
|
1400
|
+
}, /* @__PURE__ */ React10.createElement("div", {
|
|
1401
|
+
role: "none",
|
|
1402
|
+
className: "flex-1"
|
|
1403
|
+
}, /* @__PURE__ */ React10.createElement(FormField, {
|
|
1404
|
+
property: {
|
|
1405
|
+
...property,
|
|
1406
|
+
array: false,
|
|
1407
|
+
ast: elementType
|
|
1408
|
+
},
|
|
1409
|
+
path: [
|
|
1410
|
+
...path ?? [],
|
|
1411
|
+
index
|
|
1412
|
+
],
|
|
1413
|
+
readonly,
|
|
1414
|
+
inline: true,
|
|
1415
|
+
Custom,
|
|
1416
|
+
lookupComponent
|
|
1417
|
+
})), /* @__PURE__ */ React10.createElement(IconButton3, {
|
|
1418
|
+
icon: "ph--trash--regular",
|
|
1419
|
+
iconOnly: true,
|
|
1420
|
+
label: t("button remove"),
|
|
1421
|
+
onClick: () => handleRemove(index)
|
|
1422
|
+
})))), /* @__PURE__ */ React10.createElement("div", {
|
|
1423
|
+
role: "none",
|
|
1424
|
+
className: "flex justify-between items-center plb-1"
|
|
1425
|
+
}, /* @__PURE__ */ React10.createElement(IconButton3, {
|
|
1426
|
+
icon: "ph--plus--regular",
|
|
1427
|
+
iconOnly: true,
|
|
1428
|
+
label: t("button add"),
|
|
1429
|
+
onClick: handleAdd
|
|
1430
|
+
})));
|
|
1431
|
+
};
|
|
1432
|
+
|
|
1433
|
+
// packages/ui/react-ui-form/src/components/Form/RefField.tsx
|
|
1434
|
+
import React11, { useCallback as useCallback7, useMemo as useMemo5 } from "react";
|
|
1435
|
+
import { Expando, getTypeAnnotation, Ref, ReferenceAnnotationId as ReferenceAnnotationId2 } from "@dxos/echo-schema";
|
|
1436
|
+
import { findAnnotation as findAnnotation2 } from "@dxos/effect";
|
|
1437
|
+
import { DXN } from "@dxos/keys";
|
|
1438
|
+
import { Input as Input7 } from "@dxos/react-ui";
|
|
1439
|
+
import { TagPicker } from "@dxos/react-ui-tag-picker";
|
|
1440
|
+
import { isNonNullable as isNonNullable2 } from "@dxos/util";
|
|
1441
|
+
var RefField = ({ type, label, disabled, placeholder, inputOnly, array, ast, getValue: getValue3, onBlur, onQueryRefOptions, onValueChange, ...restInputProps }) => {
|
|
1442
|
+
const refTypeInfo = useMemo5(() => ast ? findAnnotation2(ast, ReferenceAnnotationId2) : void 0, [
|
|
1443
|
+
ast
|
|
1444
|
+
]);
|
|
1445
|
+
const { options: availableOptions, loading: _loading } = useQueryRefOptions({
|
|
1446
|
+
refTypeInfo,
|
|
1447
|
+
onQueryRefOptions
|
|
1448
|
+
});
|
|
1449
|
+
if (refTypeInfo && refTypeInfo?.typename === getTypeAnnotation(Expando)?.typename || !onQueryRefOptions) {
|
|
1450
|
+
return /* @__PURE__ */ React11.createElement(RefFieldFallback, {
|
|
1451
|
+
type,
|
|
1452
|
+
label,
|
|
1453
|
+
placeholder,
|
|
1454
|
+
disabled,
|
|
1455
|
+
inputOnly,
|
|
1456
|
+
getValue: getValue3,
|
|
1457
|
+
onBlur,
|
|
1458
|
+
onValueChange,
|
|
1459
|
+
...restInputProps
|
|
1460
|
+
});
|
|
1461
|
+
}
|
|
1462
|
+
const handleGetValue = useCallback7(() => {
|
|
1463
|
+
const formValue = getValue3();
|
|
1464
|
+
const unknownToRefOption = (val) => {
|
|
1465
|
+
if (Ref.isRef(val)) {
|
|
1466
|
+
const dxnString = val.dxn.toString();
|
|
1467
|
+
const matchingOption = availableOptions.find((option2) => option2.id === dxnString);
|
|
1468
|
+
if (matchingOption) {
|
|
1469
|
+
return matchingOption;
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1472
|
+
return void 0;
|
|
1473
|
+
};
|
|
1474
|
+
if (array && Array.isArray(formValue)) {
|
|
1475
|
+
return formValue.map(unknownToRefOption).filter(isNonNullable2) ?? [];
|
|
1476
|
+
}
|
|
1477
|
+
const option = unknownToRefOption(formValue);
|
|
1478
|
+
if (option) {
|
|
1479
|
+
return [
|
|
1480
|
+
option
|
|
1481
|
+
];
|
|
1482
|
+
}
|
|
1483
|
+
return [];
|
|
1484
|
+
}, [
|
|
1485
|
+
getValue3,
|
|
1486
|
+
availableOptions,
|
|
1487
|
+
array
|
|
1488
|
+
]);
|
|
1489
|
+
const handleSearch = useCallback7((text, ids) => availableOptions.filter((option) => !ids.includes(option.id)).filter((option) => option.label.toLowerCase().includes(text.toLowerCase())).map((option) => ({
|
|
1490
|
+
id: option.id,
|
|
1491
|
+
label: option.label,
|
|
1492
|
+
hue: option.hue
|
|
1493
|
+
})), [
|
|
1494
|
+
availableOptions
|
|
1495
|
+
]);
|
|
1496
|
+
const handleUpdate = useCallback7((ids) => {
|
|
1497
|
+
if (ids.length === 0) {
|
|
1498
|
+
onValueChange("object", void 0);
|
|
1499
|
+
return;
|
|
1500
|
+
}
|
|
1501
|
+
const refs = ids.map((id) => {
|
|
1502
|
+
const item = availableOptions.find((option) => option.id === id);
|
|
1503
|
+
if (item) {
|
|
1504
|
+
const dxn = DXN.parse(item.id);
|
|
1505
|
+
return Ref.fromDXN(dxn);
|
|
1506
|
+
}
|
|
1507
|
+
return null;
|
|
1508
|
+
}).filter(isNonNullable2);
|
|
1509
|
+
if (array) {
|
|
1510
|
+
onValueChange("object", refs);
|
|
1511
|
+
} else {
|
|
1512
|
+
onValueChange("object", refs[0]);
|
|
1513
|
+
}
|
|
1514
|
+
}, [
|
|
1515
|
+
availableOptions,
|
|
1516
|
+
array,
|
|
1517
|
+
onValueChange
|
|
1518
|
+
]);
|
|
1519
|
+
const tagPickerMode = useMemo5(() => array ? "multi-select" : "single-select", [
|
|
1520
|
+
array
|
|
1521
|
+
]);
|
|
1522
|
+
if (!refTypeInfo) {
|
|
1523
|
+
return null;
|
|
1524
|
+
}
|
|
1525
|
+
const { status, error } = restInputProps.getStatus();
|
|
1526
|
+
return /* @__PURE__ */ React11.createElement(Input7.Root, {
|
|
1527
|
+
validationValence: status
|
|
1528
|
+
}, !inputOnly && /* @__PURE__ */ React11.createElement(InputHeader, {
|
|
1529
|
+
error
|
|
1530
|
+
}, /* @__PURE__ */ React11.createElement(Input7.Label, null, label)), /* @__PURE__ */ React11.createElement("div", {
|
|
1531
|
+
"data-no-submit": true
|
|
1532
|
+
}, /* @__PURE__ */ React11.createElement(TagPicker, {
|
|
1533
|
+
items: handleGetValue(),
|
|
1534
|
+
mode: tagPickerMode,
|
|
1535
|
+
onBlur: (event) => onBlur(event),
|
|
1536
|
+
onUpdate: handleUpdate,
|
|
1537
|
+
onSearch: handleSearch,
|
|
1538
|
+
classNames: "rounded-sm bg-input p-1.5"
|
|
1539
|
+
})), inputOnly && /* @__PURE__ */ React11.createElement(Input7.DescriptionAndValidation, null, error));
|
|
1540
|
+
};
|
|
1541
|
+
var RefFieldFallback = ({ type, label, disabled, placeholder, inputOnly, getValue: getValue3, onValueChange, ...restInputProps }) => {
|
|
1542
|
+
const handleOnValueChange = (_type, dxnString) => {
|
|
1543
|
+
const dxn = DXN.tryParse(dxnString);
|
|
1544
|
+
if (dxn) {
|
|
1545
|
+
onValueChange?.("object", Ref.fromDXN(dxn));
|
|
1546
|
+
} else if (dxnString === "") {
|
|
1547
|
+
onValueChange?.("object", void 0);
|
|
1548
|
+
} else {
|
|
1549
|
+
onValueChange?.("string", dxnString);
|
|
1550
|
+
}
|
|
1551
|
+
};
|
|
1552
|
+
const handleGetValue = () => {
|
|
1553
|
+
const formValue = getValue3();
|
|
1554
|
+
if (typeof formValue === "string") {
|
|
1555
|
+
return formValue;
|
|
1556
|
+
}
|
|
1557
|
+
if (Ref.isRef(formValue)) {
|
|
1558
|
+
return formValue.dxn.toString();
|
|
1559
|
+
}
|
|
1560
|
+
return void 0;
|
|
1561
|
+
};
|
|
1562
|
+
return /* @__PURE__ */ React11.createElement(TextInput, {
|
|
1563
|
+
type,
|
|
1564
|
+
label,
|
|
1565
|
+
disabled,
|
|
1566
|
+
placeholder,
|
|
1567
|
+
inputOnly,
|
|
1568
|
+
getValue: handleGetValue,
|
|
1569
|
+
onValueChange: handleOnValueChange,
|
|
1570
|
+
...restInputProps
|
|
1571
|
+
});
|
|
1572
|
+
};
|
|
1573
|
+
|
|
1574
|
+
// packages/ui/react-ui-form/src/components/Form/factory.tsx
|
|
1575
|
+
import { FormatEnum as FormatEnum4 } from "@dxos/echo-schema";
|
|
1576
|
+
var getInputComponent = (type, format) => {
|
|
1577
|
+
switch (format) {
|
|
1578
|
+
case FormatEnum4.GeoPoint:
|
|
1579
|
+
return GeoPointInput;
|
|
1580
|
+
case FormatEnum4.Markdown:
|
|
1581
|
+
return MarkdownInput;
|
|
1582
|
+
}
|
|
1583
|
+
switch (type) {
|
|
1584
|
+
case "string":
|
|
1585
|
+
return TextInput;
|
|
1586
|
+
case "number":
|
|
1587
|
+
return NumberInput;
|
|
1588
|
+
case "boolean":
|
|
1589
|
+
return BooleanInput;
|
|
1590
|
+
}
|
|
1591
|
+
};
|
|
1592
|
+
|
|
1593
|
+
// packages/ui/react-ui-form/src/components/Form/FormContent.tsx
|
|
1594
|
+
var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupComponent, Custom }) => {
|
|
1202
1595
|
const inputProps = useInputProps(path);
|
|
1203
1596
|
const { ast, name, type, format, title, description, options, examples, array } = property;
|
|
1204
|
-
const label =
|
|
1597
|
+
const label = useMemo6(() => title ?? pipe2(name, capitalize2), [
|
|
1205
1598
|
title,
|
|
1206
1599
|
name
|
|
1207
1600
|
]);
|
|
1208
|
-
const placeholder =
|
|
1601
|
+
const placeholder = useMemo6(() => examples?.length ? `Example: "${examples[0]}"` : description, [
|
|
1209
1602
|
examples,
|
|
1210
1603
|
description
|
|
1211
1604
|
]);
|
|
@@ -1239,6 +1632,21 @@ var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupCo
|
|
|
1239
1632
|
...inputProps
|
|
1240
1633
|
});
|
|
1241
1634
|
}
|
|
1635
|
+
const refProps = getRefProps(property);
|
|
1636
|
+
if (refProps) {
|
|
1637
|
+
return /* @__PURE__ */ React12.createElement(RefField, {
|
|
1638
|
+
ast: refProps.ast,
|
|
1639
|
+
array: refProps.isArray,
|
|
1640
|
+
type,
|
|
1641
|
+
format,
|
|
1642
|
+
label,
|
|
1643
|
+
placeholder,
|
|
1644
|
+
disabled: readonly,
|
|
1645
|
+
inputOnly: inline,
|
|
1646
|
+
onQueryRefOptions,
|
|
1647
|
+
...inputProps
|
|
1648
|
+
});
|
|
1649
|
+
}
|
|
1242
1650
|
if (array) {
|
|
1243
1651
|
return /* @__PURE__ */ React12.createElement(ArrayField, {
|
|
1244
1652
|
property,
|
|
@@ -1279,21 +1687,9 @@ var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupCo
|
|
|
1279
1687
|
...inputProps
|
|
1280
1688
|
}));
|
|
1281
1689
|
}
|
|
1282
|
-
if (format === "ref") {
|
|
1283
|
-
return /* @__PURE__ */ React12.createElement(RefField, {
|
|
1284
|
-
ast,
|
|
1285
|
-
type,
|
|
1286
|
-
label,
|
|
1287
|
-
readonly,
|
|
1288
|
-
placeholder,
|
|
1289
|
-
inline,
|
|
1290
|
-
onQueryRefOptions,
|
|
1291
|
-
inputProps
|
|
1292
|
-
});
|
|
1293
|
-
}
|
|
1294
1690
|
if (type === "object") {
|
|
1295
|
-
const baseNode =
|
|
1296
|
-
const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, inputProps.getValue()) :
|
|
1691
|
+
const baseNode = findNode3(ast, isDiscriminatedUnion2);
|
|
1692
|
+
const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, inputProps.getValue()) : findNode3(ast, SchemaAST4.isTypeLiteral);
|
|
1297
1693
|
if (typeLiteral) {
|
|
1298
1694
|
return /* @__PURE__ */ React12.createElement("div", {
|
|
1299
1695
|
role: "none"
|
|
@@ -1313,7 +1709,7 @@ var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupCo
|
|
|
1313
1709
|
};
|
|
1314
1710
|
var FormFields = ({ schema, path, filter, sort, readonly, onQueryRefOptions, lookupComponent, Custom }) => {
|
|
1315
1711
|
const values = useFormValues(path);
|
|
1316
|
-
const properties =
|
|
1712
|
+
const properties = useMemo6(() => {
|
|
1317
1713
|
const props = getSchemaProperties2(schema.ast, values);
|
|
1318
1714
|
const filtered = filter ? filter(props) : props;
|
|
1319
1715
|
return sort ? filtered.sort((a, b) => sort.indexOf(a.name) - sort.indexOf(b.name)) : filtered;
|
|
@@ -1345,7 +1741,7 @@ var FormFields = ({ schema, path, filter, sort, readonly, onQueryRefOptions, loo
|
|
|
1345
1741
|
// packages/ui/react-ui-form/src/components/Form/Form.tsx
|
|
1346
1742
|
var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, onQueryRefOptions, lookupComponent, Custom }) => {
|
|
1347
1743
|
const formRef = useRef3(null);
|
|
1348
|
-
const onValid =
|
|
1744
|
+
const onValid = useMemo7(() => autoSave ? onSave : void 0, [
|
|
1349
1745
|
autoSave,
|
|
1350
1746
|
onSave
|
|
1351
1747
|
]);
|
|
@@ -1426,7 +1822,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
1426
1822
|
const [{ fieldSchema }, setFieldSchema] = useState5({
|
|
1427
1823
|
fieldSchema: getFormatSchema(props?.format)
|
|
1428
1824
|
});
|
|
1429
|
-
const handleValuesChanged =
|
|
1825
|
+
const handleValuesChanged = useCallback8((_props) => {
|
|
1430
1826
|
setFieldSchema((prev) => {
|
|
1431
1827
|
const fieldSchema2 = getFormatSchema(_props.format);
|
|
1432
1828
|
if (prev.fieldSchema === fieldSchema2) {
|
|
@@ -1461,7 +1857,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
1461
1857
|
props.format,
|
|
1462
1858
|
props.referenceSchema
|
|
1463
1859
|
]);
|
|
1464
|
-
const handleValidate =
|
|
1860
|
+
const handleValidate = useCallback8(({ property }) => {
|
|
1465
1861
|
if (property && view.fields.find((f) => f.path === property && f.path !== field.path)) {
|
|
1466
1862
|
return [
|
|
1467
1863
|
{
|
|
@@ -1474,7 +1870,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
1474
1870
|
view.fields,
|
|
1475
1871
|
field
|
|
1476
1872
|
]);
|
|
1477
|
-
const handleSave =
|
|
1873
|
+
const handleSave = useCallback8((props2) => {
|
|
1478
1874
|
projection.setFieldProjection({
|
|
1479
1875
|
field,
|
|
1480
1876
|
props: props2
|
|
@@ -1485,16 +1881,16 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
1485
1881
|
field,
|
|
1486
1882
|
onSave
|
|
1487
1883
|
]);
|
|
1488
|
-
const handleCancel =
|
|
1884
|
+
const handleCancel = useCallback8(() => {
|
|
1489
1885
|
requestAnimationFrame(() => onCancel?.());
|
|
1490
1886
|
onSave();
|
|
1491
1887
|
}, [
|
|
1492
1888
|
onSave
|
|
1493
1889
|
]);
|
|
1494
|
-
const Custom =
|
|
1890
|
+
const Custom = useMemo8(() => ({
|
|
1495
1891
|
["format"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
|
|
1496
1892
|
...props2,
|
|
1497
|
-
options: FormatEnums.filter((value) => value !==
|
|
1893
|
+
options: FormatEnums.filter((value) => value !== FormatEnum5.None).map((value) => ({
|
|
1498
1894
|
value,
|
|
1499
1895
|
label: t(`format ${value}`)
|
|
1500
1896
|
}))
|
|
@@ -1517,7 +1913,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
1517
1913
|
schemas,
|
|
1518
1914
|
referenceSchema
|
|
1519
1915
|
]);
|
|
1520
|
-
const propIsNotType =
|
|
1916
|
+
const propIsNotType = useCallback8((props2) => props2.filter((p) => p.name !== "type"), []);
|
|
1521
1917
|
if (!fieldSchema) {
|
|
1522
1918
|
log3.warn("invalid format", {
|
|
1523
1919
|
props
|
|
@@ -1548,8 +1944,8 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
1548
1944
|
};
|
|
1549
1945
|
|
|
1550
1946
|
// packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx
|
|
1551
|
-
import { Schema as Schema2, SchemaAST as
|
|
1552
|
-
import React15, { useCallback as
|
|
1947
|
+
import { Schema as Schema2, SchemaAST as SchemaAST5 } from "effect";
|
|
1948
|
+
import React15, { useCallback as useCallback9, useMemo as useMemo9, useState as useState6 } from "react";
|
|
1553
1949
|
import { Format } from "@dxos/echo-schema";
|
|
1554
1950
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
1555
1951
|
import { IconButton as IconButton4, useTranslation as useTranslation7 } from "@dxos/react-ui";
|
|
@@ -1560,20 +1956,20 @@ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/c
|
|
|
1560
1956
|
var grid = "grid grid-cols-[32px_1fr_32px] min-bs-[2.5rem]";
|
|
1561
1957
|
var ViewMetaSchema = Schema2.Struct({
|
|
1562
1958
|
name: Schema2.String.annotations({
|
|
1563
|
-
[
|
|
1959
|
+
[SchemaAST5.TitleAnnotationId]: "View"
|
|
1564
1960
|
}),
|
|
1565
1961
|
typename: Format.URL.annotations({
|
|
1566
|
-
[
|
|
1962
|
+
[SchemaAST5.TitleAnnotationId]: "Typename"
|
|
1567
1963
|
})
|
|
1568
1964
|
}).pipe(Schema2.mutable);
|
|
1569
1965
|
var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading = false, onTypenameChanged, onDelete }) => {
|
|
1570
1966
|
const { t } = useTranslation7(translationKey);
|
|
1571
|
-
const projection =
|
|
1967
|
+
const projection = useMemo9(() => new ViewProjection(schema.jsonSchema, view), [
|
|
1572
1968
|
schema,
|
|
1573
1969
|
view
|
|
1574
1970
|
]);
|
|
1575
1971
|
const [field, setField] = useState6();
|
|
1576
|
-
const viewValues =
|
|
1972
|
+
const viewValues = useMemo9(() => {
|
|
1577
1973
|
return {
|
|
1578
1974
|
name: view.name,
|
|
1579
1975
|
// TODO(burdon): Need to warn user of possible consequences of editing.
|
|
@@ -1583,10 +1979,10 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
1583
1979
|
}, [
|
|
1584
1980
|
view
|
|
1585
1981
|
]);
|
|
1586
|
-
const handleSelect =
|
|
1982
|
+
const handleSelect = useCallback9((field2) => {
|
|
1587
1983
|
setField((f) => f === field2 ? void 0 : field2);
|
|
1588
1984
|
}, []);
|
|
1589
|
-
const handleAdd =
|
|
1985
|
+
const handleAdd = useCallback9(() => {
|
|
1590
1986
|
invariant3(!schema.readonly, void 0, {
|
|
1591
1987
|
F: __dxlog_file5,
|
|
1592
1988
|
L: 77,
|
|
@@ -1602,7 +1998,7 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
1602
1998
|
schema,
|
|
1603
1999
|
view
|
|
1604
2000
|
]);
|
|
1605
|
-
const handleUpdate =
|
|
2001
|
+
const handleUpdate = useCallback9(({ name, typename }) => {
|
|
1606
2002
|
invariant3(!schema.readonly, void 0, {
|
|
1607
2003
|
F: __dxlog_file5,
|
|
1608
2004
|
L: 84,
|
|
@@ -1625,7 +2021,7 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
1625
2021
|
view,
|
|
1626
2022
|
onTypenameChanged
|
|
1627
2023
|
]);
|
|
1628
|
-
const handleDelete =
|
|
2024
|
+
const handleDelete = useCallback9((fieldId) => {
|
|
1629
2025
|
invariant3(!schema.readonly, void 0, {
|
|
1630
2026
|
F: __dxlog_file5,
|
|
1631
2027
|
L: 100,
|
|
@@ -1644,7 +2040,7 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
1644
2040
|
field,
|
|
1645
2041
|
onDelete
|
|
1646
2042
|
]);
|
|
1647
|
-
const handleMove =
|
|
2043
|
+
const handleMove = useCallback9((fromIndex, toIndex) => {
|
|
1648
2044
|
invariant3(!schema.readonly, void 0, {
|
|
1649
2045
|
F: __dxlog_file5,
|
|
1650
2046
|
L: 112,
|
|
@@ -1664,15 +2060,15 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
1664
2060
|
schema,
|
|
1665
2061
|
view.fields
|
|
1666
2062
|
]);
|
|
1667
|
-
const handleClose =
|
|
2063
|
+
const handleClose = useCallback9(() => setField(void 0), []);
|
|
1668
2064
|
const hiddenProperties = projection.getHiddenProperties();
|
|
1669
|
-
const handleHide =
|
|
2065
|
+
const handleHide = useCallback9((fieldId) => {
|
|
1670
2066
|
setField(void 0);
|
|
1671
2067
|
projection.hideFieldProjection(fieldId);
|
|
1672
2068
|
}, [
|
|
1673
2069
|
projection
|
|
1674
2070
|
]);
|
|
1675
|
-
const handleShow =
|
|
2071
|
+
const handleShow = useCallback9((property) => {
|
|
1676
2072
|
setField(void 0);
|
|
1677
2073
|
projection.showFieldProjection(property);
|
|
1678
2074
|
}, [
|
|
@@ -1760,276 +2156,6 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
1760
2156
|
disabled: view.fields.length >= VIEW_FIELD_LIMIT
|
|
1761
2157
|
})));
|
|
1762
2158
|
};
|
|
1763
|
-
|
|
1764
|
-
// packages/ui/react-ui-form/src/util/field.ts
|
|
1765
|
-
import { FormatEnum as FormatEnum3, GeoLocation as GeoLocation2, TypeEnum } from "@dxos/echo-schema";
|
|
1766
|
-
var parseValue = ({ type, format, value }) => {
|
|
1767
|
-
if (value === void 0 || value === null || value === "") {
|
|
1768
|
-
return void 0;
|
|
1769
|
-
}
|
|
1770
|
-
const parseScalar = (type2) => {
|
|
1771
|
-
switch (type2) {
|
|
1772
|
-
case TypeEnum.Boolean: {
|
|
1773
|
-
if (typeof value === "string") {
|
|
1774
|
-
const lowercaseValue = value.toLowerCase();
|
|
1775
|
-
if (lowercaseValue === "0" || lowercaseValue === "false") {
|
|
1776
|
-
return false;
|
|
1777
|
-
} else if (lowercaseValue === "1" || lowercaseValue === "true") {
|
|
1778
|
-
return true;
|
|
1779
|
-
}
|
|
1780
|
-
}
|
|
1781
|
-
return Boolean(value);
|
|
1782
|
-
}
|
|
1783
|
-
case TypeEnum.Number: {
|
|
1784
|
-
const cleaned = typeof value === "string" ? value.replace(/[^0-9.-]+/g, "") : value;
|
|
1785
|
-
const num = Number(cleaned);
|
|
1786
|
-
return Number.isNaN(num) ? null : num;
|
|
1787
|
-
}
|
|
1788
|
-
case TypeEnum.String:
|
|
1789
|
-
case TypeEnum.Ref:
|
|
1790
|
-
return String(value);
|
|
1791
|
-
default: {
|
|
1792
|
-
return value;
|
|
1793
|
-
}
|
|
1794
|
-
}
|
|
1795
|
-
};
|
|
1796
|
-
if (!format) {
|
|
1797
|
-
return parseScalar(type);
|
|
1798
|
-
}
|
|
1799
|
-
switch (format) {
|
|
1800
|
-
case FormatEnum3.Boolean:
|
|
1801
|
-
return parseScalar(TypeEnum.Boolean);
|
|
1802
|
-
case FormatEnum3.Number:
|
|
1803
|
-
case FormatEnum3.Percent:
|
|
1804
|
-
case FormatEnum3.Currency:
|
|
1805
|
-
return parseScalar(TypeEnum.Number);
|
|
1806
|
-
case FormatEnum3.String:
|
|
1807
|
-
case FormatEnum3.Markdown: {
|
|
1808
|
-
return parseScalar(TypeEnum.String);
|
|
1809
|
-
}
|
|
1810
|
-
case FormatEnum3.Ref:
|
|
1811
|
-
throw new Error(`unexpected format: ${FormatEnum3.Ref}`);
|
|
1812
|
-
case FormatEnum3.DateTime:
|
|
1813
|
-
case FormatEnum3.Date:
|
|
1814
|
-
case FormatEnum3.Time:
|
|
1815
|
-
case FormatEnum3.Timestamp: {
|
|
1816
|
-
const date = new Date(value);
|
|
1817
|
-
return isNaN(date.getTime()) ? null : date;
|
|
1818
|
-
}
|
|
1819
|
-
case FormatEnum3.GeoPoint: {
|
|
1820
|
-
if (typeof value === "string") {
|
|
1821
|
-
const cleaned = value.replace(/[^0-9.,-]+/g, "");
|
|
1822
|
-
const parts = cleaned.split(",");
|
|
1823
|
-
if (parts.length === 2) {
|
|
1824
|
-
const lat = parseFloat(parts[0]);
|
|
1825
|
-
const long = parseFloat(parts[1]);
|
|
1826
|
-
if (!isNaN(lat) && !isNaN(long)) {
|
|
1827
|
-
return GeoLocation2.toGeoPoint({
|
|
1828
|
-
latitude: lat,
|
|
1829
|
-
longitude: long
|
|
1830
|
-
});
|
|
1831
|
-
}
|
|
1832
|
-
}
|
|
1833
|
-
}
|
|
1834
|
-
return [
|
|
1835
|
-
0,
|
|
1836
|
-
0
|
|
1837
|
-
];
|
|
1838
|
-
}
|
|
1839
|
-
default: {
|
|
1840
|
-
return value;
|
|
1841
|
-
}
|
|
1842
|
-
}
|
|
1843
|
-
};
|
|
1844
|
-
var cellClassesForFieldType = ({ type, format }) => {
|
|
1845
|
-
if (!format) {
|
|
1846
|
-
switch (type) {
|
|
1847
|
-
case TypeEnum.Number:
|
|
1848
|
-
return [
|
|
1849
|
-
"text-right",
|
|
1850
|
-
"font-mono"
|
|
1851
|
-
];
|
|
1852
|
-
case TypeEnum.Boolean:
|
|
1853
|
-
return [
|
|
1854
|
-
"text-right",
|
|
1855
|
-
"font-mono"
|
|
1856
|
-
];
|
|
1857
|
-
case TypeEnum.String:
|
|
1858
|
-
return void 0;
|
|
1859
|
-
case TypeEnum.Ref:
|
|
1860
|
-
return void 0;
|
|
1861
|
-
default: {
|
|
1862
|
-
return void 0;
|
|
1863
|
-
}
|
|
1864
|
-
}
|
|
1865
|
-
}
|
|
1866
|
-
switch (format) {
|
|
1867
|
-
case FormatEnum3.Markdown:
|
|
1868
|
-
return void 0;
|
|
1869
|
-
case FormatEnum3.Time:
|
|
1870
|
-
case FormatEnum3.Timestamp:
|
|
1871
|
-
case FormatEnum3.DateTime:
|
|
1872
|
-
case FormatEnum3.Date:
|
|
1873
|
-
case FormatEnum3.Duration:
|
|
1874
|
-
return [
|
|
1875
|
-
"font-mono",
|
|
1876
|
-
"text-right"
|
|
1877
|
-
];
|
|
1878
|
-
case FormatEnum3.Currency:
|
|
1879
|
-
return [
|
|
1880
|
-
"text-right"
|
|
1881
|
-
];
|
|
1882
|
-
case FormatEnum3.JSON:
|
|
1883
|
-
case FormatEnum3.DID:
|
|
1884
|
-
return [
|
|
1885
|
-
"font-mono"
|
|
1886
|
-
];
|
|
1887
|
-
default:
|
|
1888
|
-
return void 0;
|
|
1889
|
-
}
|
|
1890
|
-
};
|
|
1891
|
-
var pathNotUniqueError = (path) => ({
|
|
1892
|
-
path: "path",
|
|
1893
|
-
message: `'${path}' is already present`
|
|
1894
|
-
});
|
|
1895
|
-
|
|
1896
|
-
// packages/ui/react-ui-form/src/util/formatting.ts
|
|
1897
|
-
import { format as formatDate } from "date-fns/format";
|
|
1898
|
-
import { FormatEnum as FormatEnum4, GeoLocation as GeoLocation3, TypeEnum as TypeEnum2 } from "@dxos/echo-schema";
|
|
1899
|
-
var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
|
|
1900
|
-
const formatScalar = (type2) => {
|
|
1901
|
-
switch (type2) {
|
|
1902
|
-
case TypeEnum2.Boolean:
|
|
1903
|
-
return value.toLocaleString().toUpperCase();
|
|
1904
|
-
case TypeEnum2.Number:
|
|
1905
|
-
return value.toLocaleString(locale);
|
|
1906
|
-
case TypeEnum2.String:
|
|
1907
|
-
case TypeEnum2.Ref:
|
|
1908
|
-
return String(value);
|
|
1909
|
-
default: {
|
|
1910
|
-
return String(value);
|
|
1911
|
-
}
|
|
1912
|
-
}
|
|
1913
|
-
};
|
|
1914
|
-
if (!format) {
|
|
1915
|
-
return formatScalar(type);
|
|
1916
|
-
}
|
|
1917
|
-
switch (format) {
|
|
1918
|
-
case FormatEnum4.Boolean: {
|
|
1919
|
-
return formatScalar(TypeEnum2.Boolean);
|
|
1920
|
-
}
|
|
1921
|
-
case FormatEnum4.Number: {
|
|
1922
|
-
return formatScalar(TypeEnum2.Number);
|
|
1923
|
-
}
|
|
1924
|
-
case FormatEnum4.String:
|
|
1925
|
-
case FormatEnum4.Ref: {
|
|
1926
|
-
return formatScalar(TypeEnum2.String);
|
|
1927
|
-
}
|
|
1928
|
-
case FormatEnum4.Percent: {
|
|
1929
|
-
return `${value * 100}%`;
|
|
1930
|
-
}
|
|
1931
|
-
case FormatEnum4.Currency: {
|
|
1932
|
-
return value.toLocaleString(locale, {
|
|
1933
|
-
style: "currency",
|
|
1934
|
-
currency: "USD",
|
|
1935
|
-
minimumFractionDigits: 2,
|
|
1936
|
-
maximumFractionDigits: 2
|
|
1937
|
-
});
|
|
1938
|
-
}
|
|
1939
|
-
case FormatEnum4.Date: {
|
|
1940
|
-
try {
|
|
1941
|
-
return formatDate(new Date(value), "yyyy-MM-dd");
|
|
1942
|
-
} catch (error) {
|
|
1943
|
-
return "Invalid Date";
|
|
1944
|
-
}
|
|
1945
|
-
}
|
|
1946
|
-
case FormatEnum4.Time: {
|
|
1947
|
-
try {
|
|
1948
|
-
return formatDate(new Date(value), "HH:mm:ss");
|
|
1949
|
-
} catch (error) {
|
|
1950
|
-
return "Invalid Time";
|
|
1951
|
-
}
|
|
1952
|
-
}
|
|
1953
|
-
case FormatEnum4.DateTime: {
|
|
1954
|
-
try {
|
|
1955
|
-
return formatDate(new Date(value), "yyyy-MM-dd HH:mm:ss");
|
|
1956
|
-
} catch (error) {
|
|
1957
|
-
return "Invalid DateTime";
|
|
1958
|
-
}
|
|
1959
|
-
}
|
|
1960
|
-
case FormatEnum4.GeoPoint: {
|
|
1961
|
-
if (value === null || value === void 0) {
|
|
1962
|
-
return "";
|
|
1963
|
-
}
|
|
1964
|
-
if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
|
|
1965
|
-
const { latitude, longitude } = GeoLocation3.fromGeoPoint(value);
|
|
1966
|
-
return `${latitude},${longitude}`;
|
|
1967
|
-
}
|
|
1968
|
-
return String(value);
|
|
1969
|
-
}
|
|
1970
|
-
default: {
|
|
1971
|
-
if (value === null || value === "undefined") {
|
|
1972
|
-
return "";
|
|
1973
|
-
}
|
|
1974
|
-
return String(value);
|
|
1975
|
-
}
|
|
1976
|
-
}
|
|
1977
|
-
};
|
|
1978
|
-
var formatForEditing = ({ type, format, value, locale = void 0 }) => {
|
|
1979
|
-
const formatScalar = (type2) => {
|
|
1980
|
-
switch (type2) {
|
|
1981
|
-
case TypeEnum2.Boolean:
|
|
1982
|
-
case TypeEnum2.Number:
|
|
1983
|
-
case TypeEnum2.String:
|
|
1984
|
-
case TypeEnum2.Ref:
|
|
1985
|
-
return String(value);
|
|
1986
|
-
default:
|
|
1987
|
-
return String(value);
|
|
1988
|
-
}
|
|
1989
|
-
};
|
|
1990
|
-
if (!format) {
|
|
1991
|
-
return formatScalar(type);
|
|
1992
|
-
}
|
|
1993
|
-
switch (format) {
|
|
1994
|
-
case FormatEnum4.Boolean:
|
|
1995
|
-
case FormatEnum4.Number:
|
|
1996
|
-
case FormatEnum4.String:
|
|
1997
|
-
case FormatEnum4.Ref: {
|
|
1998
|
-
return formatScalar(type);
|
|
1999
|
-
}
|
|
2000
|
-
case FormatEnum4.Percent: {
|
|
2001
|
-
return String(value * 100);
|
|
2002
|
-
}
|
|
2003
|
-
case FormatEnum4.Currency: {
|
|
2004
|
-
return String(value);
|
|
2005
|
-
}
|
|
2006
|
-
case FormatEnum4.DateTime: {
|
|
2007
|
-
const date = new Date(value);
|
|
2008
|
-
return date.toISOString();
|
|
2009
|
-
}
|
|
2010
|
-
case FormatEnum4.Date: {
|
|
2011
|
-
const date = new Date(value);
|
|
2012
|
-
return date.toISOString().split("T")[0];
|
|
2013
|
-
}
|
|
2014
|
-
case FormatEnum4.Time: {
|
|
2015
|
-
const date = new Date(value);
|
|
2016
|
-
return date.toISOString().split("T")[1].split(".")[0];
|
|
2017
|
-
}
|
|
2018
|
-
case FormatEnum4.GeoPoint: {
|
|
2019
|
-
if (value === null || value === void 0) {
|
|
2020
|
-
return "";
|
|
2021
|
-
}
|
|
2022
|
-
if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
|
|
2023
|
-
const { latitude, longitude } = GeoLocation3.fromGeoPoint(value);
|
|
2024
|
-
return `${latitude},${longitude}`;
|
|
2025
|
-
}
|
|
2026
|
-
return String(value);
|
|
2027
|
-
}
|
|
2028
|
-
default: {
|
|
2029
|
-
return String(value);
|
|
2030
|
-
}
|
|
2031
|
-
}
|
|
2032
|
-
};
|
|
2033
2159
|
export {
|
|
2034
2160
|
BooleanInput,
|
|
2035
2161
|
ControlFrame,
|
|
@@ -2057,8 +2183,10 @@ export {
|
|
|
2057
2183
|
ViewEditor,
|
|
2058
2184
|
cellClassesForFieldType,
|
|
2059
2185
|
controlItemClasses,
|
|
2186
|
+
findArrayElementType,
|
|
2060
2187
|
formatForDisplay,
|
|
2061
2188
|
formatForEditing,
|
|
2189
|
+
getRefProps,
|
|
2062
2190
|
parseValue,
|
|
2063
2191
|
pathNotUniqueError,
|
|
2064
2192
|
translations_default as translations,
|
|
@@ -2066,6 +2194,7 @@ export {
|
|
|
2066
2194
|
useFormContext,
|
|
2067
2195
|
useFormValues,
|
|
2068
2196
|
useInputProps,
|
|
2197
|
+
useQueryRefOptions,
|
|
2069
2198
|
useRefQueryLookupHandler
|
|
2070
2199
|
};
|
|
2071
2200
|
//# sourceMappingURL=index.mjs.map
|