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