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