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