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