@dxos/react-ui-form 0.7.4 → 0.7.5-labs.071a3e2
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 +841 -521
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +877 -571
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +841 -521
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts +2 -2
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
- package/dist/types/src/components/Form/ArrayField.d.ts +16 -0
- package/dist/types/src/components/Form/ArrayField.d.ts.map +1 -0
- package/dist/types/src/components/Form/Defaults.d.ts +5 -6
- package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.d.ts +14 -17
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts +7 -1
- package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormActions.d.ts +7 -0
- package/dist/types/src/components/Form/FormActions.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormContent.d.ts +26 -0
- package/dist/types/src/components/Form/FormContent.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormContext.d.ts +20 -0
- package/dist/types/src/components/Form/FormContext.d.ts.map +1 -0
- package/dist/types/src/components/Form/Input.d.ts +5 -6
- package/dist/types/src/components/Form/Input.d.ts.map +1 -1
- package/dist/types/src/components/Form/custom/GeoPointInput.d.ts +4 -0
- package/dist/types/src/components/Form/custom/GeoPointInput.d.ts.map +1 -0
- package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts +4 -0
- package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts.map +1 -0
- package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts +7 -0
- package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts.map +1 -0
- package/dist/types/src/components/Form/custom/TupleInput.d.ts +6 -0
- package/dist/types/src/components/Form/custom/TupleInput.d.ts.map +1 -0
- package/dist/types/src/components/Form/custom/index.d.ts +4 -0
- package/dist/types/src/components/Form/custom/index.d.ts.map +1 -0
- package/dist/types/src/components/Form/factory.d.ts +2 -2
- package/dist/types/src/components/Form/factory.d.ts.map +1 -1
- package/dist/types/src/components/Form/index.d.ts +2 -2
- package/dist/types/src/components/Form/index.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +6 -5
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/deprecated/FormInput.d.ts +5 -0
- package/dist/types/src/components/deprecated/FormInput.d.ts.map +1 -1
- package/dist/types/src/hooks/useForm.d.ts +13 -15
- package/dist/types/src/hooks/useForm.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +6 -0
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/package.json +28 -27
- package/src/components/FieldEditor/FieldEditor.stories.tsx +3 -3
- package/src/components/FieldEditor/FieldEditor.tsx +77 -51
- package/src/components/Form/ArrayField.tsx +111 -0
- package/src/components/Form/Defaults.tsx +20 -33
- package/src/components/Form/Form.stories.tsx +48 -6
- package/src/components/Form/Form.tsx +49 -329
- package/src/components/Form/FormActions.tsx +41 -0
- package/src/components/Form/FormContent.tsx +173 -0
- package/src/components/Form/FormContext.tsx +48 -0
- package/src/components/Form/Input.tsx +5 -6
- package/src/components/Form/custom/GeoPointInput.tsx +44 -0
- package/src/components/Form/custom/SelectOptionsInput.stories.tsx +58 -0
- package/src/components/Form/custom/SelectOptionsInput.tsx +192 -0
- package/src/components/Form/custom/TupleInput.tsx +49 -0
- package/src/components/Form/custom/index.ts +7 -0
- package/src/components/Form/factory.tsx +4 -7
- package/src/components/Form/index.ts +3 -2
- package/src/components/ViewEditor/ViewEditor.stories.tsx +30 -8
- package/src/components/ViewEditor/ViewEditor.tsx +18 -10
- package/src/components/deprecated/FormInput.tsx +20 -7
- package/src/hooks/useForm.ts +67 -79
- package/src/translations.ts +8 -0
- package/dist/types/src/components/Form/Custom.d.ts +0 -5
- package/dist/types/src/components/Form/Custom.d.ts.map +0 -1
- package/src/components/Form/Custom.tsx +0 -65
|
@@ -35,6 +35,7 @@ var translations_default = [
|
|
|
35
35
|
"format ref": "Reference",
|
|
36
36
|
"format regex": "RegExp",
|
|
37
37
|
"format string": "String",
|
|
38
|
+
"format single-select": "Select",
|
|
38
39
|
"format text": "Long text",
|
|
39
40
|
"format time": "Time",
|
|
40
41
|
"format timestamp": "Timestamp",
|
|
@@ -44,7 +45,13 @@ var translations_default = [
|
|
|
44
45
|
"format uuid": "UUID",
|
|
45
46
|
// Placeholders
|
|
46
47
|
"placeholder latitude": "Latitude",
|
|
47
|
-
"placeholder longitude": "Longitude"
|
|
48
|
+
"placeholder longitude": "Longitude",
|
|
49
|
+
// SelectOptionsInput
|
|
50
|
+
"select option label": "Label",
|
|
51
|
+
"select option label placeholder": "Option label",
|
|
52
|
+
"select option color": "Color",
|
|
53
|
+
"select option delete": "Delete",
|
|
54
|
+
"select option add": "Add option"
|
|
48
55
|
}
|
|
49
56
|
}
|
|
50
57
|
}
|
|
@@ -53,6 +60,16 @@ var translations_default = [
|
|
|
53
60
|
// packages/ui/react-ui-form/src/components/deprecated/FormInput.tsx
|
|
54
61
|
import React from "react";
|
|
55
62
|
import { Input } from "@dxos/react-ui";
|
|
63
|
+
import { mx, textBlockWidth } from "@dxos/react-ui-theme";
|
|
64
|
+
var DeprecatedFormContainer = ({ children, classNames }) => {
|
|
65
|
+
return /* @__PURE__ */ React.createElement("div", {
|
|
66
|
+
role: "none",
|
|
67
|
+
className: "w-full p-4 justify-center overflow-x-hidden overflow-y-auto"
|
|
68
|
+
}, /* @__PURE__ */ React.createElement("div", {
|
|
69
|
+
role: "form",
|
|
70
|
+
className: mx("flex flex-col", textBlockWidth, classNames)
|
|
71
|
+
}, children));
|
|
72
|
+
};
|
|
56
73
|
var DeprecatedFormInput = ({ label, description, secondary, children }) => {
|
|
57
74
|
const primary = /* @__PURE__ */ React.createElement("div", {
|
|
58
75
|
role: "none",
|
|
@@ -61,46 +78,37 @@ var DeprecatedFormInput = ({ label, description, secondary, children }) => {
|
|
|
61
78
|
role: "none",
|
|
62
79
|
className: "flex flex-col w-full"
|
|
63
80
|
}, /* @__PURE__ */ React.createElement(Input.Label, {
|
|
64
|
-
classNames: "flex min-
|
|
81
|
+
classNames: "flex min-bs-[--rail-action] items-center",
|
|
82
|
+
style: {
|
|
83
|
+
fontSize: "unset"
|
|
84
|
+
}
|
|
65
85
|
}, label), description && /* @__PURE__ */ React.createElement(Input.DescriptionAndValidation, {
|
|
66
86
|
classNames: "mbs-0.5"
|
|
67
87
|
}, /* @__PURE__ */ React.createElement(Input.Description, null, description))), /* @__PURE__ */ React.createElement("div", {
|
|
68
88
|
role: "none"
|
|
69
89
|
}, /* @__PURE__ */ React.createElement("div", {
|
|
70
90
|
role: "none",
|
|
71
|
-
className: "flex min-
|
|
91
|
+
className: "flex min-bs-[--rail-action] items-center"
|
|
72
92
|
}, children))));
|
|
73
93
|
if (secondary) {
|
|
74
94
|
return /* @__PURE__ */ React.createElement("div", {
|
|
75
|
-
role: "none"
|
|
76
|
-
className: "flex flex-col w-full"
|
|
95
|
+
role: "none"
|
|
77
96
|
}, primary, secondary);
|
|
78
97
|
}
|
|
79
98
|
return primary;
|
|
80
99
|
};
|
|
81
100
|
|
|
82
101
|
// packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx
|
|
83
|
-
import
|
|
102
|
+
import React12, { useCallback as useCallback4, useEffect as useEffect4, useMemo as useMemo5, useState as useState3 } from "react";
|
|
84
103
|
import { FormatEnum as FormatEnum2, FormatEnums, formatToType } from "@dxos/echo-schema";
|
|
85
|
-
import { log as log3 } from "@dxos/log";
|
|
86
|
-
import { useTranslation as useTranslation3 } from "@dxos/react-ui";
|
|
87
|
-
import { getFormatSchema, getSchemaProperties as getSchemaProperties2, sortProperties } from "@dxos/schema";
|
|
88
|
-
|
|
89
|
-
// packages/ui/react-ui-form/src/components/Form/Form.tsx
|
|
90
|
-
import { pipe } from "effect";
|
|
91
|
-
import { capitalize } from "effect/String";
|
|
92
|
-
import React5, { useEffect as useEffect2, useMemo as useMemo2 } from "react";
|
|
93
|
-
import { AST, S } from "@dxos/echo-schema";
|
|
94
|
-
import { findNode, getDiscriminatedType, isDiscriminatedUnion, SimpleType } from "@dxos/effect";
|
|
95
104
|
import { log as log2 } from "@dxos/log";
|
|
96
|
-
import {
|
|
97
|
-
import {
|
|
98
|
-
import { getSchemaProperties } from "@dxos/schema";
|
|
99
|
-
import { isNotFalsy } from "@dxos/util";
|
|
105
|
+
import { useTranslation as useTranslation5 } from "@dxos/react-ui";
|
|
106
|
+
import { getFormatSchema, getSchemaProperties as getSchemaProperties3, sortProperties } from "@dxos/schema";
|
|
100
107
|
|
|
101
|
-
// packages/ui/react-ui-form/src/components/Form/
|
|
108
|
+
// packages/ui/react-ui-form/src/components/Form/custom/GeoPointInput.tsx
|
|
102
109
|
import React3 from "react";
|
|
103
|
-
import { Input as Input2,
|
|
110
|
+
import { Input as Input2, useTranslation } from "@dxos/react-ui";
|
|
111
|
+
import { safeParseFloat } from "@dxos/util";
|
|
104
112
|
|
|
105
113
|
// packages/ui/react-ui-form/src/components/Form/Input.tsx
|
|
106
114
|
import React2 from "react";
|
|
@@ -121,164 +129,382 @@ var InputHeader = ({ children, error }) => {
|
|
|
121
129
|
}, /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null), error)));
|
|
122
130
|
};
|
|
123
131
|
|
|
124
|
-
// packages/ui/react-ui-form/src/components/Form/
|
|
125
|
-
var
|
|
126
|
-
const {
|
|
132
|
+
// packages/ui/react-ui-form/src/components/Form/custom/GeoPointInput.tsx
|
|
133
|
+
var GeoPointInput = ({ type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
134
|
+
const { t } = useTranslation(translationKey);
|
|
135
|
+
const { status, error } = getStatus();
|
|
136
|
+
const [lng = 0, lat = 0] = getValue3() ?? [];
|
|
127
137
|
return /* @__PURE__ */ React3.createElement(Input2.Root, {
|
|
128
138
|
validationValence: status
|
|
129
|
-
},
|
|
139
|
+
}, /* @__PURE__ */ React3.createElement(InputHeader, {
|
|
140
|
+
error
|
|
141
|
+
}, /* @__PURE__ */ React3.createElement(Input2.Label, null, label)), /* @__PURE__ */ React3.createElement("div", {
|
|
142
|
+
className: "grid grid-cols-2 gap-2"
|
|
143
|
+
}, /* @__PURE__ */ React3.createElement(Input2.TextInput, {
|
|
144
|
+
type: "number",
|
|
145
|
+
disabled,
|
|
146
|
+
placeholder: t("placeholder longitude"),
|
|
147
|
+
value: lng,
|
|
148
|
+
onChange: (event) => onValueChange(type, [
|
|
149
|
+
lat,
|
|
150
|
+
safeParseFloat(event.target.value, 0)
|
|
151
|
+
]),
|
|
152
|
+
onBlur
|
|
153
|
+
}), /* @__PURE__ */ React3.createElement(Input2.TextInput, {
|
|
154
|
+
type: "number",
|
|
155
|
+
disabled,
|
|
156
|
+
placeholder: t("placeholder latitude"),
|
|
157
|
+
value: lat,
|
|
158
|
+
onChange: (event) => onValueChange(type, [
|
|
159
|
+
safeParseFloat(event.target.value, 0),
|
|
160
|
+
lng
|
|
161
|
+
]),
|
|
162
|
+
onBlur
|
|
163
|
+
})));
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
// packages/ui/react-ui-form/src/components/Form/custom/SelectOptionsInput.tsx
|
|
167
|
+
import React4, { useCallback, useEffect, useState, useRef } from "react";
|
|
168
|
+
import { PublicKey } from "@dxos/keys";
|
|
169
|
+
import { Icon as Icon2, IconButton, Input as Input3, Tag, Toolbar, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
170
|
+
import { List } from "@dxos/react-ui-list";
|
|
171
|
+
import { HuePickerToolbarButton } from "@dxos/react-ui-pickers";
|
|
172
|
+
import { hueTokenThemes, mx as mx2 } from "@dxos/react-ui-theme";
|
|
173
|
+
var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3, onValueChange }) => {
|
|
174
|
+
const [selected, setSelectedId] = useState(null);
|
|
175
|
+
const [isNewOption, setIsNewOption] = useState(false);
|
|
176
|
+
const inputRef = useRef(null);
|
|
177
|
+
const { t } = useTranslation2(translationKey);
|
|
178
|
+
const { status, error } = getStatus();
|
|
179
|
+
const options = getValue3();
|
|
180
|
+
useEffect(() => {
|
|
181
|
+
if (options === void 0) {
|
|
182
|
+
onValueChange(type, []);
|
|
183
|
+
}
|
|
184
|
+
}, [
|
|
185
|
+
options,
|
|
186
|
+
onValueChange,
|
|
187
|
+
type
|
|
188
|
+
]);
|
|
189
|
+
const randomHue = () => {
|
|
190
|
+
const usedHues = new Set(options?.map((option) => option.color) ?? []);
|
|
191
|
+
const hueKeys = Object.keys(hueTokenThemes);
|
|
192
|
+
const unusedHues = hueKeys.filter((hue) => !usedHues.has(hue));
|
|
193
|
+
if (unusedHues.length > 0) {
|
|
194
|
+
return unusedHues[Math.floor(Math.random() * unusedHues.length)];
|
|
195
|
+
}
|
|
196
|
+
const lastThree = new Set(options?.slice(-3).map((option) => option.color) ?? []);
|
|
197
|
+
const availableHues = hueKeys.filter((hue) => !lastThree.has(hue));
|
|
198
|
+
return availableHues[Math.floor(Math.random() * availableHues.length)] ?? hueKeys[Math.floor(Math.random() * hueKeys.length)];
|
|
199
|
+
};
|
|
200
|
+
const handleAdd = useCallback(() => {
|
|
201
|
+
const newId = PublicKey.random().truncate();
|
|
202
|
+
const newOption = {
|
|
203
|
+
id: newId,
|
|
204
|
+
title: "",
|
|
205
|
+
color: randomHue()
|
|
206
|
+
};
|
|
207
|
+
onValueChange(type, [
|
|
208
|
+
...options ?? [],
|
|
209
|
+
newOption
|
|
210
|
+
]);
|
|
211
|
+
setSelectedId(newId);
|
|
212
|
+
setIsNewOption(true);
|
|
213
|
+
}, [
|
|
214
|
+
options,
|
|
215
|
+
type,
|
|
216
|
+
onValueChange
|
|
217
|
+
]);
|
|
218
|
+
const handleDelete = useCallback((id) => {
|
|
219
|
+
const newOptions = options?.filter((option) => option.id !== id) ?? [];
|
|
220
|
+
onValueChange(type, newOptions);
|
|
221
|
+
setSelectedId(null);
|
|
222
|
+
}, [
|
|
223
|
+
options,
|
|
224
|
+
type,
|
|
225
|
+
onValueChange
|
|
226
|
+
]);
|
|
227
|
+
const handleMove = useCallback((from, to) => {
|
|
228
|
+
if (!options) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
const newOptions = [
|
|
232
|
+
...options
|
|
233
|
+
];
|
|
234
|
+
const [removed] = newOptions.splice(from, 1);
|
|
235
|
+
newOptions.splice(to, 0, removed);
|
|
236
|
+
onValueChange(type, newOptions);
|
|
237
|
+
}, [
|
|
238
|
+
options,
|
|
239
|
+
type,
|
|
240
|
+
onValueChange
|
|
241
|
+
]);
|
|
242
|
+
const handleClick = useCallback((id) => {
|
|
243
|
+
setSelectedId((current) => current === id ? null : id);
|
|
244
|
+
}, []);
|
|
245
|
+
const handleTitleChange = useCallback((id) => (e) => {
|
|
246
|
+
const newOptions = options?.map((o) => o.id === id ? {
|
|
247
|
+
...o,
|
|
248
|
+
title: e.target.value
|
|
249
|
+
} : o);
|
|
250
|
+
onValueChange(type, newOptions ?? []);
|
|
251
|
+
}, [
|
|
252
|
+
options,
|
|
253
|
+
type,
|
|
254
|
+
onValueChange
|
|
255
|
+
]);
|
|
256
|
+
const handleKeyDown = useCallback((e) => {
|
|
257
|
+
if (e.key === "Enter") {
|
|
258
|
+
setSelectedId(null);
|
|
259
|
+
}
|
|
260
|
+
}, []);
|
|
261
|
+
const handleColorChange = useCallback((id) => (hue) => {
|
|
262
|
+
const newOptions = options?.map((o) => o.id === id ? {
|
|
263
|
+
...o,
|
|
264
|
+
color: hue
|
|
265
|
+
} : o);
|
|
266
|
+
onValueChange(type, newOptions ?? []);
|
|
267
|
+
}, [
|
|
268
|
+
options,
|
|
269
|
+
type,
|
|
270
|
+
onValueChange
|
|
271
|
+
]);
|
|
272
|
+
useEffect(() => {
|
|
273
|
+
if (selected && isNewOption && inputRef.current) {
|
|
274
|
+
inputRef.current.focus();
|
|
275
|
+
setIsNewOption(false);
|
|
276
|
+
}
|
|
277
|
+
}, [
|
|
278
|
+
selected,
|
|
279
|
+
isNewOption
|
|
280
|
+
]);
|
|
281
|
+
return /* @__PURE__ */ React4.createElement(Input3.Root, {
|
|
282
|
+
validationValence: status
|
|
283
|
+
}, /* @__PURE__ */ React4.createElement(InputHeader, {
|
|
284
|
+
error
|
|
285
|
+
}, /* @__PURE__ */ React4.createElement(Input3.Label, null, label)), /* @__PURE__ */ React4.createElement("div", {
|
|
286
|
+
role: "none"
|
|
287
|
+
}, options && /* @__PURE__ */ React4.createElement(List.Root, {
|
|
288
|
+
items: options,
|
|
289
|
+
isItem: (item) => true,
|
|
290
|
+
onMove: handleMove
|
|
291
|
+
}, ({ items }) => /* @__PURE__ */ React4.createElement("div", {
|
|
292
|
+
role: "list",
|
|
293
|
+
className: "w-full overflow-auto"
|
|
294
|
+
}, items?.map((item) => /* @__PURE__ */ React4.createElement("div", {
|
|
295
|
+
key: item.id
|
|
296
|
+
}, /* @__PURE__ */ React4.createElement(List.Item, {
|
|
297
|
+
role: "button",
|
|
298
|
+
item,
|
|
299
|
+
classNames: mx2("p-1 plb-2", "flex flex-col", "cursor-pointer", "hover:bg-hoverOverlay"),
|
|
300
|
+
"aria-expanded": selected === item.id
|
|
301
|
+
}, /* @__PURE__ */ React4.createElement("div", {
|
|
302
|
+
className: "flex items-center"
|
|
303
|
+
}, /* @__PURE__ */ React4.createElement(List.ItemDragHandle, null), /* @__PURE__ */ React4.createElement(List.ItemTitle, {
|
|
304
|
+
onClick: () => handleClick(item.id),
|
|
305
|
+
classNames: "flex-1"
|
|
306
|
+
}, /* @__PURE__ */ React4.createElement(Tag, {
|
|
307
|
+
palette: item.color
|
|
308
|
+
}, item.title || "\u200B")), /* @__PURE__ */ React4.createElement(Icon2, {
|
|
309
|
+
icon: selected === item.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
|
|
310
|
+
onClick: () => handleClick(item.id)
|
|
311
|
+
})), selected === item.id && /* @__PURE__ */ React4.createElement("div", {
|
|
312
|
+
className: "mis-4 mbs-2 flex flex-col gap-1"
|
|
313
|
+
}, /* @__PURE__ */ React4.createElement(Input3.Label, {
|
|
314
|
+
classNames: "text-xs"
|
|
315
|
+
}, t("select option label")), /* @__PURE__ */ React4.createElement("div", {
|
|
316
|
+
className: "flex flex-row items-center gap-1"
|
|
317
|
+
}, /* @__PURE__ */ React4.createElement(Input3.TextInput, {
|
|
318
|
+
placeholder: t("select option label placeholder"),
|
|
319
|
+
ref: selected === item.id ? inputRef : void 0,
|
|
320
|
+
value: item.title,
|
|
321
|
+
onChange: handleTitleChange(item.id),
|
|
322
|
+
onKeyDown: handleKeyDown,
|
|
323
|
+
classNames: "flex-1"
|
|
324
|
+
}), /* @__PURE__ */ React4.createElement(Toolbar.Root, {
|
|
325
|
+
classNames: "p-0 m-0 !is-auto"
|
|
326
|
+
}, /* @__PURE__ */ React4.createElement(HuePickerToolbarButton, {
|
|
327
|
+
hue: item.color,
|
|
328
|
+
onChangeHue: handleColorChange(item.id)
|
|
329
|
+
})), /* @__PURE__ */ React4.createElement(IconButton, {
|
|
330
|
+
icon: "ph--trash--fill",
|
|
331
|
+
iconOnly: true,
|
|
332
|
+
label: t("select option delete"),
|
|
333
|
+
onClick: () => handleDelete(item.id)
|
|
334
|
+
})))))), /* @__PURE__ */ React4.createElement("div", {
|
|
335
|
+
role: "listitem"
|
|
336
|
+
}, /* @__PURE__ */ React4.createElement("div", {
|
|
337
|
+
role: "button",
|
|
338
|
+
className: mx2("p-1 plb-2", "flex flex-col", "cursor-pointer", "hover:bg-hoverOverlay"),
|
|
339
|
+
onClick: handleAdd
|
|
340
|
+
}, /* @__PURE__ */ React4.createElement("div", {
|
|
341
|
+
className: "flex items-center gap-1"
|
|
342
|
+
}, /* @__PURE__ */ React4.createElement(Icon2, {
|
|
343
|
+
icon: "ph--plus--regular"
|
|
344
|
+
}), /* @__PURE__ */ React4.createElement("span", {
|
|
345
|
+
className: "text-sm"
|
|
346
|
+
}, t("select option add")))))))));
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
// packages/ui/react-ui-form/src/components/Form/custom/TupleInput.tsx
|
|
350
|
+
import React5 from "react";
|
|
351
|
+
import { Input as Input4 } from "@dxos/react-ui";
|
|
352
|
+
import { mx as mx3 } from "@dxos/react-ui-theme";
|
|
353
|
+
import { safeParseFloat as safeParseFloat2 } from "@dxos/util";
|
|
354
|
+
var gridCols = [
|
|
355
|
+
"grid-cols-1",
|
|
356
|
+
"grid-cols-2",
|
|
357
|
+
"grid-cols-3",
|
|
358
|
+
"grid-cols-4"
|
|
359
|
+
];
|
|
360
|
+
var TupleInput = ({ binding, type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
361
|
+
const { status, error } = getStatus();
|
|
362
|
+
const values = getValue3() ?? {};
|
|
363
|
+
return /* @__PURE__ */ React5.createElement(Input4.Root, {
|
|
364
|
+
validationValence: status
|
|
365
|
+
}, /* @__PURE__ */ React5.createElement(InputHeader, {
|
|
366
|
+
error
|
|
367
|
+
}, /* @__PURE__ */ React5.createElement(Input4.Label, null, label)), /* @__PURE__ */ React5.createElement("div", {
|
|
368
|
+
className: mx3("grid gap-2", gridCols[binding.length - 1])
|
|
369
|
+
}, binding.map((prop) => /* @__PURE__ */ React5.createElement(Input4.TextInput, {
|
|
370
|
+
key: prop,
|
|
371
|
+
type: "number",
|
|
372
|
+
disabled,
|
|
373
|
+
value: values[prop],
|
|
374
|
+
onChange: (event) => onValueChange(type, {
|
|
375
|
+
...values,
|
|
376
|
+
[prop]: safeParseFloat2(event.target.value, 0)
|
|
377
|
+
}),
|
|
378
|
+
onBlur
|
|
379
|
+
}))));
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
// packages/ui/react-ui-form/src/components/Form/Defaults.tsx
|
|
383
|
+
import React6 from "react";
|
|
384
|
+
import { Input as Input5, Select } from "@dxos/react-ui";
|
|
385
|
+
var TextInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
386
|
+
const { status, error } = getStatus();
|
|
387
|
+
return /* @__PURE__ */ React6.createElement(Input5.Root, {
|
|
388
|
+
validationValence: status
|
|
389
|
+
}, !inputOnly && /* @__PURE__ */ React6.createElement(InputHeader, {
|
|
130
390
|
error
|
|
131
|
-
}, /* @__PURE__ */
|
|
391
|
+
}, /* @__PURE__ */ React6.createElement(Input5.Label, null, label)), /* @__PURE__ */ React6.createElement(Input5.TextInput, {
|
|
132
392
|
disabled,
|
|
133
393
|
placeholder,
|
|
134
|
-
value:
|
|
135
|
-
onChange: (event) => onValueChange(
|
|
394
|
+
value: getValue3() ?? "",
|
|
395
|
+
onChange: (event) => onValueChange(type, event.target.value),
|
|
136
396
|
onBlur
|
|
137
|
-
}), inputOnly && /* @__PURE__ */
|
|
397
|
+
}), inputOnly && /* @__PURE__ */ React6.createElement(Input5.Validation, null, error));
|
|
138
398
|
};
|
|
139
|
-
var NumberInput = ({
|
|
140
|
-
const { status, error } = getStatus
|
|
141
|
-
return /* @__PURE__ */
|
|
399
|
+
var NumberInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
400
|
+
const { status, error } = getStatus();
|
|
401
|
+
return /* @__PURE__ */ React6.createElement(Input5.Root, {
|
|
142
402
|
validationValence: status
|
|
143
|
-
}, !inputOnly && /* @__PURE__ */
|
|
403
|
+
}, !inputOnly && /* @__PURE__ */ React6.createElement(InputHeader, {
|
|
144
404
|
error
|
|
145
|
-
}, /* @__PURE__ */
|
|
405
|
+
}, /* @__PURE__ */ React6.createElement(Input5.Label, null, label)), /* @__PURE__ */ React6.createElement(Input5.TextInput, {
|
|
146
406
|
type: "number",
|
|
147
407
|
disabled,
|
|
148
408
|
placeholder,
|
|
149
|
-
value:
|
|
150
|
-
onChange: (event) => onValueChange(
|
|
409
|
+
value: getValue3() ?? 0,
|
|
410
|
+
onChange: (event) => onValueChange(type, event.target.value),
|
|
151
411
|
onBlur
|
|
152
|
-
}), inputOnly && /* @__PURE__ */
|
|
412
|
+
}), inputOnly && /* @__PURE__ */ React6.createElement(Input5.DescriptionAndValidation, null, error));
|
|
153
413
|
};
|
|
154
|
-
var BooleanInput = ({
|
|
155
|
-
const { status, error } = getStatus
|
|
156
|
-
return /* @__PURE__ */
|
|
414
|
+
var BooleanInput = ({ type, label, inputOnly, getStatus, getValue: getValue3, onValueChange }) => {
|
|
415
|
+
const { status, error } = getStatus();
|
|
416
|
+
return /* @__PURE__ */ React6.createElement(Input5.Root, {
|
|
157
417
|
validationValence: status
|
|
158
|
-
}, !inputOnly && /* @__PURE__ */
|
|
418
|
+
}, !inputOnly && /* @__PURE__ */ React6.createElement(InputHeader, {
|
|
159
419
|
error
|
|
160
|
-
}, /* @__PURE__ */
|
|
161
|
-
checked:
|
|
162
|
-
onCheckedChange: (value) => onValueChange(
|
|
163
|
-
}), inputOnly && /* @__PURE__ */
|
|
420
|
+
}, /* @__PURE__ */ React6.createElement(Input5.Label, null, label)), /* @__PURE__ */ React6.createElement(Input5.Switch, {
|
|
421
|
+
checked: getValue3(),
|
|
422
|
+
onCheckedChange: (value) => onValueChange(type, value)
|
|
423
|
+
}), inputOnly && /* @__PURE__ */ React6.createElement(Input5.DescriptionAndValidation, null, error));
|
|
164
424
|
};
|
|
165
|
-
var SelectInput = ({
|
|
166
|
-
const { status, error } = getStatus
|
|
167
|
-
return /* @__PURE__ */
|
|
425
|
+
var SelectInput = ({ type, label, inputOnly, disabled, placeholder, options, getStatus, getValue: getValue3, onValueChange }) => {
|
|
426
|
+
const { status, error } = getStatus();
|
|
427
|
+
return /* @__PURE__ */ React6.createElement(Input5.Root, {
|
|
168
428
|
validationValence: status
|
|
169
|
-
}, !inputOnly && /* @__PURE__ */
|
|
429
|
+
}, !inputOnly && /* @__PURE__ */ React6.createElement(InputHeader, {
|
|
170
430
|
error
|
|
171
|
-
}, /* @__PURE__ */
|
|
172
|
-
value:
|
|
173
|
-
onValueChange: (value) => onValueChange(
|
|
174
|
-
}, /* @__PURE__ */
|
|
431
|
+
}, /* @__PURE__ */ React6.createElement(Input5.Label, null, label)), /* @__PURE__ */ React6.createElement(Select.Root, {
|
|
432
|
+
value: getValue3(),
|
|
433
|
+
onValueChange: (value) => onValueChange(type, value)
|
|
434
|
+
}, /* @__PURE__ */ React6.createElement(Select.TriggerButton, {
|
|
175
435
|
classNames: "is-full",
|
|
176
436
|
disabled,
|
|
177
437
|
placeholder
|
|
178
|
-
}), /* @__PURE__ */
|
|
438
|
+
}), /* @__PURE__ */ React6.createElement(Select.Portal, null, /* @__PURE__ */ React6.createElement(Select.Content, null, /* @__PURE__ */ React6.createElement(Select.Viewport, null, options?.map(({ value, label: label2 }) => (
|
|
179
439
|
// NOTE: Numeric values are converted to and from strings.
|
|
180
|
-
/* @__PURE__ */
|
|
440
|
+
/* @__PURE__ */ React6.createElement(Select.Option, {
|
|
181
441
|
key: String(value),
|
|
182
442
|
value: String(value)
|
|
183
443
|
}, label2 ?? String(value))
|
|
184
|
-
)))))), inputOnly && /* @__PURE__ */
|
|
444
|
+
)))))), inputOnly && /* @__PURE__ */ React6.createElement(Input5.DescriptionAndValidation, null, error));
|
|
185
445
|
};
|
|
186
446
|
|
|
187
|
-
// packages/ui/react-ui-form/src/components/Form/
|
|
188
|
-
import {
|
|
447
|
+
// packages/ui/react-ui-form/src/components/Form/Form.tsx
|
|
448
|
+
import React11, { useEffect as useEffect3, useMemo as useMemo4 } from "react";
|
|
449
|
+
import { mx as mx7 } from "@dxos/react-ui-theme";
|
|
189
450
|
|
|
190
|
-
// packages/ui/react-ui-form/src/components/Form/
|
|
191
|
-
import
|
|
192
|
-
import {
|
|
193
|
-
|
|
194
|
-
const { t } = useTranslation(translationKey);
|
|
195
|
-
const { status, error } = getStatus?.(property);
|
|
196
|
-
const [lng = 0, lat = 0] = getValue(property) ?? [];
|
|
197
|
-
return /* @__PURE__ */ React4.createElement(Input3.Root, {
|
|
198
|
-
validationValence: status
|
|
199
|
-
}, /* @__PURE__ */ React4.createElement(InputHeader, {
|
|
200
|
-
error
|
|
201
|
-
}, /* @__PURE__ */ React4.createElement(Input3.Label, null, label)), /* @__PURE__ */ React4.createElement("div", {
|
|
202
|
-
className: "grid grid-cols-2 gap-2"
|
|
203
|
-
}, /* @__PURE__ */ React4.createElement(Input3.TextInput, {
|
|
204
|
-
type: "number",
|
|
205
|
-
disabled,
|
|
206
|
-
placeholder: t("placeholder longitude"),
|
|
207
|
-
value: lng,
|
|
208
|
-
onChange: (event) => onValueChange(property, type, [
|
|
209
|
-
lat,
|
|
210
|
-
safeParseFloat(event.target.value, 0)
|
|
211
|
-
]),
|
|
212
|
-
onBlur
|
|
213
|
-
}), /* @__PURE__ */ React4.createElement(Input3.TextInput, {
|
|
214
|
-
type: "number",
|
|
215
|
-
disabled,
|
|
216
|
-
placeholder: t("placeholder latitude"),
|
|
217
|
-
value: lat,
|
|
218
|
-
onChange: (event) => onValueChange(property, type, [
|
|
219
|
-
safeParseFloat(event.target.value, 0),
|
|
220
|
-
lng
|
|
221
|
-
]),
|
|
222
|
-
onBlur
|
|
223
|
-
})));
|
|
224
|
-
};
|
|
225
|
-
var safeParseFloat = (str, defaultValue) => {
|
|
226
|
-
try {
|
|
227
|
-
return parseFloat(str);
|
|
228
|
-
} catch {
|
|
229
|
-
return defaultValue ?? 0;
|
|
230
|
-
}
|
|
231
|
-
};
|
|
451
|
+
// packages/ui/react-ui-form/src/components/Form/FormActions.tsx
|
|
452
|
+
import React8 from "react";
|
|
453
|
+
import { IconButton as IconButton2, useTranslation as useTranslation3 } from "@dxos/react-ui";
|
|
454
|
+
import { mx as mx4 } from "@dxos/react-ui-theme";
|
|
232
455
|
|
|
233
|
-
// packages/ui/react-ui-form/src/components/Form/
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
}
|
|
239
|
-
switch (type) {
|
|
240
|
-
case "string":
|
|
241
|
-
return TextInput;
|
|
242
|
-
case "number":
|
|
243
|
-
return NumberInput;
|
|
244
|
-
case "boolean":
|
|
245
|
-
return BooleanInput;
|
|
246
|
-
}
|
|
247
|
-
};
|
|
456
|
+
// packages/ui/react-ui-form/src/components/Form/FormContext.tsx
|
|
457
|
+
import React7, { createContext, useContext } from "react";
|
|
458
|
+
import { raise } from "@dxos/debug";
|
|
459
|
+
import { getValue as getValue2 } from "@dxos/echo-schema";
|
|
460
|
+
import { createJsonPath as createJsonPath2 } from "@dxos/effect";
|
|
248
461
|
|
|
249
462
|
// packages/ui/react-ui-form/src/hooks/useForm.ts
|
|
250
|
-
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
463
|
+
import { useCallback as useCallback2, useEffect as useEffect2, useMemo, useState as useState2 } from "react";
|
|
464
|
+
import { getValue, setValue } from "@dxos/echo-schema";
|
|
465
|
+
import { AST, createJsonPath, fromEffectValidationPath } from "@dxos/effect";
|
|
251
466
|
import { invariant } from "@dxos/invariant";
|
|
252
467
|
import { log } from "@dxos/log";
|
|
253
468
|
import { validateSchema } from "@dxos/schema";
|
|
254
469
|
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/hooks/useForm.ts";
|
|
255
470
|
var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, onSave }) => {
|
|
256
|
-
|
|
257
|
-
|
|
471
|
+
invariant(AST.isTypeLiteral(schema.ast), void 0, {
|
|
472
|
+
F: __dxlog_file,
|
|
473
|
+
L: 91,
|
|
474
|
+
S: void 0,
|
|
475
|
+
A: [
|
|
476
|
+
"AST.isTypeLiteral(schema.ast)",
|
|
477
|
+
""
|
|
478
|
+
]
|
|
479
|
+
});
|
|
480
|
+
const [values, setValues] = useState2(initialValues);
|
|
481
|
+
useEffect2(() => {
|
|
258
482
|
setValues(initialValues);
|
|
259
483
|
}, [
|
|
260
484
|
initialValues
|
|
261
485
|
]);
|
|
262
|
-
const [touched, setTouched] =
|
|
263
|
-
const [changed, setChanged] =
|
|
264
|
-
const [errors, setErrors] =
|
|
265
|
-
const [saving, setSaving] =
|
|
266
|
-
const validate =
|
|
486
|
+
const [touched, setTouched] = useState2(createKeySet(initialValues, false));
|
|
487
|
+
const [changed, setChanged] = useState2(createKeySet(initialValues, false));
|
|
488
|
+
const [errors, setErrors] = useState2({});
|
|
489
|
+
const [saving, setSaving] = useState2(false);
|
|
490
|
+
const validate = useCallback2((values2) => {
|
|
267
491
|
let errors2 = validateSchema(schema, values2) ?? [];
|
|
268
492
|
if (errors2.length === 0 && onValidate) {
|
|
269
|
-
|
|
493
|
+
const validatedValues = values2;
|
|
494
|
+
errors2 = onValidate(validatedValues) ?? [];
|
|
270
495
|
}
|
|
271
496
|
setErrors(flatMap(errors2));
|
|
272
|
-
|
|
497
|
+
const valid = errors2.length === 0;
|
|
498
|
+
return valid;
|
|
273
499
|
}, [
|
|
274
500
|
schema,
|
|
275
501
|
onValidate
|
|
276
502
|
]);
|
|
277
|
-
const [schemaDirty, setSchemaDirty] =
|
|
278
|
-
|
|
503
|
+
const [schemaDirty, setSchemaDirty] = useState2(false);
|
|
504
|
+
useEffect2(() => setSchemaDirty(true), [
|
|
279
505
|
schema
|
|
280
506
|
]);
|
|
281
|
-
|
|
507
|
+
useEffect2(() => {
|
|
282
508
|
if (schemaDirty) {
|
|
283
509
|
validate(values);
|
|
284
510
|
setSchemaDirty(false);
|
|
@@ -287,13 +513,13 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
287
513
|
values,
|
|
288
514
|
schemaDirty
|
|
289
515
|
]);
|
|
290
|
-
const canSave = useMemo(() => !saving &&
|
|
291
|
-
|
|
516
|
+
const canSave = useMemo(() => !saving && // Check if any error paths that are touched have errors
|
|
517
|
+
!Object.entries(touched).some(([path, isTouched]) => isTouched && Object.keys(errors).some((errorPath) => errorPath === path || errorPath.startsWith(`${path}.`) || errorPath.startsWith(`${path}[`))), [
|
|
292
518
|
touched,
|
|
293
519
|
errors,
|
|
294
520
|
saving
|
|
295
521
|
]);
|
|
296
|
-
const handleSave =
|
|
522
|
+
const handleSave = useCallback2(async () => {
|
|
297
523
|
if (validate(values)) {
|
|
298
524
|
setSaving(true);
|
|
299
525
|
try {
|
|
@@ -307,19 +533,24 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
307
533
|
}, [
|
|
308
534
|
values,
|
|
309
535
|
validate,
|
|
310
|
-
onSave
|
|
536
|
+
onSave,
|
|
537
|
+
changed
|
|
311
538
|
]);
|
|
312
|
-
const getStatus =
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
539
|
+
const getStatus = useCallback2((path) => {
|
|
540
|
+
const jsonPath = Array.isArray(path) ? createJsonPath(path) : path;
|
|
541
|
+
const matchingError = Object.entries(errors).find(([errorPath]) => errorPath === jsonPath || errorPath.startsWith(`${jsonPath}.`) || errorPath.startsWith(`${jsonPath}[`));
|
|
542
|
+
return {
|
|
543
|
+
status: matchingError ? "error" : void 0,
|
|
544
|
+
error: matchingError ? matchingError[1] : void 0
|
|
545
|
+
};
|
|
546
|
+
}, [
|
|
317
547
|
errors
|
|
318
548
|
]);
|
|
319
|
-
const
|
|
320
|
-
return
|
|
549
|
+
const getFormValue = (path) => {
|
|
550
|
+
return getValue(values, createJsonPath(path));
|
|
321
551
|
};
|
|
322
|
-
const onValueChange = (
|
|
552
|
+
const onValueChange = (path, type, value) => {
|
|
553
|
+
const jsonPath = createJsonPath(path);
|
|
323
554
|
let parsedValue = value;
|
|
324
555
|
try {
|
|
325
556
|
if (type === "number") {
|
|
@@ -328,17 +559,19 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
328
559
|
} catch (err) {
|
|
329
560
|
log.catch(err, void 0, {
|
|
330
561
|
F: __dxlog_file,
|
|
331
|
-
L:
|
|
562
|
+
L: 193,
|
|
332
563
|
S: void 0,
|
|
333
564
|
C: (f, a) => f(...a)
|
|
334
565
|
});
|
|
335
566
|
parsedValue = void 0;
|
|
336
567
|
}
|
|
337
|
-
const newValues =
|
|
568
|
+
const newValues = {
|
|
569
|
+
...setValue(values, jsonPath, parsedValue)
|
|
570
|
+
};
|
|
338
571
|
setValues(newValues);
|
|
339
572
|
setChanged((prev) => ({
|
|
340
573
|
...prev,
|
|
341
|
-
[
|
|
574
|
+
[jsonPath]: true
|
|
342
575
|
}));
|
|
343
576
|
onValuesChanged?.(newValues);
|
|
344
577
|
const isValid = validate(newValues);
|
|
@@ -348,15 +581,12 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
348
581
|
});
|
|
349
582
|
}
|
|
350
583
|
};
|
|
351
|
-
const
|
|
352
|
-
const
|
|
584
|
+
const onTouched = useCallback2((path) => {
|
|
585
|
+
const jsonPath = createJsonPath(path);
|
|
353
586
|
setTouched((touched2) => ({
|
|
354
587
|
...touched2,
|
|
355
|
-
[
|
|
588
|
+
[jsonPath]: true
|
|
356
589
|
}));
|
|
357
|
-
if (event.relatedTarget?.getAttribute("type") === "submit") {
|
|
358
|
-
setTouched(createKeySet(values, true));
|
|
359
|
-
}
|
|
360
590
|
validate(values);
|
|
361
591
|
}, [
|
|
362
592
|
validate,
|
|
@@ -372,15 +602,15 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
372
602
|
handleSave,
|
|
373
603
|
// Field utils.
|
|
374
604
|
getStatus,
|
|
375
|
-
getValue,
|
|
605
|
+
getValue: getFormValue,
|
|
376
606
|
onValueChange,
|
|
377
|
-
|
|
607
|
+
onTouched
|
|
378
608
|
};
|
|
379
609
|
};
|
|
380
610
|
var createKeySet = (obj, value) => {
|
|
381
611
|
invariant(obj, void 0, {
|
|
382
612
|
F: __dxlog_file,
|
|
383
|
-
L:
|
|
613
|
+
L: 235,
|
|
384
614
|
S: void 0,
|
|
385
615
|
A: [
|
|
386
616
|
"obj",
|
|
@@ -394,338 +624,400 @@ var createKeySet = (obj, value) => {
|
|
|
394
624
|
};
|
|
395
625
|
var flatMap = (errors) => {
|
|
396
626
|
return errors.reduce((result, { path, message }) => {
|
|
397
|
-
|
|
398
|
-
|
|
627
|
+
const jsonPath = fromEffectValidationPath(path);
|
|
628
|
+
if (!(jsonPath in result)) {
|
|
629
|
+
result[jsonPath] = message;
|
|
399
630
|
}
|
|
400
631
|
return result;
|
|
401
632
|
}, {});
|
|
402
633
|
};
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
634
|
+
|
|
635
|
+
// packages/ui/react-ui-form/src/components/Form/FormContext.tsx
|
|
636
|
+
var FormContext = /* @__PURE__ */ createContext(void 0);
|
|
637
|
+
var useFormContext = () => {
|
|
638
|
+
return useContext(FormContext) ?? raise(new Error("Missing FormContext"));
|
|
639
|
+
};
|
|
640
|
+
var useFormValues = (path = []) => {
|
|
641
|
+
const { values: formValues } = useFormContext();
|
|
642
|
+
const jsonPath = createJsonPath2(path);
|
|
643
|
+
return getValue2(formValues, jsonPath);
|
|
406
644
|
};
|
|
407
|
-
var
|
|
408
|
-
const
|
|
409
|
-
const newValue = index === void 0 ? value : [
|
|
410
|
-
...obj[key]
|
|
411
|
-
].map((v, i) => i === parseInt(index) ? value : v);
|
|
645
|
+
var useInputProps = (path = []) => {
|
|
646
|
+
const { getStatus, getValue: getFormValue, onValueChange, onTouched } = useFormContext();
|
|
412
647
|
return {
|
|
413
|
-
|
|
414
|
-
|
|
648
|
+
getStatus: () => getStatus(path),
|
|
649
|
+
getValue: () => getFormValue(path),
|
|
650
|
+
onValueChange: (type, value) => onValueChange(path, type, value),
|
|
651
|
+
onBlur: () => onTouched(path)
|
|
415
652
|
};
|
|
416
653
|
};
|
|
654
|
+
var FormProvider = ({ children, ...formOptions }) => {
|
|
655
|
+
const formHandler = useForm(formOptions);
|
|
656
|
+
return /* @__PURE__ */ React7.createElement(FormContext.Provider, {
|
|
657
|
+
value: formHandler
|
|
658
|
+
}, children);
|
|
659
|
+
};
|
|
417
660
|
|
|
418
|
-
// packages/ui/react-ui-form/src/components/Form/
|
|
419
|
-
var
|
|
661
|
+
// packages/ui/react-ui-form/src/components/Form/FormActions.tsx
|
|
662
|
+
var FormActions = ({ onCancel, readonly }) => {
|
|
663
|
+
const { t } = useTranslation3(translationKey);
|
|
664
|
+
const { canSave, handleSave } = useFormContext();
|
|
665
|
+
return /* @__PURE__ */ React8.createElement("div", {
|
|
666
|
+
role: "none",
|
|
667
|
+
className: "flex justify-center"
|
|
668
|
+
}, /* @__PURE__ */ React8.createElement("div", {
|
|
669
|
+
role: "none",
|
|
670
|
+
className: mx4(onCancel && !readonly && "grid grid-cols-2 gap-2")
|
|
671
|
+
}, onCancel && !readonly && /* @__PURE__ */ React8.createElement(IconButton2, {
|
|
672
|
+
"data-testid": "cancel-button",
|
|
673
|
+
icon: "ph--x--regular",
|
|
674
|
+
label: t("button cancel"),
|
|
675
|
+
onClick: onCancel
|
|
676
|
+
}), handleSave && /* @__PURE__ */ React8.createElement(IconButton2, {
|
|
677
|
+
type: "submit",
|
|
678
|
+
"data-testid": "save-button",
|
|
679
|
+
disabled: !canSave,
|
|
680
|
+
icon: "ph--check--regular",
|
|
681
|
+
label: t("button save"),
|
|
682
|
+
onClick: handleSave
|
|
683
|
+
})));
|
|
684
|
+
};
|
|
685
|
+
|
|
686
|
+
// packages/ui/react-ui-form/src/components/Form/FormContent.tsx
|
|
687
|
+
import { pipe as pipe2 } from "effect";
|
|
688
|
+
import { capitalize as capitalize2 } from "effect/String";
|
|
689
|
+
import React10, { useMemo as useMemo3 } from "react";
|
|
690
|
+
import { AST as AST3, S } from "@dxos/echo-schema";
|
|
691
|
+
import { createJsonPath as createJsonPath3, findNode as findNode2, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2 } from "@dxos/effect";
|
|
692
|
+
import { mx as mx6 } from "@dxos/react-ui-theme";
|
|
693
|
+
import { getSchemaProperties as getSchemaProperties2 } from "@dxos/schema";
|
|
694
|
+
import { isNotFalsy } from "@dxos/util";
|
|
695
|
+
|
|
696
|
+
// packages/ui/react-ui-form/src/components/Form/ArrayField.tsx
|
|
697
|
+
import { pipe } from "effect";
|
|
698
|
+
import { capitalize } from "effect/String";
|
|
699
|
+
import React9, { useCallback as useCallback3, useMemo as useMemo2 } from "react";
|
|
700
|
+
import { AST as AST2 } from "@dxos/echo-schema";
|
|
701
|
+
import { findNode, getDiscriminatedType, isDiscriminatedUnion, SimpleType } from "@dxos/effect";
|
|
702
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
703
|
+
import { IconButton as IconButton3, useTranslation as useTranslation4 } from "@dxos/react-ui";
|
|
704
|
+
import { mx as mx5 } from "@dxos/react-ui-theme";
|
|
705
|
+
import { getSchemaProperties } from "@dxos/schema";
|
|
706
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/Form/ArrayField.tsx";
|
|
420
707
|
var padding = "px-2";
|
|
421
|
-
var
|
|
422
|
-
const
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
708
|
+
var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponent }) => {
|
|
709
|
+
const { t } = useTranslation4(translationKey);
|
|
710
|
+
const { ast, name, type, title } = property;
|
|
711
|
+
const values = useFormValues(path ?? []);
|
|
712
|
+
invariant2(Array.isArray(values), `Values at path ${path?.join(".")} must be an array.`, {
|
|
713
|
+
F: __dxlog_file2,
|
|
714
|
+
L: 37,
|
|
715
|
+
S: void 0,
|
|
716
|
+
A: [
|
|
717
|
+
"Array.isArray(values)",
|
|
718
|
+
"`Values at path ${path?.join('.')} must be an array.`"
|
|
719
|
+
]
|
|
433
720
|
});
|
|
434
|
-
const
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
721
|
+
const label = title ?? pipe(name, capitalize);
|
|
722
|
+
const tupleType = findNode(ast, AST2.isTupleType);
|
|
723
|
+
const elementType = tupleType?.rest[0]?.type;
|
|
724
|
+
const getDefaultObjectValue = (typeNode) => {
|
|
725
|
+
const baseNode = findNode(typeNode, isDiscriminatedUnion);
|
|
726
|
+
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, {}) : findNode(typeNode, AST2.isTypeLiteral);
|
|
727
|
+
if (!typeLiteral) {
|
|
728
|
+
return {};
|
|
729
|
+
}
|
|
730
|
+
return Object.fromEntries(getSchemaProperties(typeLiteral, {}).map((prop) => [
|
|
731
|
+
prop.name,
|
|
732
|
+
prop.defaultValue
|
|
733
|
+
]));
|
|
734
|
+
};
|
|
735
|
+
const newValue = useMemo2(() => {
|
|
736
|
+
if (type === "object" && elementType) {
|
|
737
|
+
return getDefaultObjectValue(elementType);
|
|
738
|
+
} else {
|
|
739
|
+
return SimpleType.getDefaultValue(type);
|
|
740
|
+
}
|
|
442
741
|
}, [
|
|
443
|
-
|
|
444
|
-
|
|
742
|
+
type,
|
|
743
|
+
elementType
|
|
744
|
+
]);
|
|
745
|
+
const handleAdd = useCallback3(() => {
|
|
746
|
+
inputProps.onValueChange(type, [
|
|
747
|
+
...values,
|
|
748
|
+
newValue
|
|
749
|
+
]);
|
|
750
|
+
}, [
|
|
751
|
+
type,
|
|
752
|
+
elementType,
|
|
753
|
+
inputProps,
|
|
754
|
+
newValue,
|
|
445
755
|
values
|
|
446
756
|
]);
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
errors
|
|
451
|
-
}, {
|
|
452
|
-
F: __dxlog_file2,
|
|
453
|
-
L: 100,
|
|
454
|
-
S: void 0,
|
|
455
|
-
C: (f, a) => f(...a)
|
|
456
|
-
});
|
|
457
|
-
}
|
|
757
|
+
const handleRemove = useCallback3((index) => {
|
|
758
|
+
const newValues = values.filter((_, i) => i !== index);
|
|
759
|
+
inputProps.onValueChange(type, newValues);
|
|
458
760
|
}, [
|
|
459
|
-
|
|
761
|
+
type,
|
|
762
|
+
inputProps,
|
|
763
|
+
values
|
|
460
764
|
]);
|
|
461
|
-
|
|
462
|
-
role: "form",
|
|
463
|
-
className: mx("flex flex-col w-full gap-2 py-2", classNames),
|
|
464
|
-
"data-testid": testId
|
|
465
|
-
}, properties.map((property) => {
|
|
466
|
-
const { ast, name, type, format, title, description, examples, options, array } = property;
|
|
467
|
-
const key = [
|
|
468
|
-
...path,
|
|
469
|
-
name
|
|
470
|
-
];
|
|
471
|
-
const label = title ?? pipe(name, capitalize);
|
|
472
|
-
const placeholder = examples?.length ? `Example: "${examples[0]}"` : description;
|
|
473
|
-
let InputComponent = Custom?.[key.join(".")];
|
|
474
|
-
if (!InputComponent) {
|
|
475
|
-
if (options) {
|
|
476
|
-
return /* @__PURE__ */ React5.createElement("div", {
|
|
477
|
-
key: name,
|
|
478
|
-
role: "none",
|
|
479
|
-
className: padding
|
|
480
|
-
}, /* @__PURE__ */ React5.createElement(SelectInput, {
|
|
481
|
-
type,
|
|
482
|
-
format,
|
|
483
|
-
property: name,
|
|
484
|
-
disabled: readonly,
|
|
485
|
-
label,
|
|
486
|
-
options: options.map((option) => ({
|
|
487
|
-
value: option,
|
|
488
|
-
label: String(option)
|
|
489
|
-
})),
|
|
490
|
-
placeholder,
|
|
491
|
-
...inputProps
|
|
492
|
-
}));
|
|
493
|
-
}
|
|
494
|
-
InputComponent = getInputComponent(type, format);
|
|
495
|
-
if (array) {
|
|
496
|
-
return /* @__PURE__ */ React5.createElement(ArrayField, {
|
|
497
|
-
key: name,
|
|
498
|
-
name,
|
|
499
|
-
type,
|
|
500
|
-
array: true,
|
|
501
|
-
label,
|
|
502
|
-
ast,
|
|
503
|
-
values,
|
|
504
|
-
format,
|
|
505
|
-
readonly,
|
|
506
|
-
placeholder,
|
|
507
|
-
inputProps,
|
|
508
|
-
Custom
|
|
509
|
-
});
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
if (!InputComponent) {
|
|
513
|
-
if (type === "object") {
|
|
514
|
-
const baseNode = findNode(ast, isDiscriminatedUnion);
|
|
515
|
-
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, values[name]) : findNode(ast, AST.isTypeLiteral);
|
|
516
|
-
if (typeLiteral) {
|
|
517
|
-
const schema2 = S.make(typeLiteral);
|
|
518
|
-
return /* @__PURE__ */ React5.createElement("div", {
|
|
519
|
-
key: name,
|
|
520
|
-
role: "none"
|
|
521
|
-
}, /* @__PURE__ */ React5.createElement("div", {
|
|
522
|
-
className: padding
|
|
523
|
-
}, label), /* @__PURE__ */ React5.createElement(Form, {
|
|
524
|
-
schema: schema2,
|
|
525
|
-
path: key,
|
|
526
|
-
values: values[name] ?? {},
|
|
527
|
-
onValuesChanged: (childValues) => {
|
|
528
|
-
inputProps.onValueChange(name, "object", childValues);
|
|
529
|
-
},
|
|
530
|
-
Custom
|
|
531
|
-
}));
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
log2("no renderer for property", {
|
|
535
|
-
name,
|
|
536
|
-
type
|
|
537
|
-
}, {
|
|
538
|
-
F: __dxlog_file2,
|
|
539
|
-
L: 185,
|
|
540
|
-
S: void 0,
|
|
541
|
-
C: (f, a) => f(...a)
|
|
542
|
-
});
|
|
543
|
-
return null;
|
|
544
|
-
}
|
|
545
|
-
return /* @__PURE__ */ React5.createElement("div", {
|
|
546
|
-
key: name,
|
|
547
|
-
role: "none",
|
|
548
|
-
className: padding
|
|
549
|
-
}, /* @__PURE__ */ React5.createElement(InputComponent, {
|
|
550
|
-
type,
|
|
551
|
-
format,
|
|
552
|
-
property: name,
|
|
553
|
-
disabled: readonly,
|
|
554
|
-
label,
|
|
555
|
-
placeholder,
|
|
556
|
-
...inputProps
|
|
557
|
-
}));
|
|
558
|
-
}).filter(isNotFalsy), (onCancel || onSave) && !autoSave && /* @__PURE__ */ React5.createElement(FormActions, {
|
|
559
|
-
onCancel,
|
|
560
|
-
onSubmit: handleSave,
|
|
561
|
-
canSubmit: canSave,
|
|
562
|
-
readonly
|
|
563
|
-
}));
|
|
564
|
-
};
|
|
565
|
-
var ArrayField = ({ name, type, label, ast, values, format, readonly, placeholder, inputProps, Custom }) => {
|
|
566
|
-
const { t } = useTranslation2(translationKey);
|
|
567
|
-
const arrayValues = values[name] ?? [];
|
|
568
|
-
const key = [
|
|
569
|
-
name
|
|
570
|
-
];
|
|
571
|
-
const tupleType = findNode(ast, AST.isTupleType);
|
|
572
|
-
const elementType = tupleType?.rest[0]?.type;
|
|
573
|
-
if (type === "object" && elementType) {
|
|
574
|
-
const baseNode = findNode(elementType, isDiscriminatedUnion);
|
|
575
|
-
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, values[name]) : findNode(elementType, AST.isTypeLiteral);
|
|
576
|
-
if (typeLiteral) {
|
|
577
|
-
const schema = S.make(typeLiteral);
|
|
578
|
-
return /* @__PURE__ */ React5.createElement("div", {
|
|
579
|
-
key: name,
|
|
580
|
-
role: "none",
|
|
581
|
-
className: mx(padding)
|
|
582
|
-
}, /* @__PURE__ */ React5.createElement(InputHeader, null, label), /* @__PURE__ */ React5.createElement("div", {
|
|
583
|
-
role: "none",
|
|
584
|
-
className: "flex flex-col gap-1"
|
|
585
|
-
}, arrayValues.map((value, index) => {
|
|
586
|
-
return /* @__PURE__ */ React5.createElement("div", {
|
|
587
|
-
key: index,
|
|
588
|
-
role: "none",
|
|
589
|
-
className: "flex items-center gap-1"
|
|
590
|
-
}, /* @__PURE__ */ React5.createElement("div", {
|
|
591
|
-
role: "none",
|
|
592
|
-
className: "flex-1"
|
|
593
|
-
}, /* @__PURE__ */ React5.createElement(Form, {
|
|
594
|
-
schema,
|
|
595
|
-
path: [
|
|
596
|
-
...key,
|
|
597
|
-
index.toString()
|
|
598
|
-
],
|
|
599
|
-
values: value,
|
|
600
|
-
onValuesChanged: (childValues) => {
|
|
601
|
-
const newValues = [
|
|
602
|
-
...arrayValues
|
|
603
|
-
];
|
|
604
|
-
newValues[index] = childValues;
|
|
605
|
-
inputProps.onValueChange(name, "object", newValues);
|
|
606
|
-
},
|
|
607
|
-
Custom
|
|
608
|
-
})), /* @__PURE__ */ React5.createElement(IconButton, {
|
|
609
|
-
icon: "ph--trash--regular",
|
|
610
|
-
iconOnly: true,
|
|
611
|
-
label: t("button remove"),
|
|
612
|
-
onClick: () => {
|
|
613
|
-
const newValues = arrayValues.filter((_, i) => i !== index);
|
|
614
|
-
inputProps.onValueChange(name, type, newValues);
|
|
615
|
-
}
|
|
616
|
-
}));
|
|
617
|
-
})), /* @__PURE__ */ React5.createElement("div", {
|
|
618
|
-
role: "none",
|
|
619
|
-
className: "flex justify-between items-center plb-1"
|
|
620
|
-
}, /* @__PURE__ */ React5.createElement(IconButton, {
|
|
621
|
-
icon: "ph--plus--regular",
|
|
622
|
-
iconOnly: true,
|
|
623
|
-
label: t("button add"),
|
|
624
|
-
onClick: () => {
|
|
625
|
-
const newValues = [
|
|
626
|
-
...arrayValues,
|
|
627
|
-
{}
|
|
628
|
-
];
|
|
629
|
-
inputProps.onValueChange(name, type, newValues);
|
|
630
|
-
}
|
|
631
|
-
})));
|
|
632
|
-
}
|
|
633
|
-
return /* @__PURE__ */ React5.createElement("div", {
|
|
634
|
-
key: name,
|
|
635
|
-
role: "none"
|
|
636
|
-
}, "Nested form not supported in arrays, yet.");
|
|
637
|
-
}
|
|
638
|
-
const InputComponent = getInputComponent(type, format);
|
|
639
|
-
if (!InputComponent) {
|
|
765
|
+
if (!elementType) {
|
|
640
766
|
return null;
|
|
641
767
|
}
|
|
642
|
-
return /* @__PURE__ */
|
|
768
|
+
return /* @__PURE__ */ React9.createElement("div", {
|
|
643
769
|
role: "none",
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
}, /* @__PURE__ */ React5.createElement(InputHeader, null, label), /* @__PURE__ */ React5.createElement("div", {
|
|
770
|
+
className: mx5(padding)
|
|
771
|
+
}, /* @__PURE__ */ React9.createElement(InputHeader, null, label), /* @__PURE__ */ React9.createElement("div", {
|
|
647
772
|
role: "none",
|
|
648
773
|
className: "flex flex-col gap-1"
|
|
649
|
-
},
|
|
774
|
+
}, values.map((_value, index) => /* @__PURE__ */ React9.createElement("div", {
|
|
650
775
|
key: index,
|
|
651
776
|
role: "none",
|
|
652
|
-
className: "flex items-
|
|
653
|
-
}, /* @__PURE__ */
|
|
777
|
+
className: "flex items-center gap-1"
|
|
778
|
+
}, /* @__PURE__ */ React9.createElement("div", {
|
|
654
779
|
role: "none",
|
|
655
780
|
className: "flex-1"
|
|
656
|
-
}, /* @__PURE__ */
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
781
|
+
}, /* @__PURE__ */ React9.createElement(FormField, {
|
|
782
|
+
property: {
|
|
783
|
+
...property,
|
|
784
|
+
array: false,
|
|
785
|
+
ast: elementType
|
|
786
|
+
},
|
|
787
|
+
path: [
|
|
788
|
+
...path ?? [],
|
|
789
|
+
index
|
|
790
|
+
],
|
|
791
|
+
readonly,
|
|
792
|
+
inline: true,
|
|
793
|
+
Custom,
|
|
794
|
+
lookupComponent
|
|
795
|
+
})), /* @__PURE__ */ React9.createElement(IconButton3, {
|
|
666
796
|
icon: "ph--trash--regular",
|
|
667
797
|
iconOnly: true,
|
|
668
798
|
label: t("button remove"),
|
|
669
|
-
onClick: () =>
|
|
670
|
-
|
|
671
|
-
inputProps.onValueChange(name, type, newValues);
|
|
672
|
-
}
|
|
673
|
-
})))), /* @__PURE__ */ React5.createElement("div", {
|
|
799
|
+
onClick: () => handleRemove(index)
|
|
800
|
+
})))), /* @__PURE__ */ React9.createElement("div", {
|
|
674
801
|
role: "none",
|
|
675
802
|
className: "flex justify-between items-center plb-1"
|
|
676
|
-
}, /* @__PURE__ */
|
|
803
|
+
}, /* @__PURE__ */ React9.createElement(IconButton3, {
|
|
677
804
|
icon: "ph--plus--regular",
|
|
678
805
|
iconOnly: true,
|
|
679
806
|
label: t("button add"),
|
|
680
|
-
onClick:
|
|
681
|
-
const newValues = [
|
|
682
|
-
...arrayValues,
|
|
683
|
-
SimpleType.getDefaultValue(type)
|
|
684
|
-
];
|
|
685
|
-
inputProps.onValueChange(name, type, newValues);
|
|
686
|
-
}
|
|
807
|
+
onClick: handleAdd
|
|
687
808
|
})));
|
|
688
809
|
};
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
810
|
+
|
|
811
|
+
// packages/ui/react-ui-form/src/components/Form/factory.tsx
|
|
812
|
+
import { FormatEnum } from "@dxos/echo-schema";
|
|
813
|
+
var getInputComponent = (type, format) => {
|
|
814
|
+
switch (format) {
|
|
815
|
+
case FormatEnum.LatLng:
|
|
816
|
+
return GeoPointInput;
|
|
817
|
+
}
|
|
818
|
+
switch (type) {
|
|
819
|
+
case "string":
|
|
820
|
+
return TextInput;
|
|
821
|
+
case "number":
|
|
822
|
+
return NumberInput;
|
|
823
|
+
case "boolean":
|
|
824
|
+
return BooleanInput;
|
|
825
|
+
}
|
|
826
|
+
};
|
|
827
|
+
|
|
828
|
+
// packages/ui/react-ui-form/src/components/Form/FormContent.tsx
|
|
829
|
+
var FormField = ({ property, path, readonly, inline, lookupComponent, Custom }) => {
|
|
830
|
+
const inputProps = useInputProps(path);
|
|
831
|
+
const { ast, name, type, format, title, description, options, examples, array } = property;
|
|
832
|
+
const label = useMemo3(() => title ?? pipe2(name, capitalize2), [
|
|
833
|
+
title,
|
|
834
|
+
name
|
|
835
|
+
]);
|
|
836
|
+
const placeholder = useMemo3(() => examples?.length ? `Example: "${examples[0]}"` : description, [
|
|
837
|
+
examples,
|
|
838
|
+
description
|
|
839
|
+
]);
|
|
840
|
+
const FoundComponent = lookupComponent?.({
|
|
841
|
+
prop: name,
|
|
842
|
+
schema: S.make(ast),
|
|
843
|
+
inputProps: {
|
|
844
|
+
type,
|
|
845
|
+
format,
|
|
846
|
+
label,
|
|
847
|
+
disabled: readonly,
|
|
848
|
+
placeholder,
|
|
849
|
+
...inputProps
|
|
850
|
+
}
|
|
851
|
+
});
|
|
852
|
+
if (FoundComponent) {
|
|
853
|
+
return /* @__PURE__ */ React10.createElement("div", {
|
|
854
|
+
role: "none"
|
|
855
|
+
}, FoundComponent);
|
|
856
|
+
}
|
|
857
|
+
const jsonPath = createJsonPath3(path ?? []);
|
|
858
|
+
const CustomComponent = Custom?.[jsonPath];
|
|
859
|
+
if (CustomComponent) {
|
|
860
|
+
return (
|
|
861
|
+
// TODO(ZaymonFC): We should try to remove this div wrapper.
|
|
862
|
+
/* @__PURE__ */ React10.createElement("div", {
|
|
863
|
+
role: "none"
|
|
864
|
+
}, /* @__PURE__ */ React10.createElement(CustomComponent, {
|
|
865
|
+
type,
|
|
866
|
+
format,
|
|
867
|
+
label,
|
|
868
|
+
inputOnly: inline,
|
|
869
|
+
placeholder,
|
|
870
|
+
disabled: readonly,
|
|
871
|
+
...inputProps
|
|
872
|
+
}))
|
|
873
|
+
);
|
|
874
|
+
}
|
|
875
|
+
if (array) {
|
|
876
|
+
return /* @__PURE__ */ React10.createElement(ArrayField, {
|
|
877
|
+
property,
|
|
878
|
+
path,
|
|
879
|
+
inputProps,
|
|
880
|
+
readonly,
|
|
881
|
+
Custom
|
|
882
|
+
});
|
|
883
|
+
}
|
|
884
|
+
const InputComponent = getInputComponent(type, format);
|
|
885
|
+
if (InputComponent) {
|
|
886
|
+
return /* @__PURE__ */ React10.createElement("div", {
|
|
887
|
+
role: "none"
|
|
888
|
+
}, /* @__PURE__ */ React10.createElement(InputComponent, {
|
|
889
|
+
type,
|
|
890
|
+
format,
|
|
891
|
+
label,
|
|
892
|
+
inputOnly: inline,
|
|
893
|
+
placeholder,
|
|
894
|
+
disabled: readonly,
|
|
895
|
+
...inputProps
|
|
896
|
+
}));
|
|
897
|
+
}
|
|
898
|
+
if (options) {
|
|
899
|
+
return /* @__PURE__ */ React10.createElement("div", {
|
|
900
|
+
role: "none"
|
|
901
|
+
}, /* @__PURE__ */ React10.createElement(SelectInput, {
|
|
902
|
+
type,
|
|
903
|
+
format,
|
|
904
|
+
disabled: readonly,
|
|
905
|
+
inputOnly: inline,
|
|
906
|
+
label,
|
|
907
|
+
options: options.map((option) => ({
|
|
908
|
+
value: option,
|
|
909
|
+
label: String(option)
|
|
910
|
+
})),
|
|
911
|
+
placeholder,
|
|
912
|
+
...inputProps
|
|
913
|
+
}));
|
|
914
|
+
}
|
|
915
|
+
if (type === "object") {
|
|
916
|
+
const baseNode = findNode2(ast, isDiscriminatedUnion2);
|
|
917
|
+
const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, inputProps.getValue()) : findNode2(ast, AST3.isTypeLiteral);
|
|
918
|
+
if (typeLiteral) {
|
|
919
|
+
return /* @__PURE__ */ React10.createElement("div", {
|
|
920
|
+
role: "none"
|
|
921
|
+
}, !inline && /* @__PURE__ */ React10.createElement("div", null, label), /* @__PURE__ */ React10.createElement(FormFields, {
|
|
922
|
+
schema: S.make(typeLiteral),
|
|
923
|
+
path,
|
|
924
|
+
readonly,
|
|
925
|
+
Custom
|
|
926
|
+
}));
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
return null;
|
|
930
|
+
};
|
|
931
|
+
var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custom }) => {
|
|
932
|
+
const values = useFormValues(path);
|
|
933
|
+
const properties = useMemo3(() => {
|
|
934
|
+
const props = getSchemaProperties2(schema.ast, values);
|
|
935
|
+
const filtered = filter ? filter(props) : props;
|
|
936
|
+
return sort ? filtered.sort((a, b) => sort.indexOf(a.name) - sort.indexOf(b.name)) : filtered;
|
|
937
|
+
}, [
|
|
938
|
+
schema,
|
|
939
|
+
values,
|
|
940
|
+
filter,
|
|
941
|
+
sort
|
|
942
|
+
]);
|
|
943
|
+
return /* @__PURE__ */ React10.createElement("div", {
|
|
944
|
+
role: "form",
|
|
945
|
+
className: mx6("flex flex-col w-full gap-2 py-2")
|
|
946
|
+
}, properties.map((property) => {
|
|
947
|
+
return /* @__PURE__ */ React10.createElement(FormField, {
|
|
948
|
+
key: property.name,
|
|
949
|
+
property,
|
|
950
|
+
path: [
|
|
951
|
+
...path ?? [],
|
|
952
|
+
property.name
|
|
953
|
+
],
|
|
954
|
+
readonly,
|
|
955
|
+
lookupComponent,
|
|
956
|
+
Custom
|
|
957
|
+
});
|
|
958
|
+
}).filter(isNotFalsy));
|
|
959
|
+
};
|
|
960
|
+
|
|
961
|
+
// packages/ui/react-ui-form/src/components/Form/Form.tsx
|
|
962
|
+
var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, lookupComponent, Custom }) => {
|
|
963
|
+
const onValid = useMemo4(() => autoSave ? onSave : void 0, [
|
|
964
|
+
autoSave,
|
|
965
|
+
onSave
|
|
966
|
+
]);
|
|
967
|
+
useEffect3(() => {
|
|
968
|
+
if (autoFocus) {
|
|
969
|
+
const input = document.querySelector("input");
|
|
970
|
+
if (input) {
|
|
971
|
+
input.focus();
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
}, [
|
|
975
|
+
autoFocus
|
|
976
|
+
]);
|
|
977
|
+
return /* @__PURE__ */ React11.createElement(FormProvider, {
|
|
978
|
+
schema,
|
|
979
|
+
initialValues,
|
|
980
|
+
onValuesChanged,
|
|
981
|
+
onValidate,
|
|
982
|
+
onValid,
|
|
983
|
+
onSave
|
|
984
|
+
}, /* @__PURE__ */ React11.createElement("div", {
|
|
695
985
|
role: "none",
|
|
696
|
-
className:
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
986
|
+
className: mx7("p-2", classNames),
|
|
987
|
+
"data-testid": testId
|
|
988
|
+
}, /* @__PURE__ */ React11.createElement(FormFields, {
|
|
989
|
+
schema,
|
|
990
|
+
path,
|
|
991
|
+
readonly,
|
|
992
|
+
filter,
|
|
993
|
+
sort,
|
|
994
|
+
lookupComponent,
|
|
995
|
+
Custom
|
|
996
|
+
}), (onCancel || onSave) && !autoSave && /* @__PURE__ */ React11.createElement(FormActions, {
|
|
997
|
+
onCancel,
|
|
998
|
+
readonly
|
|
709
999
|
})));
|
|
710
1000
|
};
|
|
711
1001
|
|
|
712
1002
|
// packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx
|
|
713
1003
|
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
|
|
714
1004
|
var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
715
|
-
const { t } =
|
|
716
|
-
const [props, setProps] =
|
|
717
|
-
|
|
1005
|
+
const { t } = useTranslation5(translationKey);
|
|
1006
|
+
const [props, setProps] = useState3(projection.getFieldProjection(field.id).props);
|
|
1007
|
+
useEffect4(() => setProps(projection.getFieldProjection(field.id).props), [
|
|
718
1008
|
field,
|
|
719
1009
|
projection
|
|
720
1010
|
]);
|
|
721
|
-
const [schemas, setSchemas] =
|
|
722
|
-
|
|
1011
|
+
const [schemas, setSchemas] = useState3([]);
|
|
1012
|
+
useEffect4(() => {
|
|
723
1013
|
if (!registry) {
|
|
724
1014
|
return;
|
|
725
1015
|
}
|
|
726
|
-
const subscription = registry.subscribe(setSchemas)
|
|
1016
|
+
const subscription = registry.query().subscribe((query) => setSchemas(query.results), {
|
|
1017
|
+
fire: true
|
|
1018
|
+
});
|
|
727
1019
|
const t2 = setTimeout(async () => {
|
|
728
|
-
const schemas2 = await registry.query();
|
|
1020
|
+
const schemas2 = await registry.query().run();
|
|
729
1021
|
setSchemas(schemas2);
|
|
730
1022
|
});
|
|
731
1023
|
return () => {
|
|
@@ -735,25 +1027,35 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
735
1027
|
}, [
|
|
736
1028
|
registry
|
|
737
1029
|
]);
|
|
738
|
-
const [
|
|
739
|
-
|
|
740
|
-
|
|
1030
|
+
const [referenceSchema, setReferenceSchema] = useState3();
|
|
1031
|
+
useEffect4(() => {
|
|
1032
|
+
setReferenceSchema(schemas.find((schema) => schema.typename === props?.referenceSchema));
|
|
741
1033
|
}, [
|
|
742
1034
|
schemas,
|
|
743
1035
|
props?.referenceSchema
|
|
744
1036
|
]);
|
|
745
|
-
const [{ fieldSchema }, setFieldSchema] =
|
|
1037
|
+
const [{ fieldSchema }, setFieldSchema] = useState3({
|
|
746
1038
|
fieldSchema: getFormatSchema(props?.format)
|
|
747
1039
|
});
|
|
748
|
-
const handleValuesChanged =
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
1040
|
+
const handleValuesChanged = useCallback4((_props) => {
|
|
1041
|
+
setFieldSchema((prev) => {
|
|
1042
|
+
const fieldSchema2 = getFormatSchema(_props.format);
|
|
1043
|
+
if (prev.fieldSchema === fieldSchema2) {
|
|
1044
|
+
return prev;
|
|
1045
|
+
}
|
|
1046
|
+
return {
|
|
1047
|
+
fieldSchema: fieldSchema2
|
|
1048
|
+
};
|
|
1049
|
+
});
|
|
1050
|
+
setReferenceSchema((prev) => {
|
|
1051
|
+
if (_props.referenceSchema !== prev?.typename) {
|
|
1052
|
+
const newSchema = schemas.find((schema) => schema.typename === _props.referenceSchema);
|
|
1053
|
+
if (newSchema) {
|
|
1054
|
+
return newSchema;
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
return prev;
|
|
1058
|
+
});
|
|
757
1059
|
setProps((props2) => {
|
|
758
1060
|
const type = formatToType[_props.format];
|
|
759
1061
|
if (props2.type !== type) {
|
|
@@ -763,13 +1065,14 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
763
1065
|
type
|
|
764
1066
|
};
|
|
765
1067
|
}
|
|
766
|
-
return
|
|
1068
|
+
return _props;
|
|
767
1069
|
});
|
|
768
1070
|
}, [
|
|
769
1071
|
schemas,
|
|
770
|
-
props
|
|
1072
|
+
props.format,
|
|
1073
|
+
props.referenceSchema
|
|
771
1074
|
]);
|
|
772
|
-
const handleValidate =
|
|
1075
|
+
const handleValidate = useCallback4(({ property }) => {
|
|
773
1076
|
if (property && view.fields.find((f) => f.path === property && f.path !== field.path)) {
|
|
774
1077
|
return [
|
|
775
1078
|
{
|
|
@@ -782,7 +1085,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
782
1085
|
view.fields,
|
|
783
1086
|
field
|
|
784
1087
|
]);
|
|
785
|
-
const handleSave =
|
|
1088
|
+
const handleSave = useCallback4((props2) => {
|
|
786
1089
|
projection.setFieldProjection({
|
|
787
1090
|
field,
|
|
788
1091
|
props: props2
|
|
@@ -793,29 +1096,56 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
793
1096
|
field,
|
|
794
1097
|
onSave
|
|
795
1098
|
]);
|
|
796
|
-
const handleCancel =
|
|
1099
|
+
const handleCancel = useCallback4(() => {
|
|
797
1100
|
requestAnimationFrame(() => onCancel?.());
|
|
798
1101
|
onSave();
|
|
799
1102
|
}, [
|
|
800
1103
|
onSave
|
|
801
1104
|
]);
|
|
1105
|
+
const Custom = useMemo5(() => ({
|
|
1106
|
+
["format"]: (props2) => /* @__PURE__ */ React12.createElement(SelectInput, {
|
|
1107
|
+
...props2,
|
|
1108
|
+
options: FormatEnums.filter((value) => value !== FormatEnum2.None).map((value) => ({
|
|
1109
|
+
value,
|
|
1110
|
+
label: t(`format ${value}`)
|
|
1111
|
+
}))
|
|
1112
|
+
}),
|
|
1113
|
+
["referenceSchema"]: (props2) => /* @__PURE__ */ React12.createElement(SelectInput, {
|
|
1114
|
+
...props2,
|
|
1115
|
+
options: schemas.map((schema) => ({
|
|
1116
|
+
value: schema.typename
|
|
1117
|
+
}))
|
|
1118
|
+
}),
|
|
1119
|
+
["referencePath"]: (props2) => /* @__PURE__ */ React12.createElement(SelectInput, {
|
|
1120
|
+
...props2,
|
|
1121
|
+
options: referenceSchema ? getSchemaProperties3(referenceSchema.ast).sort(sortProperties).map((p) => ({
|
|
1122
|
+
value: p.name
|
|
1123
|
+
})) : []
|
|
1124
|
+
}),
|
|
1125
|
+
["options"]: (props2) => /* @__PURE__ */ React12.createElement(SelectOptionInput, props2)
|
|
1126
|
+
}), [
|
|
1127
|
+
t,
|
|
1128
|
+
schemas,
|
|
1129
|
+
referenceSchema
|
|
1130
|
+
]);
|
|
1131
|
+
const propIsNotType = useCallback4((props2) => props2.filter((p) => p.name !== "type"), []);
|
|
802
1132
|
if (!fieldSchema) {
|
|
803
|
-
|
|
1133
|
+
log2.warn("invalid format", {
|
|
804
1134
|
props
|
|
805
1135
|
}, {
|
|
806
1136
|
F: __dxlog_file3,
|
|
807
|
-
L:
|
|
1137
|
+
L: 174,
|
|
808
1138
|
S: void 0,
|
|
809
1139
|
C: (f, a) => f(...a)
|
|
810
1140
|
});
|
|
811
1141
|
return null;
|
|
812
1142
|
}
|
|
813
|
-
return /* @__PURE__ */
|
|
1143
|
+
return /* @__PURE__ */ React12.createElement(Form, {
|
|
814
1144
|
key: field.id,
|
|
815
1145
|
autoFocus: true,
|
|
816
1146
|
values: props,
|
|
817
1147
|
schema: fieldSchema,
|
|
818
|
-
filter:
|
|
1148
|
+
filter: propIsNotType,
|
|
819
1149
|
sort: [
|
|
820
1150
|
"property",
|
|
821
1151
|
"format"
|
|
@@ -824,55 +1154,34 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
824
1154
|
onValidate: handleValidate,
|
|
825
1155
|
onSave: handleSave,
|
|
826
1156
|
onCancel: handleCancel,
|
|
827
|
-
Custom
|
|
828
|
-
["format"]: (props2) => /* @__PURE__ */ React6.createElement(SelectInput, {
|
|
829
|
-
...props2,
|
|
830
|
-
options: FormatEnums.filter((value) => value !== FormatEnum2.None).map((value) => ({
|
|
831
|
-
value,
|
|
832
|
-
label: t(`format ${value}`)
|
|
833
|
-
}))
|
|
834
|
-
}),
|
|
835
|
-
["referenceSchema"]: (props2) => /* @__PURE__ */ React6.createElement(SelectInput, {
|
|
836
|
-
...props2,
|
|
837
|
-
options: schemas.map((schema2) => ({
|
|
838
|
-
value: schema2.typename
|
|
839
|
-
}))
|
|
840
|
-
}),
|
|
841
|
-
["referencePath"]: (props2) => /* @__PURE__ */ React6.createElement(SelectInput, {
|
|
842
|
-
...props2,
|
|
843
|
-
options: schema ? getSchemaProperties2(schema.schema.ast).sort(sortProperties).map((p) => ({
|
|
844
|
-
value: p.name
|
|
845
|
-
})) : []
|
|
846
|
-
})
|
|
847
|
-
}
|
|
1157
|
+
Custom
|
|
848
1158
|
});
|
|
849
1159
|
};
|
|
850
1160
|
|
|
851
1161
|
// packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx
|
|
852
|
-
import
|
|
853
|
-
import { AST as
|
|
854
|
-
import { IconButton as
|
|
855
|
-
import { List } from "@dxos/react-ui-list";
|
|
856
|
-
import { ghostHover, inputTextLabel, mx as
|
|
1162
|
+
import React13, { useCallback as useCallback5, useMemo as useMemo6, useState as useState4 } from "react";
|
|
1163
|
+
import { AST as AST4, Format, S as S2 } from "@dxos/echo-schema";
|
|
1164
|
+
import { IconButton as IconButton4, useTranslation as useTranslation6 } from "@dxos/react-ui";
|
|
1165
|
+
import { List as List2 } from "@dxos/react-ui-list";
|
|
1166
|
+
import { ghostHover, inputTextLabel, mx as mx8 } from "@dxos/react-ui-theme";
|
|
857
1167
|
import { FieldSchema, ViewProjection, VIEW_FIELD_LIMIT } from "@dxos/schema";
|
|
858
|
-
import { arrayMove } from "@dxos/util";
|
|
859
1168
|
var grid = "grid grid-cols-[32px_1fr_32px] min-bs-[2.5rem]";
|
|
860
1169
|
var ViewMetaSchema = S2.Struct({
|
|
861
1170
|
name: S2.String.annotations({
|
|
862
|
-
[
|
|
1171
|
+
[AST4.TitleAnnotationId]: "View"
|
|
863
1172
|
}),
|
|
864
1173
|
typename: Format.DXN.annotations({
|
|
865
|
-
[
|
|
1174
|
+
[AST4.TitleAnnotationId]: "Typename"
|
|
866
1175
|
})
|
|
867
1176
|
}).pipe(S2.mutable);
|
|
868
|
-
var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading = false, onDelete }) => {
|
|
869
|
-
const { t } =
|
|
870
|
-
const projection =
|
|
1177
|
+
var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading = false, onTypenameChanged, onDelete }) => {
|
|
1178
|
+
const { t } = useTranslation6(translationKey);
|
|
1179
|
+
const projection = useMemo6(() => new ViewProjection(schema, view), [
|
|
871
1180
|
schema,
|
|
872
1181
|
view
|
|
873
1182
|
]);
|
|
874
|
-
const [field, setField] =
|
|
875
|
-
const viewValues =
|
|
1183
|
+
const [field, setField] = useState4();
|
|
1184
|
+
const viewValues = useMemo6(() => {
|
|
876
1185
|
return {
|
|
877
1186
|
name: view.name,
|
|
878
1187
|
// TODO(burdon): Need to warn user of possible consequences of editing.
|
|
@@ -882,77 +1191,86 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
882
1191
|
}, [
|
|
883
1192
|
view
|
|
884
1193
|
]);
|
|
885
|
-
const handleViewUpdate =
|
|
1194
|
+
const handleViewUpdate = useCallback5(({ name, typename }) => {
|
|
886
1195
|
requestAnimationFrame(() => {
|
|
887
|
-
view.name
|
|
888
|
-
|
|
889
|
-
|
|
1196
|
+
if (view.name !== name) {
|
|
1197
|
+
view.name = name;
|
|
1198
|
+
}
|
|
1199
|
+
if (view.query.type !== typename) {
|
|
1200
|
+
onTypenameChanged(typename);
|
|
1201
|
+
}
|
|
890
1202
|
});
|
|
891
1203
|
}, [
|
|
892
1204
|
view,
|
|
893
|
-
schema
|
|
1205
|
+
schema,
|
|
1206
|
+
onTypenameChanged
|
|
894
1207
|
]);
|
|
895
|
-
const handleSelect =
|
|
1208
|
+
const handleSelect = useCallback5((field2) => {
|
|
896
1209
|
setField((f) => f === field2 ? void 0 : field2);
|
|
897
1210
|
}, []);
|
|
898
|
-
const handleAdd =
|
|
1211
|
+
const handleAdd = useCallback5(() => {
|
|
899
1212
|
const field2 = projection.createFieldProjection();
|
|
900
1213
|
setField(field2);
|
|
901
1214
|
}, [
|
|
902
1215
|
view
|
|
903
1216
|
]);
|
|
904
|
-
const handleMove =
|
|
905
|
-
|
|
1217
|
+
const handleMove = useCallback5((fromIndex, toIndex) => {
|
|
1218
|
+
const fields = [
|
|
1219
|
+
...view.fields
|
|
1220
|
+
];
|
|
1221
|
+
const [moved] = fields.splice(fromIndex, 1);
|
|
1222
|
+
fields.splice(toIndex, 0, moved);
|
|
1223
|
+
view.fields = fields;
|
|
906
1224
|
}, [
|
|
907
1225
|
view.fields
|
|
908
1226
|
]);
|
|
909
|
-
const handleClose =
|
|
910
|
-
return /* @__PURE__ */
|
|
1227
|
+
const handleClose = useCallback5(() => setField(void 0), []);
|
|
1228
|
+
return /* @__PURE__ */ React13.createElement("div", {
|
|
911
1229
|
role: "none",
|
|
912
|
-
className:
|
|
913
|
-
}, /* @__PURE__ */
|
|
1230
|
+
className: mx8("flex flex-col w-full divide-y divide-separator", classNames)
|
|
1231
|
+
}, /* @__PURE__ */ React13.createElement(Form, {
|
|
914
1232
|
autoFocus: true,
|
|
915
1233
|
autoSave: true,
|
|
916
1234
|
schema: ViewMetaSchema,
|
|
917
1235
|
values: viewValues,
|
|
918
1236
|
onSave: handleViewUpdate
|
|
919
|
-
}), /* @__PURE__ */
|
|
1237
|
+
}), /* @__PURE__ */ React13.createElement("div", null, /* @__PURE__ */ React13.createElement("div", {
|
|
920
1238
|
role: "none",
|
|
921
1239
|
className: "p-2"
|
|
922
|
-
}, /* @__PURE__ */
|
|
923
|
-
className:
|
|
924
|
-
}, t("fields label"))), /* @__PURE__ */
|
|
1240
|
+
}, /* @__PURE__ */ React13.createElement("label", {
|
|
1241
|
+
className: mx8(inputTextLabel)
|
|
1242
|
+
}, t("fields label"))), /* @__PURE__ */ React13.createElement(List2.Root, {
|
|
925
1243
|
items: view.fields,
|
|
926
1244
|
isItem: S2.is(FieldSchema),
|
|
927
1245
|
getId: (field2) => field2.id,
|
|
928
1246
|
onMove: handleMove
|
|
929
|
-
}, ({ items: fields }) => /* @__PURE__ */
|
|
1247
|
+
}, ({ items: fields }) => /* @__PURE__ */ React13.createElement(React13.Fragment, null, showHeading && /* @__PURE__ */ React13.createElement("div", {
|
|
930
1248
|
role: "heading",
|
|
931
1249
|
className: grid
|
|
932
|
-
}, /* @__PURE__ */
|
|
1250
|
+
}, /* @__PURE__ */ React13.createElement("div", null), /* @__PURE__ */ React13.createElement("div", {
|
|
933
1251
|
className: "flex items-center text-sm"
|
|
934
|
-
}, t("field path label"))), /* @__PURE__ */
|
|
1252
|
+
}, t("field path label"))), /* @__PURE__ */ React13.createElement("div", {
|
|
935
1253
|
role: "list",
|
|
936
1254
|
className: "flex flex-col w-full"
|
|
937
|
-
}, fields?.map((field2) => /* @__PURE__ */
|
|
1255
|
+
}, fields?.map((field2) => /* @__PURE__ */ React13.createElement(List2.Item, {
|
|
938
1256
|
key: field2.id,
|
|
939
1257
|
item: field2,
|
|
940
|
-
classNames:
|
|
941
|
-
}, /* @__PURE__ */
|
|
1258
|
+
classNames: mx8(grid, ghostHover, "cursor-pointer")
|
|
1259
|
+
}, /* @__PURE__ */ React13.createElement(List2.ItemDragHandle, null), /* @__PURE__ */ React13.createElement(List2.ItemTitle, {
|
|
942
1260
|
onClick: () => handleSelect(field2)
|
|
943
|
-
}, field2.path), /* @__PURE__ */
|
|
1261
|
+
}, field2.path), /* @__PURE__ */ React13.createElement(List2.ItemDeleteButton, {
|
|
944
1262
|
disabled: view.fields.length <= 1,
|
|
945
1263
|
onClick: () => onDelete(field2.id)
|
|
946
|
-
}))))))), field && /* @__PURE__ */
|
|
1264
|
+
}))))))), field && /* @__PURE__ */ React13.createElement(FieldEditor, {
|
|
947
1265
|
key: field.id,
|
|
948
1266
|
view,
|
|
949
1267
|
projection,
|
|
950
1268
|
field,
|
|
951
1269
|
registry,
|
|
952
1270
|
onSave: handleClose
|
|
953
|
-
}), !readonly && !field && /* @__PURE__ */
|
|
1271
|
+
}), !readonly && !field && /* @__PURE__ */ React13.createElement("div", {
|
|
954
1272
|
className: "flex p-2 justify-center"
|
|
955
|
-
}, /* @__PURE__ */
|
|
1273
|
+
}, /* @__PURE__ */ React13.createElement(IconButton4, {
|
|
956
1274
|
icon: "ph--plus--regular",
|
|
957
1275
|
label: t("button add property"),
|
|
958
1276
|
onClick: handleAdd,
|
|
@@ -1182,15 +1500,17 @@ var formatForEditing = ({ type, format, value, locale = void 0 }) => {
|
|
|
1182
1500
|
};
|
|
1183
1501
|
export {
|
|
1184
1502
|
BooleanInput,
|
|
1503
|
+
DeprecatedFormContainer,
|
|
1185
1504
|
DeprecatedFormInput,
|
|
1186
1505
|
FieldEditor,
|
|
1187
1506
|
Form,
|
|
1188
|
-
|
|
1189
|
-
GeiPointInput,
|
|
1507
|
+
GeoPointInput,
|
|
1190
1508
|
InputHeader,
|
|
1191
1509
|
NumberInput,
|
|
1192
1510
|
SelectInput,
|
|
1511
|
+
SelectOptionInput,
|
|
1193
1512
|
TextInput,
|
|
1513
|
+
TupleInput,
|
|
1194
1514
|
ViewEditor,
|
|
1195
1515
|
cellClassesForFieldType,
|
|
1196
1516
|
cellClassesForRowSelection,
|