@dxos/react-ui-form 0.7.5-labs.5f04cf6 → 0.7.5-labs.8a82073
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 +403 -160
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +390 -147
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +403 -160
- 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.map +1 -1
- package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.d.ts +3 -2
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormContent.d.ts.map +1 -1
- 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/index.d.ts +1 -0
- package/dist/types/src/components/Form/custom/index.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.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.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 -1
- package/package.json +25 -24
- package/src/components/FieldEditor/FieldEditor.stories.tsx +1 -1
- package/src/components/FieldEditor/FieldEditor.tsx +3 -2
- package/src/components/Form/ArrayField.tsx +1 -1
- package/src/components/Form/Defaults.tsx +2 -1
- package/src/components/Form/Form.tsx +16 -2
- package/src/components/Form/FormActions.tsx +1 -1
- package/src/components/Form/FormContent.tsx +27 -9
- package/src/components/Form/custom/SelectOptionsInput.stories.tsx +58 -0
- package/src/components/Form/custom/SelectOptionsInput.tsx +192 -0
- package/src/components/Form/custom/index.ts +1 -0
- package/src/components/ViewEditor/ViewEditor.tsx +5 -2
- package/src/components/deprecated/FormInput.tsx +20 -7
- package/src/hooks/useForm.ts +0 -1
- package/src/translations.ts +8 -0
|
@@ -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,29 +80,31 @@ 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
106
|
import { log as log2 } from "@dxos/log";
|
|
88
|
-
import { useTranslation as
|
|
107
|
+
import { useTranslation as useTranslation5 } from "@dxos/react-ui";
|
|
89
108
|
import { getFormatSchema, getSchemaProperties as getSchemaProperties3, sortProperties } from "@dxos/schema";
|
|
90
109
|
|
|
91
110
|
// packages/ui/react-ui-form/src/components/Form/custom/GeoPointInput.tsx
|
|
@@ -146,10 +165,193 @@ var GeoPointInput = ({ type, label, disabled, getStatus, getValue: getValue3, on
|
|
|
146
165
|
})));
|
|
147
166
|
};
|
|
148
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
|
+
|
|
149
351
|
// packages/ui/react-ui-form/src/components/Form/custom/TupleInput.tsx
|
|
150
|
-
import
|
|
151
|
-
import { Input as
|
|
152
|
-
import { mx } from "@dxos/react-ui-theme";
|
|
352
|
+
import React5 from "react";
|
|
353
|
+
import { Input as Input4 } from "@dxos/react-ui";
|
|
354
|
+
import { mx as mx3 } from "@dxos/react-ui-theme";
|
|
153
355
|
import { safeParseFloat as safeParseFloat2 } from "@dxos/util";
|
|
154
356
|
var gridCols = [
|
|
155
357
|
"grid-cols-1",
|
|
@@ -160,13 +362,13 @@ var gridCols = [
|
|
|
160
362
|
var TupleInput = ({ binding, type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
161
363
|
const { status, error } = getStatus();
|
|
162
364
|
const values = getValue3() ?? {};
|
|
163
|
-
return /* @__PURE__ */
|
|
365
|
+
return /* @__PURE__ */ React5.createElement(Input4.Root, {
|
|
164
366
|
validationValence: status
|
|
165
|
-
}, /* @__PURE__ */
|
|
367
|
+
}, /* @__PURE__ */ React5.createElement(InputHeader, {
|
|
166
368
|
error
|
|
167
|
-
}, /* @__PURE__ */
|
|
168
|
-
className:
|
|
169
|
-
}, binding.map((prop) => /* @__PURE__ */
|
|
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, {
|
|
170
372
|
key: prop,
|
|
171
373
|
type: "number",
|
|
172
374
|
disabled,
|
|
@@ -180,87 +382,88 @@ var TupleInput = ({ binding, type, label, disabled, getStatus, getValue: getValu
|
|
|
180
382
|
};
|
|
181
383
|
|
|
182
384
|
// packages/ui/react-ui-form/src/components/Form/Defaults.tsx
|
|
183
|
-
import
|
|
184
|
-
import { Input as
|
|
385
|
+
import React6 from "react";
|
|
386
|
+
import { Input as Input5, Select } from "@dxos/react-ui";
|
|
185
387
|
var TextInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
186
388
|
const { status, error } = getStatus();
|
|
187
|
-
return /* @__PURE__ */
|
|
389
|
+
return /* @__PURE__ */ React6.createElement(Input5.Root, {
|
|
188
390
|
validationValence: status
|
|
189
|
-
}, !inputOnly && /* @__PURE__ */
|
|
391
|
+
}, !inputOnly && /* @__PURE__ */ React6.createElement(InputHeader, {
|
|
190
392
|
error
|
|
191
|
-
}, /* @__PURE__ */
|
|
393
|
+
}, /* @__PURE__ */ React6.createElement(Input5.Label, null, label)), /* @__PURE__ */ React6.createElement(Input5.TextInput, {
|
|
192
394
|
disabled,
|
|
193
395
|
placeholder,
|
|
194
396
|
value: getValue3() ?? "",
|
|
195
397
|
onChange: (event) => onValueChange(type, event.target.value),
|
|
196
398
|
onBlur
|
|
197
|
-
}), inputOnly && /* @__PURE__ */
|
|
399
|
+
}), inputOnly && /* @__PURE__ */ React6.createElement(Input5.Validation, null, error));
|
|
198
400
|
};
|
|
199
401
|
var NumberInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
200
402
|
const { status, error } = getStatus();
|
|
201
|
-
return /* @__PURE__ */
|
|
403
|
+
return /* @__PURE__ */ React6.createElement(Input5.Root, {
|
|
202
404
|
validationValence: status
|
|
203
|
-
}, !inputOnly && /* @__PURE__ */
|
|
405
|
+
}, !inputOnly && /* @__PURE__ */ React6.createElement(InputHeader, {
|
|
204
406
|
error
|
|
205
|
-
}, /* @__PURE__ */
|
|
407
|
+
}, /* @__PURE__ */ React6.createElement(Input5.Label, null, label)), /* @__PURE__ */ React6.createElement(Input5.TextInput, {
|
|
206
408
|
type: "number",
|
|
207
409
|
disabled,
|
|
208
410
|
placeholder,
|
|
209
411
|
value: getValue3() ?? 0,
|
|
210
412
|
onChange: (event) => onValueChange(type, event.target.value),
|
|
211
413
|
onBlur
|
|
212
|
-
}), inputOnly && /* @__PURE__ */
|
|
414
|
+
}), inputOnly && /* @__PURE__ */ React6.createElement(Input5.DescriptionAndValidation, null, error));
|
|
213
415
|
};
|
|
214
416
|
var BooleanInput = ({ type, label, inputOnly, getStatus, getValue: getValue3, onValueChange }) => {
|
|
215
417
|
const { status, error } = getStatus();
|
|
216
|
-
|
|
418
|
+
const checked = Boolean(getValue3());
|
|
419
|
+
return /* @__PURE__ */ React6.createElement(Input5.Root, {
|
|
217
420
|
validationValence: status
|
|
218
|
-
}, !inputOnly && /* @__PURE__ */
|
|
421
|
+
}, !inputOnly && /* @__PURE__ */ React6.createElement(InputHeader, {
|
|
219
422
|
error
|
|
220
|
-
}, /* @__PURE__ */
|
|
221
|
-
checked
|
|
423
|
+
}, /* @__PURE__ */ React6.createElement(Input5.Label, null, label)), /* @__PURE__ */ React6.createElement(Input5.Switch, {
|
|
424
|
+
checked,
|
|
222
425
|
onCheckedChange: (value) => onValueChange(type, value)
|
|
223
|
-
}), inputOnly && /* @__PURE__ */
|
|
426
|
+
}), inputOnly && /* @__PURE__ */ React6.createElement(Input5.DescriptionAndValidation, null, error));
|
|
224
427
|
};
|
|
225
428
|
var SelectInput = ({ type, label, inputOnly, disabled, placeholder, options, getStatus, getValue: getValue3, onValueChange }) => {
|
|
226
429
|
const { status, error } = getStatus();
|
|
227
|
-
return /* @__PURE__ */
|
|
430
|
+
return /* @__PURE__ */ React6.createElement(Input5.Root, {
|
|
228
431
|
validationValence: status
|
|
229
|
-
}, !inputOnly && /* @__PURE__ */
|
|
432
|
+
}, !inputOnly && /* @__PURE__ */ React6.createElement(InputHeader, {
|
|
230
433
|
error
|
|
231
|
-
}, /* @__PURE__ */
|
|
434
|
+
}, /* @__PURE__ */ React6.createElement(Input5.Label, null, label)), /* @__PURE__ */ React6.createElement(Select.Root, {
|
|
232
435
|
value: getValue3(),
|
|
233
436
|
onValueChange: (value) => onValueChange(type, value)
|
|
234
|
-
}, /* @__PURE__ */
|
|
437
|
+
}, /* @__PURE__ */ React6.createElement(Select.TriggerButton, {
|
|
235
438
|
classNames: "is-full",
|
|
236
439
|
disabled,
|
|
237
440
|
placeholder
|
|
238
|
-
}), /* @__PURE__ */
|
|
441
|
+
}), /* @__PURE__ */ React6.createElement(Select.Portal, null, /* @__PURE__ */ React6.createElement(Select.Content, null, /* @__PURE__ */ React6.createElement(Select.Viewport, null, options?.map(({ value, label: label2 }) => (
|
|
239
442
|
// NOTE: Numeric values are converted to and from strings.
|
|
240
|
-
/* @__PURE__ */
|
|
443
|
+
/* @__PURE__ */ React6.createElement(Select.Option, {
|
|
241
444
|
key: String(value),
|
|
242
445
|
value: String(value)
|
|
243
446
|
}, label2 ?? String(value))
|
|
244
|
-
)))))), inputOnly && /* @__PURE__ */
|
|
447
|
+
)))))), inputOnly && /* @__PURE__ */ React6.createElement(Input5.DescriptionAndValidation, null, error));
|
|
245
448
|
};
|
|
246
449
|
|
|
247
450
|
// packages/ui/react-ui-form/src/components/Form/Form.tsx
|
|
248
|
-
import
|
|
249
|
-
import { mx as
|
|
451
|
+
import React11, { useEffect as useEffect3, useMemo as useMemo4 } from "react";
|
|
452
|
+
import { mx as mx7 } from "@dxos/react-ui-theme";
|
|
250
453
|
|
|
251
454
|
// packages/ui/react-ui-form/src/components/Form/FormActions.tsx
|
|
252
|
-
import
|
|
253
|
-
import { IconButton, useTranslation as
|
|
254
|
-
import { mx as
|
|
455
|
+
import React8 from "react";
|
|
456
|
+
import { IconButton as IconButton2, useTranslation as useTranslation3 } from "@dxos/react-ui";
|
|
457
|
+
import { mx as mx4 } from "@dxos/react-ui-theme";
|
|
255
458
|
|
|
256
459
|
// packages/ui/react-ui-form/src/components/Form/FormContext.tsx
|
|
257
|
-
import
|
|
460
|
+
import React7, { createContext, useContext } from "react";
|
|
258
461
|
import { raise } from "@dxos/debug";
|
|
259
462
|
import { getValue as getValue2 } from "@dxos/echo-schema";
|
|
260
463
|
import { createJsonPath as createJsonPath2 } from "@dxos/effect";
|
|
261
464
|
|
|
262
465
|
// packages/ui/react-ui-form/src/hooks/useForm.ts
|
|
263
|
-
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
466
|
+
import { useCallback as useCallback2, useEffect as useEffect2, useMemo, useState as useState2 } from "react";
|
|
264
467
|
import { getValue, setValue } from "@dxos/echo-schema";
|
|
265
468
|
import { AST, createJsonPath, fromEffectValidationPath } from "@dxos/effect";
|
|
266
469
|
import { invariant } from "@dxos/invariant";
|
|
@@ -277,17 +480,17 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
277
480
|
""
|
|
278
481
|
]
|
|
279
482
|
});
|
|
280
|
-
const [values, setValues] =
|
|
281
|
-
|
|
483
|
+
const [values, setValues] = useState2(initialValues);
|
|
484
|
+
useEffect2(() => {
|
|
282
485
|
setValues(initialValues);
|
|
283
486
|
}, [
|
|
284
487
|
initialValues
|
|
285
488
|
]);
|
|
286
|
-
const [touched, setTouched] =
|
|
287
|
-
const [changed, setChanged] =
|
|
288
|
-
const [errors, setErrors] =
|
|
289
|
-
const [saving, setSaving] =
|
|
290
|
-
const validate =
|
|
489
|
+
const [touched, setTouched] = useState2(createKeySet(initialValues, false));
|
|
490
|
+
const [changed, setChanged] = useState2(createKeySet(initialValues, false));
|
|
491
|
+
const [errors, setErrors] = useState2({});
|
|
492
|
+
const [saving, setSaving] = useState2(false);
|
|
493
|
+
const validate = useCallback2((values2) => {
|
|
291
494
|
let errors2 = validateSchema(schema, values2) ?? [];
|
|
292
495
|
if (errors2.length === 0 && onValidate) {
|
|
293
496
|
const validatedValues = values2;
|
|
@@ -300,11 +503,11 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
300
503
|
schema,
|
|
301
504
|
onValidate
|
|
302
505
|
]);
|
|
303
|
-
const [schemaDirty, setSchemaDirty] =
|
|
304
|
-
|
|
506
|
+
const [schemaDirty, setSchemaDirty] = useState2(false);
|
|
507
|
+
useEffect2(() => setSchemaDirty(true), [
|
|
305
508
|
schema
|
|
306
509
|
]);
|
|
307
|
-
|
|
510
|
+
useEffect2(() => {
|
|
308
511
|
if (schemaDirty) {
|
|
309
512
|
validate(values);
|
|
310
513
|
setSchemaDirty(false);
|
|
@@ -319,7 +522,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
319
522
|
errors,
|
|
320
523
|
saving
|
|
321
524
|
]);
|
|
322
|
-
const handleSave =
|
|
525
|
+
const handleSave = useCallback2(async () => {
|
|
323
526
|
if (validate(values)) {
|
|
324
527
|
setSaving(true);
|
|
325
528
|
try {
|
|
@@ -336,7 +539,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
336
539
|
onSave,
|
|
337
540
|
changed
|
|
338
541
|
]);
|
|
339
|
-
const getStatus =
|
|
542
|
+
const getStatus = useCallback2((path) => {
|
|
340
543
|
const jsonPath = Array.isArray(path) ? createJsonPath(path) : path;
|
|
341
544
|
const matchingError = Object.entries(errors).find(([errorPath]) => errorPath === jsonPath || errorPath.startsWith(`${jsonPath}.`) || errorPath.startsWith(`${jsonPath}[`));
|
|
342
545
|
return {
|
|
@@ -359,7 +562,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
359
562
|
} catch (err) {
|
|
360
563
|
log.catch(err, void 0, {
|
|
361
564
|
F: __dxlog_file,
|
|
362
|
-
L:
|
|
565
|
+
L: 193,
|
|
363
566
|
S: void 0,
|
|
364
567
|
C: (f, a) => f(...a)
|
|
365
568
|
});
|
|
@@ -381,7 +584,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
381
584
|
});
|
|
382
585
|
}
|
|
383
586
|
};
|
|
384
|
-
const onTouched =
|
|
587
|
+
const onTouched = useCallback2((path) => {
|
|
385
588
|
const jsonPath = createJsonPath(path);
|
|
386
589
|
setTouched((touched2) => ({
|
|
387
590
|
...touched2,
|
|
@@ -410,7 +613,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
410
613
|
var createKeySet = (obj, value) => {
|
|
411
614
|
invariant(obj, void 0, {
|
|
412
615
|
F: __dxlog_file,
|
|
413
|
-
L:
|
|
616
|
+
L: 235,
|
|
414
617
|
S: void 0,
|
|
415
618
|
A: [
|
|
416
619
|
"obj",
|
|
@@ -453,27 +656,27 @@ var useInputProps = (path = []) => {
|
|
|
453
656
|
};
|
|
454
657
|
var FormProvider = ({ children, ...formOptions }) => {
|
|
455
658
|
const formHandler = useForm(formOptions);
|
|
456
|
-
return /* @__PURE__ */
|
|
659
|
+
return /* @__PURE__ */ React7.createElement(FormContext.Provider, {
|
|
457
660
|
value: formHandler
|
|
458
661
|
}, children);
|
|
459
662
|
};
|
|
460
663
|
|
|
461
664
|
// packages/ui/react-ui-form/src/components/Form/FormActions.tsx
|
|
462
665
|
var FormActions = ({ onCancel, readonly }) => {
|
|
463
|
-
const { t } =
|
|
666
|
+
const { t } = useTranslation3(translationKey);
|
|
464
667
|
const { canSave, handleSave } = useFormContext();
|
|
465
|
-
return /* @__PURE__ */
|
|
668
|
+
return /* @__PURE__ */ React8.createElement("div", {
|
|
466
669
|
role: "none",
|
|
467
|
-
className: "flex justify-center"
|
|
468
|
-
}, /* @__PURE__ */
|
|
670
|
+
className: "mt-2 flex justify-center"
|
|
671
|
+
}, /* @__PURE__ */ React8.createElement("div", {
|
|
469
672
|
role: "none",
|
|
470
|
-
className:
|
|
471
|
-
}, onCancel && !readonly && /* @__PURE__ */
|
|
673
|
+
className: mx4(onCancel && !readonly && "grid grid-cols-2 gap-2")
|
|
674
|
+
}, onCancel && !readonly && /* @__PURE__ */ React8.createElement(IconButton2, {
|
|
472
675
|
"data-testid": "cancel-button",
|
|
473
676
|
icon: "ph--x--regular",
|
|
474
677
|
label: t("button cancel"),
|
|
475
678
|
onClick: onCancel
|
|
476
|
-
}), handleSave && /* @__PURE__ */
|
|
679
|
+
}), handleSave && /* @__PURE__ */ React8.createElement(IconButton2, {
|
|
477
680
|
type: "submit",
|
|
478
681
|
"data-testid": "save-button",
|
|
479
682
|
disabled: !canSave,
|
|
@@ -486,36 +689,36 @@ var FormActions = ({ onCancel, readonly }) => {
|
|
|
486
689
|
// packages/ui/react-ui-form/src/components/Form/FormContent.tsx
|
|
487
690
|
import { pipe as pipe2 } from "effect";
|
|
488
691
|
import { capitalize as capitalize2 } from "effect/String";
|
|
489
|
-
import
|
|
692
|
+
import React10, { useMemo as useMemo3 } from "react";
|
|
490
693
|
import { AST as AST3, S } from "@dxos/echo-schema";
|
|
491
694
|
import { createJsonPath as createJsonPath3, findNode as findNode2, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2 } from "@dxos/effect";
|
|
492
|
-
import { mx as
|
|
695
|
+
import { mx as mx6 } from "@dxos/react-ui-theme";
|
|
493
696
|
import { getSchemaProperties as getSchemaProperties2 } from "@dxos/schema";
|
|
494
697
|
import { isNotFalsy } from "@dxos/util";
|
|
495
698
|
|
|
496
699
|
// packages/ui/react-ui-form/src/components/Form/ArrayField.tsx
|
|
497
700
|
import { pipe } from "effect";
|
|
498
701
|
import { capitalize } from "effect/String";
|
|
499
|
-
import
|
|
702
|
+
import React9, { useCallback as useCallback3, useMemo as useMemo2 } from "react";
|
|
500
703
|
import { AST as AST2 } from "@dxos/echo-schema";
|
|
501
704
|
import { findNode, getDiscriminatedType, isDiscriminatedUnion, SimpleType } from "@dxos/effect";
|
|
502
705
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
503
|
-
import { IconButton as
|
|
504
|
-
import { mx as
|
|
706
|
+
import { IconButton as IconButton3, useTranslation as useTranslation4 } from "@dxos/react-ui";
|
|
707
|
+
import { mx as mx5 } from "@dxos/react-ui-theme";
|
|
505
708
|
import { getSchemaProperties } from "@dxos/schema";
|
|
506
709
|
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/Form/ArrayField.tsx";
|
|
507
710
|
var padding = "px-2";
|
|
508
711
|
var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponent }) => {
|
|
509
|
-
const { t } =
|
|
712
|
+
const { t } = useTranslation4(translationKey);
|
|
510
713
|
const { ast, name, type, title } = property;
|
|
511
714
|
const values = useFormValues(path ?? []);
|
|
512
|
-
invariant2(Array.isArray(values),
|
|
715
|
+
invariant2(Array.isArray(values), `Values at path ${path?.join(".")} must be an array.`, {
|
|
513
716
|
F: __dxlog_file2,
|
|
514
717
|
L: 37,
|
|
515
718
|
S: void 0,
|
|
516
719
|
A: [
|
|
517
720
|
"Array.isArray(values)",
|
|
518
|
-
""
|
|
721
|
+
"`Values at path ${path?.join('.')} must be an array.`"
|
|
519
722
|
]
|
|
520
723
|
});
|
|
521
724
|
const label = title ?? pipe(name, capitalize);
|
|
@@ -542,7 +745,7 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
|
|
|
542
745
|
type,
|
|
543
746
|
elementType
|
|
544
747
|
]);
|
|
545
|
-
const handleAdd =
|
|
748
|
+
const handleAdd = useCallback3(() => {
|
|
546
749
|
inputProps.onValueChange(type, [
|
|
547
750
|
...values,
|
|
548
751
|
newValue
|
|
@@ -554,7 +757,7 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
|
|
|
554
757
|
newValue,
|
|
555
758
|
values
|
|
556
759
|
]);
|
|
557
|
-
const handleRemove =
|
|
760
|
+
const handleRemove = useCallback3((index) => {
|
|
558
761
|
const newValues = values.filter((_, i) => i !== index);
|
|
559
762
|
inputProps.onValueChange(type, newValues);
|
|
560
763
|
}, [
|
|
@@ -565,20 +768,20 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
|
|
|
565
768
|
if (!elementType) {
|
|
566
769
|
return null;
|
|
567
770
|
}
|
|
568
|
-
return /* @__PURE__ */
|
|
771
|
+
return /* @__PURE__ */ React9.createElement("div", {
|
|
569
772
|
role: "none",
|
|
570
|
-
className:
|
|
571
|
-
}, /* @__PURE__ */
|
|
773
|
+
className: mx5(padding)
|
|
774
|
+
}, /* @__PURE__ */ React9.createElement(InputHeader, null, label), /* @__PURE__ */ React9.createElement("div", {
|
|
572
775
|
role: "none",
|
|
573
776
|
className: "flex flex-col gap-1"
|
|
574
|
-
}, values.map((_value, index) => /* @__PURE__ */
|
|
777
|
+
}, values.map((_value, index) => /* @__PURE__ */ React9.createElement("div", {
|
|
575
778
|
key: index,
|
|
576
779
|
role: "none",
|
|
577
780
|
className: "flex items-center gap-1"
|
|
578
|
-
}, /* @__PURE__ */
|
|
781
|
+
}, /* @__PURE__ */ React9.createElement("div", {
|
|
579
782
|
role: "none",
|
|
580
783
|
className: "flex-1"
|
|
581
|
-
}, /* @__PURE__ */
|
|
784
|
+
}, /* @__PURE__ */ React9.createElement(FormField, {
|
|
582
785
|
property: {
|
|
583
786
|
...property,
|
|
584
787
|
array: false,
|
|
@@ -592,15 +795,15 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
|
|
|
592
795
|
inline: true,
|
|
593
796
|
Custom,
|
|
594
797
|
lookupComponent
|
|
595
|
-
})), /* @__PURE__ */
|
|
798
|
+
})), /* @__PURE__ */ React9.createElement(IconButton3, {
|
|
596
799
|
icon: "ph--trash--regular",
|
|
597
800
|
iconOnly: true,
|
|
598
801
|
label: t("button remove"),
|
|
599
802
|
onClick: () => handleRemove(index)
|
|
600
|
-
})))), /* @__PURE__ */
|
|
803
|
+
})))), /* @__PURE__ */ React9.createElement("div", {
|
|
601
804
|
role: "none",
|
|
602
805
|
className: "flex justify-between items-center plb-1"
|
|
603
|
-
}, /* @__PURE__ */
|
|
806
|
+
}, /* @__PURE__ */ React9.createElement(IconButton3, {
|
|
604
807
|
icon: "ph--plus--regular",
|
|
605
808
|
iconOnly: true,
|
|
606
809
|
label: t("button add"),
|
|
@@ -637,15 +840,6 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
|
|
|
637
840
|
examples,
|
|
638
841
|
description
|
|
639
842
|
]);
|
|
640
|
-
if (array) {
|
|
641
|
-
return /* @__PURE__ */ React9.createElement(ArrayField, {
|
|
642
|
-
property,
|
|
643
|
-
path,
|
|
644
|
-
inputProps,
|
|
645
|
-
readonly,
|
|
646
|
-
Custom
|
|
647
|
-
});
|
|
648
|
-
}
|
|
649
843
|
const FoundComponent = lookupComponent?.({
|
|
650
844
|
prop: name,
|
|
651
845
|
schema: S.make(ast),
|
|
@@ -659,12 +853,42 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
|
|
|
659
853
|
}
|
|
660
854
|
});
|
|
661
855
|
if (FoundComponent) {
|
|
662
|
-
return /* @__PURE__ */
|
|
856
|
+
return /* @__PURE__ */ React10.createElement("div", {
|
|
857
|
+
role: "none"
|
|
858
|
+
}, FoundComponent);
|
|
663
859
|
}
|
|
664
860
|
const jsonPath = createJsonPath3(path ?? []);
|
|
665
|
-
const
|
|
861
|
+
const CustomComponent = Custom?.[jsonPath];
|
|
862
|
+
if (CustomComponent) {
|
|
863
|
+
return (
|
|
864
|
+
// TODO(ZaymonFC): We should try to remove this div wrapper.
|
|
865
|
+
/* @__PURE__ */ React10.createElement("div", {
|
|
866
|
+
role: "none"
|
|
867
|
+
}, /* @__PURE__ */ React10.createElement(CustomComponent, {
|
|
868
|
+
type,
|
|
869
|
+
format,
|
|
870
|
+
label,
|
|
871
|
+
inputOnly: inline,
|
|
872
|
+
placeholder,
|
|
873
|
+
disabled: readonly,
|
|
874
|
+
...inputProps
|
|
875
|
+
}))
|
|
876
|
+
);
|
|
877
|
+
}
|
|
878
|
+
if (array) {
|
|
879
|
+
return /* @__PURE__ */ React10.createElement(ArrayField, {
|
|
880
|
+
property,
|
|
881
|
+
path,
|
|
882
|
+
inputProps,
|
|
883
|
+
readonly,
|
|
884
|
+
Custom
|
|
885
|
+
});
|
|
886
|
+
}
|
|
887
|
+
const InputComponent = getInputComponent(type, format);
|
|
666
888
|
if (InputComponent) {
|
|
667
|
-
return /* @__PURE__ */
|
|
889
|
+
return /* @__PURE__ */ React10.createElement("div", {
|
|
890
|
+
role: "none"
|
|
891
|
+
}, /* @__PURE__ */ React10.createElement(InputComponent, {
|
|
668
892
|
type,
|
|
669
893
|
format,
|
|
670
894
|
label,
|
|
@@ -675,9 +899,9 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
|
|
|
675
899
|
}));
|
|
676
900
|
}
|
|
677
901
|
if (options) {
|
|
678
|
-
return /* @__PURE__ */
|
|
902
|
+
return /* @__PURE__ */ React10.createElement("div", {
|
|
679
903
|
role: "none"
|
|
680
|
-
}, /* @__PURE__ */
|
|
904
|
+
}, /* @__PURE__ */ React10.createElement(SelectInput, {
|
|
681
905
|
type,
|
|
682
906
|
format,
|
|
683
907
|
disabled: readonly,
|
|
@@ -695,7 +919,9 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
|
|
|
695
919
|
const baseNode = findNode2(ast, isDiscriminatedUnion2);
|
|
696
920
|
const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, inputProps.getValue()) : findNode2(ast, AST3.isTypeLiteral);
|
|
697
921
|
if (typeLiteral) {
|
|
698
|
-
return /* @__PURE__ */
|
|
922
|
+
return /* @__PURE__ */ React10.createElement("div", {
|
|
923
|
+
role: "none"
|
|
924
|
+
}, !inline && /* @__PURE__ */ React10.createElement("div", null, label), /* @__PURE__ */ React10.createElement(FormFields, {
|
|
699
925
|
schema: S.make(typeLiteral),
|
|
700
926
|
path,
|
|
701
927
|
readonly,
|
|
@@ -717,11 +943,11 @@ var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custo
|
|
|
717
943
|
filter,
|
|
718
944
|
sort
|
|
719
945
|
]);
|
|
720
|
-
return /* @__PURE__ */
|
|
946
|
+
return /* @__PURE__ */ React10.createElement("div", {
|
|
721
947
|
role: "form",
|
|
722
|
-
className:
|
|
948
|
+
className: mx6("flex flex-col w-full gap-2")
|
|
723
949
|
}, properties.map((property) => {
|
|
724
|
-
return /* @__PURE__ */
|
|
950
|
+
return /* @__PURE__ */ React10.createElement(FormField, {
|
|
725
951
|
key: property.name,
|
|
726
952
|
property,
|
|
727
953
|
path: [
|
|
@@ -736,23 +962,33 @@ var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custo
|
|
|
736
962
|
};
|
|
737
963
|
|
|
738
964
|
// packages/ui/react-ui-form/src/components/Form/Form.tsx
|
|
739
|
-
var Form = ({ classNames, schema, values: initialValues, path = [], readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, lookupComponent, Custom }) => {
|
|
965
|
+
var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, lookupComponent, Custom }) => {
|
|
740
966
|
const onValid = useMemo4(() => autoSave ? onSave : void 0, [
|
|
741
967
|
autoSave,
|
|
742
968
|
onSave
|
|
743
969
|
]);
|
|
744
|
-
|
|
970
|
+
useEffect3(() => {
|
|
971
|
+
if (autoFocus) {
|
|
972
|
+
const input = document.querySelector("input");
|
|
973
|
+
if (input) {
|
|
974
|
+
input.focus();
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
}, [
|
|
978
|
+
autoFocus
|
|
979
|
+
]);
|
|
980
|
+
return /* @__PURE__ */ React11.createElement(FormProvider, {
|
|
745
981
|
schema,
|
|
746
982
|
initialValues,
|
|
747
983
|
onValuesChanged,
|
|
748
984
|
onValidate,
|
|
749
985
|
onValid,
|
|
750
986
|
onSave
|
|
751
|
-
}, /* @__PURE__ */
|
|
987
|
+
}, /* @__PURE__ */ React11.createElement("div", {
|
|
752
988
|
role: "none",
|
|
753
|
-
className:
|
|
989
|
+
className: mx7("p-2", classNames),
|
|
754
990
|
"data-testid": testId
|
|
755
|
-
}, /* @__PURE__ */
|
|
991
|
+
}, /* @__PURE__ */ React11.createElement(FormFields, {
|
|
756
992
|
schema,
|
|
757
993
|
path,
|
|
758
994
|
readonly,
|
|
@@ -760,7 +996,7 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
|
|
|
760
996
|
sort,
|
|
761
997
|
lookupComponent,
|
|
762
998
|
Custom
|
|
763
|
-
}), (onCancel || onSave) && !autoSave && /* @__PURE__ */
|
|
999
|
+
}), (onCancel || onSave) && !autoSave && /* @__PURE__ */ React11.createElement(FormActions, {
|
|
764
1000
|
onCancel,
|
|
765
1001
|
readonly
|
|
766
1002
|
})));
|
|
@@ -769,14 +1005,14 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
|
|
|
769
1005
|
// packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx
|
|
770
1006
|
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
|
|
771
1007
|
var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
772
|
-
const { t } =
|
|
773
|
-
const [props, setProps] =
|
|
774
|
-
|
|
1008
|
+
const { t } = useTranslation5(translationKey);
|
|
1009
|
+
const [props, setProps] = useState3(projection.getFieldProjection(field.id).props);
|
|
1010
|
+
useEffect4(() => setProps(projection.getFieldProjection(field.id).props), [
|
|
775
1011
|
field,
|
|
776
1012
|
projection
|
|
777
1013
|
]);
|
|
778
|
-
const [schemas, setSchemas] =
|
|
779
|
-
|
|
1014
|
+
const [schemas, setSchemas] = useState3([]);
|
|
1015
|
+
useEffect4(() => {
|
|
780
1016
|
if (!registry) {
|
|
781
1017
|
return;
|
|
782
1018
|
}
|
|
@@ -794,17 +1030,17 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
794
1030
|
}, [
|
|
795
1031
|
registry
|
|
796
1032
|
]);
|
|
797
|
-
const [referenceSchema, setReferenceSchema] =
|
|
798
|
-
|
|
1033
|
+
const [referenceSchema, setReferenceSchema] = useState3();
|
|
1034
|
+
useEffect4(() => {
|
|
799
1035
|
setReferenceSchema(schemas.find((schema) => schema.typename === props?.referenceSchema));
|
|
800
1036
|
}, [
|
|
801
1037
|
schemas,
|
|
802
1038
|
props?.referenceSchema
|
|
803
1039
|
]);
|
|
804
|
-
const [{ fieldSchema }, setFieldSchema] =
|
|
1040
|
+
const [{ fieldSchema }, setFieldSchema] = useState3({
|
|
805
1041
|
fieldSchema: getFormatSchema(props?.format)
|
|
806
1042
|
});
|
|
807
|
-
const handleValuesChanged =
|
|
1043
|
+
const handleValuesChanged = useCallback4((_props) => {
|
|
808
1044
|
setFieldSchema((prev) => {
|
|
809
1045
|
const fieldSchema2 = getFormatSchema(_props.format);
|
|
810
1046
|
if (prev.fieldSchema === fieldSchema2) {
|
|
@@ -832,14 +1068,14 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
832
1068
|
type
|
|
833
1069
|
};
|
|
834
1070
|
}
|
|
835
|
-
return
|
|
1071
|
+
return _props;
|
|
836
1072
|
});
|
|
837
1073
|
}, [
|
|
838
1074
|
schemas,
|
|
839
1075
|
props.format,
|
|
840
1076
|
props.referenceSchema
|
|
841
1077
|
]);
|
|
842
|
-
const handleValidate =
|
|
1078
|
+
const handleValidate = useCallback4(({ property }) => {
|
|
843
1079
|
if (property && view.fields.find((f) => f.path === property && f.path !== field.path)) {
|
|
844
1080
|
return [
|
|
845
1081
|
{
|
|
@@ -852,7 +1088,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
852
1088
|
view.fields,
|
|
853
1089
|
field
|
|
854
1090
|
]);
|
|
855
|
-
const handleSave =
|
|
1091
|
+
const handleSave = useCallback4((props2) => {
|
|
856
1092
|
projection.setFieldProjection({
|
|
857
1093
|
field,
|
|
858
1094
|
props: props2
|
|
@@ -863,50 +1099,51 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
863
1099
|
field,
|
|
864
1100
|
onSave
|
|
865
1101
|
]);
|
|
866
|
-
const handleCancel =
|
|
1102
|
+
const handleCancel = useCallback4(() => {
|
|
867
1103
|
requestAnimationFrame(() => onCancel?.());
|
|
868
1104
|
onSave();
|
|
869
1105
|
}, [
|
|
870
1106
|
onSave
|
|
871
1107
|
]);
|
|
872
1108
|
const Custom = useMemo5(() => ({
|
|
873
|
-
["format"]: (props2) => /* @__PURE__ */
|
|
1109
|
+
["format"]: (props2) => /* @__PURE__ */ React12.createElement(SelectInput, {
|
|
874
1110
|
...props2,
|
|
875
1111
|
options: FormatEnums.filter((value) => value !== FormatEnum2.None).map((value) => ({
|
|
876
1112
|
value,
|
|
877
1113
|
label: t(`format ${value}`)
|
|
878
1114
|
}))
|
|
879
1115
|
}),
|
|
880
|
-
["referenceSchema"]: (props2) => /* @__PURE__ */
|
|
1116
|
+
["referenceSchema"]: (props2) => /* @__PURE__ */ React12.createElement(SelectInput, {
|
|
881
1117
|
...props2,
|
|
882
1118
|
options: schemas.map((schema) => ({
|
|
883
1119
|
value: schema.typename
|
|
884
1120
|
}))
|
|
885
1121
|
}),
|
|
886
|
-
["referencePath"]: (props2) => /* @__PURE__ */
|
|
1122
|
+
["referencePath"]: (props2) => /* @__PURE__ */ React12.createElement(SelectInput, {
|
|
887
1123
|
...props2,
|
|
888
1124
|
options: referenceSchema ? getSchemaProperties3(referenceSchema.ast).sort(sortProperties).map((p) => ({
|
|
889
1125
|
value: p.name
|
|
890
1126
|
})) : []
|
|
891
|
-
})
|
|
1127
|
+
}),
|
|
1128
|
+
["options"]: (props2) => /* @__PURE__ */ React12.createElement(SelectOptionInput, props2)
|
|
892
1129
|
}), [
|
|
893
1130
|
t,
|
|
894
1131
|
schemas,
|
|
895
1132
|
referenceSchema
|
|
896
1133
|
]);
|
|
897
|
-
const propIsNotType =
|
|
1134
|
+
const propIsNotType = useCallback4((props2) => props2.filter((p) => p.name !== "type"), []);
|
|
898
1135
|
if (!fieldSchema) {
|
|
899
1136
|
log2.warn("invalid format", {
|
|
900
1137
|
props
|
|
901
1138
|
}, {
|
|
902
1139
|
F: __dxlog_file3,
|
|
903
|
-
L:
|
|
1140
|
+
L: 174,
|
|
904
1141
|
S: void 0,
|
|
905
1142
|
C: (f, a) => f(...a)
|
|
906
1143
|
});
|
|
907
1144
|
return null;
|
|
908
1145
|
}
|
|
909
|
-
return /* @__PURE__ */
|
|
1146
|
+
return /* @__PURE__ */ React12.createElement(Form, {
|
|
910
1147
|
key: field.id,
|
|
911
1148
|
autoFocus: true,
|
|
912
1149
|
values: props,
|
|
@@ -925,13 +1162,12 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
925
1162
|
};
|
|
926
1163
|
|
|
927
1164
|
// packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx
|
|
928
|
-
import
|
|
1165
|
+
import React13, { useCallback as useCallback5, useMemo as useMemo6, useState as useState4 } from "react";
|
|
929
1166
|
import { AST as AST4, Format, S as S2 } from "@dxos/echo-schema";
|
|
930
|
-
import { IconButton as
|
|
931
|
-
import { List } from "@dxos/react-ui-list";
|
|
932
|
-
import { ghostHover, inputTextLabel, mx as
|
|
1167
|
+
import { IconButton as IconButton4, useTranslation as useTranslation6 } from "@dxos/react-ui";
|
|
1168
|
+
import { List as List2 } from "@dxos/react-ui-list";
|
|
1169
|
+
import { ghostHover, inputTextLabel, mx as mx8 } from "@dxos/react-ui-theme";
|
|
933
1170
|
import { FieldSchema, ViewProjection, VIEW_FIELD_LIMIT } from "@dxos/schema";
|
|
934
|
-
import { arrayMove } from "@dxos/util";
|
|
935
1171
|
var grid = "grid grid-cols-[32px_1fr_32px] min-bs-[2.5rem]";
|
|
936
1172
|
var ViewMetaSchema = S2.Struct({
|
|
937
1173
|
name: S2.String.annotations({
|
|
@@ -942,12 +1178,12 @@ var ViewMetaSchema = S2.Struct({
|
|
|
942
1178
|
})
|
|
943
1179
|
}).pipe(S2.mutable);
|
|
944
1180
|
var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading = false, onTypenameChanged, onDelete }) => {
|
|
945
|
-
const { t } =
|
|
1181
|
+
const { t } = useTranslation6(translationKey);
|
|
946
1182
|
const projection = useMemo6(() => new ViewProjection(schema, view), [
|
|
947
1183
|
schema,
|
|
948
1184
|
view
|
|
949
1185
|
]);
|
|
950
|
-
const [field, setField] =
|
|
1186
|
+
const [field, setField] = useState4();
|
|
951
1187
|
const viewValues = useMemo6(() => {
|
|
952
1188
|
return {
|
|
953
1189
|
name: view.name,
|
|
@@ -958,7 +1194,7 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
958
1194
|
}, [
|
|
959
1195
|
view
|
|
960
1196
|
]);
|
|
961
|
-
const handleViewUpdate =
|
|
1197
|
+
const handleViewUpdate = useCallback5(({ name, typename }) => {
|
|
962
1198
|
requestAnimationFrame(() => {
|
|
963
1199
|
if (view.name !== name) {
|
|
964
1200
|
view.name = name;
|
|
@@ -972,67 +1208,72 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
972
1208
|
schema,
|
|
973
1209
|
onTypenameChanged
|
|
974
1210
|
]);
|
|
975
|
-
const handleSelect =
|
|
1211
|
+
const handleSelect = useCallback5((field2) => {
|
|
976
1212
|
setField((f) => f === field2 ? void 0 : field2);
|
|
977
1213
|
}, []);
|
|
978
|
-
const handleAdd =
|
|
1214
|
+
const handleAdd = useCallback5(() => {
|
|
979
1215
|
const field2 = projection.createFieldProjection();
|
|
980
1216
|
setField(field2);
|
|
981
1217
|
}, [
|
|
982
1218
|
view
|
|
983
1219
|
]);
|
|
984
|
-
const handleMove =
|
|
985
|
-
|
|
1220
|
+
const handleMove = useCallback5((fromIndex, toIndex) => {
|
|
1221
|
+
const fields = [
|
|
1222
|
+
...view.fields
|
|
1223
|
+
];
|
|
1224
|
+
const [moved] = fields.splice(fromIndex, 1);
|
|
1225
|
+
fields.splice(toIndex, 0, moved);
|
|
1226
|
+
view.fields = fields;
|
|
986
1227
|
}, [
|
|
987
1228
|
view.fields
|
|
988
1229
|
]);
|
|
989
|
-
const handleClose =
|
|
990
|
-
return /* @__PURE__ */
|
|
1230
|
+
const handleClose = useCallback5(() => setField(void 0), []);
|
|
1231
|
+
return /* @__PURE__ */ React13.createElement("div", {
|
|
991
1232
|
role: "none",
|
|
992
|
-
className:
|
|
993
|
-
}, /* @__PURE__ */
|
|
1233
|
+
className: mx8("flex flex-col w-full divide-y divide-separator", classNames)
|
|
1234
|
+
}, /* @__PURE__ */ React13.createElement(Form, {
|
|
994
1235
|
autoFocus: true,
|
|
995
1236
|
autoSave: true,
|
|
996
1237
|
schema: ViewMetaSchema,
|
|
997
1238
|
values: viewValues,
|
|
998
1239
|
onSave: handleViewUpdate
|
|
999
|
-
}), /* @__PURE__ */
|
|
1240
|
+
}), /* @__PURE__ */ React13.createElement("div", null, /* @__PURE__ */ React13.createElement("div", {
|
|
1000
1241
|
role: "none",
|
|
1001
1242
|
className: "p-2"
|
|
1002
|
-
}, /* @__PURE__ */
|
|
1003
|
-
className:
|
|
1004
|
-
}, t("fields label"))), /* @__PURE__ */
|
|
1243
|
+
}, /* @__PURE__ */ React13.createElement("label", {
|
|
1244
|
+
className: mx8(inputTextLabel)
|
|
1245
|
+
}, t("fields label"))), /* @__PURE__ */ React13.createElement(List2.Root, {
|
|
1005
1246
|
items: view.fields,
|
|
1006
1247
|
isItem: S2.is(FieldSchema),
|
|
1007
1248
|
getId: (field2) => field2.id,
|
|
1008
1249
|
onMove: handleMove
|
|
1009
|
-
}, ({ items: fields }) => /* @__PURE__ */
|
|
1250
|
+
}, ({ items: fields }) => /* @__PURE__ */ React13.createElement(React13.Fragment, null, showHeading && /* @__PURE__ */ React13.createElement("div", {
|
|
1010
1251
|
role: "heading",
|
|
1011
1252
|
className: grid
|
|
1012
|
-
}, /* @__PURE__ */
|
|
1253
|
+
}, /* @__PURE__ */ React13.createElement("div", null), /* @__PURE__ */ React13.createElement("div", {
|
|
1013
1254
|
className: "flex items-center text-sm"
|
|
1014
|
-
}, t("field path label"))), /* @__PURE__ */
|
|
1255
|
+
}, t("field path label"))), /* @__PURE__ */ React13.createElement("div", {
|
|
1015
1256
|
role: "list",
|
|
1016
1257
|
className: "flex flex-col w-full"
|
|
1017
|
-
}, fields?.map((field2) => /* @__PURE__ */
|
|
1258
|
+
}, fields?.map((field2) => /* @__PURE__ */ React13.createElement(List2.Item, {
|
|
1018
1259
|
key: field2.id,
|
|
1019
1260
|
item: field2,
|
|
1020
|
-
classNames:
|
|
1021
|
-
}, /* @__PURE__ */
|
|
1261
|
+
classNames: mx8(grid, ghostHover, "cursor-pointer")
|
|
1262
|
+
}, /* @__PURE__ */ React13.createElement(List2.ItemDragHandle, null), /* @__PURE__ */ React13.createElement(List2.ItemTitle, {
|
|
1022
1263
|
onClick: () => handleSelect(field2)
|
|
1023
|
-
}, field2.path), /* @__PURE__ */
|
|
1264
|
+
}, field2.path), /* @__PURE__ */ React13.createElement(List2.ItemDeleteButton, {
|
|
1024
1265
|
disabled: view.fields.length <= 1,
|
|
1025
1266
|
onClick: () => onDelete(field2.id)
|
|
1026
|
-
}))))))), field && /* @__PURE__ */
|
|
1267
|
+
}))))))), field && /* @__PURE__ */ React13.createElement(FieldEditor, {
|
|
1027
1268
|
key: field.id,
|
|
1028
1269
|
view,
|
|
1029
1270
|
projection,
|
|
1030
1271
|
field,
|
|
1031
1272
|
registry,
|
|
1032
1273
|
onSave: handleClose
|
|
1033
|
-
}), !readonly && !field && /* @__PURE__ */
|
|
1274
|
+
}), !readonly && !field && /* @__PURE__ */ React13.createElement("div", {
|
|
1034
1275
|
className: "flex p-2 justify-center"
|
|
1035
|
-
}, /* @__PURE__ */
|
|
1276
|
+
}, /* @__PURE__ */ React13.createElement(IconButton4, {
|
|
1036
1277
|
icon: "ph--plus--regular",
|
|
1037
1278
|
label: t("button add property"),
|
|
1038
1279
|
onClick: handleAdd,
|
|
@@ -1262,6 +1503,7 @@ var formatForEditing = ({ type, format, value, locale = void 0 }) => {
|
|
|
1262
1503
|
};
|
|
1263
1504
|
export {
|
|
1264
1505
|
BooleanInput,
|
|
1506
|
+
DeprecatedFormContainer,
|
|
1265
1507
|
DeprecatedFormInput,
|
|
1266
1508
|
FieldEditor,
|
|
1267
1509
|
Form,
|
|
@@ -1269,6 +1511,7 @@ export {
|
|
|
1269
1511
|
InputHeader,
|
|
1270
1512
|
NumberInput,
|
|
1271
1513
|
SelectInput,
|
|
1514
|
+
SelectOptionInput,
|
|
1272
1515
|
TextInput,
|
|
1273
1516
|
TupleInput,
|
|
1274
1517
|
ViewEditor,
|