@dxos/react-ui-form 0.7.2 → 0.7.3-staging.0905f03
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 +228 -58
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +228 -57
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +228 -58
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts +2 -2
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
- package/dist/types/src/components/Form/Defaults.d.ts +4 -4
- package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.d.ts +11 -2
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts +20 -5
- package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/Input.d.ts +5 -4
- package/dist/types/src/components/Form/Input.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
- package/dist/types/src/components/deprecated/Form.stories.d.ts.map +1 -1
- package/dist/types/src/hooks/useForm.d.ts +19 -11
- package/dist/types/src/hooks/useForm.d.ts.map +1 -1
- package/package.json +23 -22
- package/src/components/FieldEditor/FieldEditor.stories.tsx +3 -3
- package/src/components/FieldEditor/FieldEditor.tsx +8 -8
- package/src/components/Form/Defaults.tsx +28 -13
- package/src/components/Form/Form.stories.tsx +81 -19
- package/src/components/Form/Form.tsx +216 -29
- package/src/components/Form/Input.tsx +5 -4
- package/src/components/ViewEditor/ViewEditor.tsx +8 -7
- package/src/components/deprecated/Form.stories.tsx +4 -4
- package/src/hooks/useForm.ts +65 -32
package/dist/lib/node/index.cjs
CHANGED
|
@@ -32,6 +32,7 @@ __export(node_exports, {
|
|
|
32
32
|
DeprecatedFormInput: () => DeprecatedFormInput,
|
|
33
33
|
FieldEditor: () => FieldEditor,
|
|
34
34
|
Form: () => Form,
|
|
35
|
+
FormActions: () => FormActions,
|
|
35
36
|
GeiPointInput: () => GeiPointInput,
|
|
36
37
|
InputHeader: () => InputHeader,
|
|
37
38
|
NumberInput: () => NumberInput,
|
|
@@ -175,11 +176,11 @@ var InputHeader = ({ children, error }) => {
|
|
|
175
176
|
side: "bottom"
|
|
176
177
|
}, /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Tooltip.Arrow, null), error)));
|
|
177
178
|
};
|
|
178
|
-
var TextInput = ({ property, type, label, disabled, placeholder, getStatus, getValue, onValueChange, onBlur }) => {
|
|
179
|
+
var TextInput = ({ property, type, label, inputOnly, disabled, placeholder, getStatus, getValue, onValueChange, onBlur }) => {
|
|
179
180
|
const { status, error } = getStatus?.(property);
|
|
180
181
|
return /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.Root, {
|
|
181
182
|
validationValence: status
|
|
182
|
-
}, /* @__PURE__ */ import_react4.default.createElement(InputHeader, {
|
|
183
|
+
}, !inputOnly && /* @__PURE__ */ import_react4.default.createElement(InputHeader, {
|
|
183
184
|
error
|
|
184
185
|
}, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.Label, null, label)), /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.TextInput, {
|
|
185
186
|
disabled,
|
|
@@ -187,13 +188,13 @@ var TextInput = ({ property, type, label, disabled, placeholder, getStatus, getV
|
|
|
187
188
|
value: getValue(property) ?? "",
|
|
188
189
|
onChange: (event) => onValueChange(property, type, event.target.value),
|
|
189
190
|
onBlur
|
|
190
|
-
}));
|
|
191
|
+
}), inputOnly && /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.Validation, null, error));
|
|
191
192
|
};
|
|
192
|
-
var NumberInput = ({ property, type, label, disabled, placeholder, getStatus, getValue, onValueChange, onBlur }) => {
|
|
193
|
+
var NumberInput = ({ property, type, label, inputOnly, disabled, placeholder, getStatus, getValue, onValueChange, onBlur }) => {
|
|
193
194
|
const { status, error } = getStatus?.(property);
|
|
194
195
|
return /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.Root, {
|
|
195
196
|
validationValence: status
|
|
196
|
-
}, /* @__PURE__ */ import_react4.default.createElement(InputHeader, {
|
|
197
|
+
}, !inputOnly && /* @__PURE__ */ import_react4.default.createElement(InputHeader, {
|
|
197
198
|
error
|
|
198
199
|
}, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.Label, null, label)), /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.TextInput, {
|
|
199
200
|
type: "number",
|
|
@@ -202,24 +203,24 @@ var NumberInput = ({ property, type, label, disabled, placeholder, getStatus, ge
|
|
|
202
203
|
value: getValue(property) ?? 0,
|
|
203
204
|
onChange: (event) => onValueChange(property, type, event.target.value),
|
|
204
205
|
onBlur
|
|
205
|
-
}));
|
|
206
|
+
}), inputOnly && /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.DescriptionAndValidation, null, error));
|
|
206
207
|
};
|
|
207
|
-
var BooleanInput = ({ property, type, label, getStatus, getValue, onValueChange }) => {
|
|
208
|
+
var BooleanInput = ({ property, type, label, inputOnly, getStatus, getValue, onValueChange }) => {
|
|
208
209
|
const { status, error } = getStatus?.(property);
|
|
209
210
|
return /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.Root, {
|
|
210
211
|
validationValence: status
|
|
211
|
-
}, /* @__PURE__ */ import_react4.default.createElement(InputHeader, {
|
|
212
|
+
}, !inputOnly && /* @__PURE__ */ import_react4.default.createElement(InputHeader, {
|
|
212
213
|
error
|
|
213
214
|
}, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.Label, null, label)), /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.Switch, {
|
|
214
215
|
checked: getValue(property),
|
|
215
216
|
onCheckedChange: (value) => onValueChange(property, type, value)
|
|
216
|
-
}));
|
|
217
|
+
}), inputOnly && /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.DescriptionAndValidation, null, error));
|
|
217
218
|
};
|
|
218
|
-
var SelectInput = ({ property, type, label, disabled, placeholder, options, getStatus, getValue, onValueChange }) => {
|
|
219
|
+
var SelectInput = ({ property, type, label, inputOnly, disabled, placeholder, options, getStatus, getValue, onValueChange }) => {
|
|
219
220
|
const { status, error } = getStatus?.(property);
|
|
220
221
|
return /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.Root, {
|
|
221
222
|
validationValence: status
|
|
222
|
-
}, /* @__PURE__ */ import_react4.default.createElement(InputHeader, {
|
|
223
|
+
}, !inputOnly && /* @__PURE__ */ import_react4.default.createElement(InputHeader, {
|
|
223
224
|
error
|
|
224
225
|
}, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.Label, null, label)), /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Select.Root, {
|
|
225
226
|
value: getValue(property),
|
|
@@ -234,7 +235,7 @@ var SelectInput = ({ property, type, label, disabled, placeholder, options, getS
|
|
|
234
235
|
key: String(value),
|
|
235
236
|
value: String(value)
|
|
236
237
|
}, label2 ?? String(value))
|
|
237
|
-
)))))));
|
|
238
|
+
)))))), inputOnly && /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Input.DescriptionAndValidation, null, error));
|
|
238
239
|
};
|
|
239
240
|
var GeiPointInput = ({ property, type, label, disabled, getStatus, getValue, onValueChange, onBlur }) => {
|
|
240
241
|
const { t } = (0, import_react_ui6.useTranslation)(translationKey);
|
|
@@ -290,7 +291,7 @@ var getInputComponent = (type, format) => {
|
|
|
290
291
|
}
|
|
291
292
|
};
|
|
292
293
|
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/hooks/useForm.ts";
|
|
293
|
-
var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid,
|
|
294
|
+
var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, onSave }) => {
|
|
294
295
|
const [values, setValues] = (0, import_react7.useState)(initialValues);
|
|
295
296
|
(0, import_react7.useEffect)(() => {
|
|
296
297
|
setValues(initialValues);
|
|
@@ -300,6 +301,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
300
301
|
const [touched, setTouched] = (0, import_react7.useState)(createKeySet(initialValues, false));
|
|
301
302
|
const [changed, setChanged] = (0, import_react7.useState)(createKeySet(initialValues, false));
|
|
302
303
|
const [errors, setErrors] = (0, import_react7.useState)({});
|
|
304
|
+
const [saving, setSaving] = (0, import_react7.useState)(false);
|
|
303
305
|
const validate = (0, import_react7.useCallback)((values2) => {
|
|
304
306
|
let errors2 = (0, import_schema3.validateSchema)(schema, values2) ?? [];
|
|
305
307
|
if (errors2.length === 0 && onValidate) {
|
|
@@ -324,21 +326,27 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
324
326
|
values,
|
|
325
327
|
schemaDirty
|
|
326
328
|
]);
|
|
327
|
-
const
|
|
329
|
+
const canSave = (0, import_react7.useMemo)(() => !saving && Object.keys(values).every((property) => touched[property] === false || !errors[property]), [
|
|
328
330
|
values,
|
|
329
331
|
touched,
|
|
330
|
-
errors
|
|
332
|
+
errors,
|
|
333
|
+
saving
|
|
331
334
|
]);
|
|
332
|
-
const
|
|
335
|
+
const handleSave = (0, import_react7.useCallback)(async () => {
|
|
333
336
|
if (validate(values)) {
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
+
setSaving(true);
|
|
338
|
+
try {
|
|
339
|
+
await onSave?.(values, {
|
|
340
|
+
changed
|
|
341
|
+
});
|
|
342
|
+
} finally {
|
|
343
|
+
setSaving(false);
|
|
344
|
+
}
|
|
337
345
|
}
|
|
338
346
|
}, [
|
|
339
347
|
values,
|
|
340
348
|
validate,
|
|
341
|
-
|
|
349
|
+
onSave
|
|
342
350
|
]);
|
|
343
351
|
const getStatus = (0, import_react7.useCallback)((property) => ({
|
|
344
352
|
status: errors[property] ? "error" : void 0,
|
|
@@ -348,7 +356,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
348
356
|
errors
|
|
349
357
|
]);
|
|
350
358
|
const getValue = (property) => {
|
|
351
|
-
return values
|
|
359
|
+
return getByPath(values, property);
|
|
352
360
|
};
|
|
353
361
|
const onValueChange = (property, type, value) => {
|
|
354
362
|
let parsedValue = value;
|
|
@@ -359,16 +367,13 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
359
367
|
} catch (err) {
|
|
360
368
|
import_log3.log.catch(err, void 0, {
|
|
361
369
|
F: __dxlog_file,
|
|
362
|
-
L:
|
|
370
|
+
L: 183,
|
|
363
371
|
S: void 0,
|
|
364
372
|
C: (f, a) => f(...a)
|
|
365
373
|
});
|
|
366
374
|
parsedValue = void 0;
|
|
367
375
|
}
|
|
368
|
-
const newValues =
|
|
369
|
-
...values,
|
|
370
|
-
[property]: parsedValue
|
|
371
|
-
};
|
|
376
|
+
const newValues = setByPath(values, property, parsedValue);
|
|
372
377
|
setValues(newValues);
|
|
373
378
|
setChanged((prev) => ({
|
|
374
379
|
...prev,
|
|
@@ -402,8 +407,8 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
402
407
|
errors,
|
|
403
408
|
touched,
|
|
404
409
|
changed,
|
|
405
|
-
|
|
406
|
-
|
|
410
|
+
canSave,
|
|
411
|
+
handleSave,
|
|
407
412
|
// Field utils.
|
|
408
413
|
getStatus,
|
|
409
414
|
getValue,
|
|
@@ -414,7 +419,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
414
419
|
var createKeySet = (obj, value) => {
|
|
415
420
|
(0, import_invariant.invariant)(obj, void 0, {
|
|
416
421
|
F: __dxlog_file,
|
|
417
|
-
L:
|
|
422
|
+
L: 234,
|
|
418
423
|
S: void 0,
|
|
419
424
|
A: [
|
|
420
425
|
"obj",
|
|
@@ -434,21 +439,34 @@ var flatMap = (errors) => {
|
|
|
434
439
|
return result;
|
|
435
440
|
}, {});
|
|
436
441
|
};
|
|
442
|
+
var getByPath = (obj, path) => {
|
|
443
|
+
const [key, index] = path.split(".");
|
|
444
|
+
return index === void 0 ? obj[key] : obj[key][parseInt(index)];
|
|
445
|
+
};
|
|
446
|
+
var setByPath = (obj, path, value) => {
|
|
447
|
+
const [key, index] = path.split(".");
|
|
448
|
+
const newValue = index === void 0 ? value : [
|
|
449
|
+
...obj[key]
|
|
450
|
+
].map((v, i) => i === parseInt(index) ? value : v);
|
|
451
|
+
return {
|
|
452
|
+
...obj,
|
|
453
|
+
[key]: newValue
|
|
454
|
+
};
|
|
455
|
+
};
|
|
437
456
|
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/Form/Form.tsx";
|
|
438
457
|
var padding = "px-2";
|
|
439
|
-
var Form = ({ classNames, schema, values: initialValues, path = [], readonly, filter, sort, autoSave, onValuesChanged, onValidate,
|
|
440
|
-
const
|
|
441
|
-
const onValid = (0, import_react3.useMemo)(() => autoSave ? onSubmit : void 0, [
|
|
458
|
+
var Form = ({ classNames, schema, values: initialValues, path = [], readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, Custom }) => {
|
|
459
|
+
const onValid = (0, import_react3.useMemo)(() => autoSave ? onSave : void 0, [
|
|
442
460
|
autoSave,
|
|
443
|
-
|
|
461
|
+
onSave
|
|
444
462
|
]);
|
|
445
|
-
const {
|
|
463
|
+
const { canSave, values, errors, handleSave, ...inputProps } = useForm({
|
|
446
464
|
schema,
|
|
447
465
|
initialValues,
|
|
448
466
|
onValuesChanged,
|
|
449
467
|
onValidate,
|
|
450
468
|
onValid,
|
|
451
|
-
|
|
469
|
+
onSave
|
|
452
470
|
});
|
|
453
471
|
const properties = (0, import_react3.useMemo)(() => {
|
|
454
472
|
const props = (0, import_schema2.getSchemaProperties)(schema.ast, values);
|
|
@@ -469,7 +487,7 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
|
|
|
469
487
|
errors
|
|
470
488
|
}, {
|
|
471
489
|
F: __dxlog_file2,
|
|
472
|
-
L:
|
|
490
|
+
L: 100,
|
|
473
491
|
S: void 0,
|
|
474
492
|
C: (f, a) => f(...a)
|
|
475
493
|
});
|
|
@@ -479,14 +497,15 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
|
|
|
479
497
|
]);
|
|
480
498
|
return /* @__PURE__ */ import_react3.default.createElement("div", {
|
|
481
499
|
role: "form",
|
|
482
|
-
className: (0, import_react_ui_theme.mx)("flex flex-col w-full gap-2 py-2", classNames)
|
|
500
|
+
className: (0, import_react_ui_theme.mx)("flex flex-col w-full gap-2 py-2", classNames),
|
|
501
|
+
"data-testid": testId
|
|
483
502
|
}, properties.map((property) => {
|
|
484
|
-
const { ast, name, type, format, title, description, examples, options } = property;
|
|
503
|
+
const { ast, name, type, format, title, description, examples, options, array } = property;
|
|
485
504
|
const key = [
|
|
486
505
|
...path,
|
|
487
506
|
name
|
|
488
507
|
];
|
|
489
|
-
const label = (0, import_effect.pipe)(
|
|
508
|
+
const label = title ?? (0, import_effect.pipe)(name, import_String.capitalize);
|
|
490
509
|
const placeholder = examples?.length ? `Example: "${examples[0]}"` : description;
|
|
491
510
|
let InputComponent = Custom?.[key.join(".")];
|
|
492
511
|
if (!InputComponent) {
|
|
@@ -510,6 +529,22 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
|
|
|
510
529
|
}));
|
|
511
530
|
}
|
|
512
531
|
InputComponent = getInputComponent(type, format);
|
|
532
|
+
if (array) {
|
|
533
|
+
return /* @__PURE__ */ import_react3.default.createElement(ArrayField, {
|
|
534
|
+
key: name,
|
|
535
|
+
name,
|
|
536
|
+
type,
|
|
537
|
+
array: true,
|
|
538
|
+
label,
|
|
539
|
+
ast,
|
|
540
|
+
values,
|
|
541
|
+
format,
|
|
542
|
+
readonly,
|
|
543
|
+
placeholder,
|
|
544
|
+
inputProps,
|
|
545
|
+
Custom
|
|
546
|
+
});
|
|
547
|
+
}
|
|
513
548
|
}
|
|
514
549
|
if (!InputComponent) {
|
|
515
550
|
if (type === "object") {
|
|
@@ -538,7 +573,7 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
|
|
|
538
573
|
type
|
|
539
574
|
}, {
|
|
540
575
|
F: __dxlog_file2,
|
|
541
|
-
L:
|
|
576
|
+
L: 185,
|
|
542
577
|
S: void 0,
|
|
543
578
|
C: (f, a) => f(...a)
|
|
544
579
|
});
|
|
@@ -557,26 +592,161 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
|
|
|
557
592
|
placeholder,
|
|
558
593
|
...inputProps
|
|
559
594
|
}));
|
|
560
|
-
}).filter(import_util.isNotFalsy), (onCancel ||
|
|
595
|
+
}).filter(import_util.isNotFalsy), (onCancel || onSave) && !autoSave && /* @__PURE__ */ import_react3.default.createElement(FormActions, {
|
|
596
|
+
onCancel,
|
|
597
|
+
onSubmit: handleSave,
|
|
598
|
+
canSubmit: canSave,
|
|
599
|
+
readonly
|
|
600
|
+
}));
|
|
601
|
+
};
|
|
602
|
+
var ArrayField = ({ name, type, label, ast, values, format, readonly, placeholder, inputProps, Custom }) => {
|
|
603
|
+
const { t } = (0, import_react_ui3.useTranslation)(translationKey);
|
|
604
|
+
const arrayValues = values[name] ?? [];
|
|
605
|
+
const key = [
|
|
606
|
+
name
|
|
607
|
+
];
|
|
608
|
+
const tupleType = (0, import_effect2.findNode)(ast, import_echo_schema2.AST.isTupleType);
|
|
609
|
+
const elementType = tupleType?.rest[0]?.type;
|
|
610
|
+
if (type === "object" && elementType) {
|
|
611
|
+
const baseNode = (0, import_effect2.findNode)(elementType, import_effect2.isDiscriminatedUnion);
|
|
612
|
+
const typeLiteral = baseNode ? (0, import_effect2.getDiscriminatedType)(baseNode, values[name]) : (0, import_effect2.findNode)(elementType, import_echo_schema2.AST.isTypeLiteral);
|
|
613
|
+
if (typeLiteral) {
|
|
614
|
+
const schema = import_echo_schema2.S.make(typeLiteral);
|
|
615
|
+
return /* @__PURE__ */ import_react3.default.createElement("div", {
|
|
616
|
+
key: name,
|
|
617
|
+
role: "none",
|
|
618
|
+
className: (0, import_react_ui_theme.mx)(padding)
|
|
619
|
+
}, /* @__PURE__ */ import_react3.default.createElement(InputHeader, null, label), /* @__PURE__ */ import_react3.default.createElement("div", {
|
|
620
|
+
role: "none",
|
|
621
|
+
className: "flex flex-col gap-1"
|
|
622
|
+
}, arrayValues.map((value, index) => {
|
|
623
|
+
return /* @__PURE__ */ import_react3.default.createElement("div", {
|
|
624
|
+
key: index,
|
|
625
|
+
role: "none",
|
|
626
|
+
className: "flex items-center gap-1"
|
|
627
|
+
}, /* @__PURE__ */ import_react3.default.createElement("div", {
|
|
628
|
+
role: "none",
|
|
629
|
+
className: "flex-1"
|
|
630
|
+
}, /* @__PURE__ */ import_react3.default.createElement(Form, {
|
|
631
|
+
schema,
|
|
632
|
+
path: [
|
|
633
|
+
...key,
|
|
634
|
+
index.toString()
|
|
635
|
+
],
|
|
636
|
+
values: value,
|
|
637
|
+
onValuesChanged: (childValues) => {
|
|
638
|
+
const newValues = [
|
|
639
|
+
...arrayValues
|
|
640
|
+
];
|
|
641
|
+
newValues[index] = childValues;
|
|
642
|
+
inputProps.onValueChange(name, "object", newValues);
|
|
643
|
+
},
|
|
644
|
+
Custom
|
|
645
|
+
})), /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.IconButton, {
|
|
646
|
+
icon: "ph--trash--regular",
|
|
647
|
+
iconOnly: true,
|
|
648
|
+
label: t("button remove"),
|
|
649
|
+
onClick: () => {
|
|
650
|
+
const newValues = arrayValues.filter((_, i) => i !== index);
|
|
651
|
+
inputProps.onValueChange(name, type, newValues);
|
|
652
|
+
}
|
|
653
|
+
}));
|
|
654
|
+
})), /* @__PURE__ */ import_react3.default.createElement("div", {
|
|
655
|
+
role: "none",
|
|
656
|
+
className: "flex justify-between items-center plb-1"
|
|
657
|
+
}, /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.IconButton, {
|
|
658
|
+
icon: "ph--plus--regular",
|
|
659
|
+
iconOnly: true,
|
|
660
|
+
label: t("button add"),
|
|
661
|
+
onClick: () => {
|
|
662
|
+
const newValues = [
|
|
663
|
+
...arrayValues,
|
|
664
|
+
{}
|
|
665
|
+
];
|
|
666
|
+
inputProps.onValueChange(name, type, newValues);
|
|
667
|
+
}
|
|
668
|
+
})));
|
|
669
|
+
}
|
|
670
|
+
return /* @__PURE__ */ import_react3.default.createElement("div", {
|
|
671
|
+
key: name,
|
|
672
|
+
role: "none"
|
|
673
|
+
}, "Nested form not supported in arrays, yet.");
|
|
674
|
+
}
|
|
675
|
+
const InputComponent = getInputComponent(type, format);
|
|
676
|
+
if (!InputComponent) {
|
|
677
|
+
return null;
|
|
678
|
+
}
|
|
679
|
+
return /* @__PURE__ */ import_react3.default.createElement("div", {
|
|
680
|
+
role: "none",
|
|
681
|
+
key: "meta-input",
|
|
682
|
+
className: (0, import_react_ui_theme.mx)(padding)
|
|
683
|
+
}, /* @__PURE__ */ import_react3.default.createElement(InputHeader, null, label), /* @__PURE__ */ import_react3.default.createElement("div", {
|
|
684
|
+
role: "none",
|
|
685
|
+
className: "flex flex-col gap-1"
|
|
686
|
+
}, arrayValues.map((_, index) => /* @__PURE__ */ import_react3.default.createElement("div", {
|
|
687
|
+
key: index,
|
|
688
|
+
role: "none",
|
|
689
|
+
className: "flex items-start gap-1"
|
|
690
|
+
}, /* @__PURE__ */ import_react3.default.createElement("div", {
|
|
691
|
+
role: "none",
|
|
692
|
+
className: "flex-1"
|
|
693
|
+
}, /* @__PURE__ */ import_react3.default.createElement(InputComponent, {
|
|
694
|
+
type,
|
|
695
|
+
format,
|
|
696
|
+
label,
|
|
697
|
+
inputOnly: true,
|
|
698
|
+
property: `${name}.${index}`,
|
|
699
|
+
disabled: readonly,
|
|
700
|
+
placeholder,
|
|
701
|
+
...inputProps
|
|
702
|
+
})), /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.IconButton, {
|
|
703
|
+
icon: "ph--trash--regular",
|
|
704
|
+
iconOnly: true,
|
|
705
|
+
label: t("button remove"),
|
|
706
|
+
onClick: () => {
|
|
707
|
+
const newValues = arrayValues.filter((_2, i) => i !== index);
|
|
708
|
+
inputProps.onValueChange(name, type, newValues);
|
|
709
|
+
}
|
|
710
|
+
})))), /* @__PURE__ */ import_react3.default.createElement("div", {
|
|
711
|
+
role: "none",
|
|
712
|
+
className: "flex justify-between items-center plb-1"
|
|
713
|
+
}, /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.IconButton, {
|
|
714
|
+
icon: "ph--plus--regular",
|
|
715
|
+
iconOnly: true,
|
|
716
|
+
label: t("button add"),
|
|
717
|
+
onClick: () => {
|
|
718
|
+
const newValues = [
|
|
719
|
+
...arrayValues,
|
|
720
|
+
import_effect2.SimpleType.getDefaultValue(type)
|
|
721
|
+
];
|
|
722
|
+
inputProps.onValueChange(name, type, newValues);
|
|
723
|
+
}
|
|
724
|
+
})));
|
|
725
|
+
};
|
|
726
|
+
var FormActions = ({ onCancel, onSubmit, canSubmit, readonly }) => {
|
|
727
|
+
const { t } = (0, import_react_ui3.useTranslation)(translationKey);
|
|
728
|
+
return /* @__PURE__ */ import_react3.default.createElement("div", {
|
|
561
729
|
role: "none",
|
|
562
730
|
className: "flex justify-center"
|
|
563
731
|
}, /* @__PURE__ */ import_react3.default.createElement("div", {
|
|
564
732
|
role: "none",
|
|
565
733
|
className: (0, import_react_ui_theme.mx)(onCancel && !readonly && "grid grid-cols-2 gap-2")
|
|
566
734
|
}, onCancel && !readonly && /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.IconButton, {
|
|
735
|
+
"data-testid": "cancel-button",
|
|
567
736
|
icon: "ph--x--regular",
|
|
568
737
|
label: t("button cancel"),
|
|
569
738
|
onClick: onCancel
|
|
570
739
|
}), onSubmit && /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.IconButton, {
|
|
571
740
|
type: "submit",
|
|
741
|
+
"data-testid": "save-button",
|
|
572
742
|
disabled: !canSubmit,
|
|
573
743
|
icon: "ph--check--regular",
|
|
574
744
|
label: t("button save"),
|
|
575
|
-
onClick:
|
|
576
|
-
})))
|
|
745
|
+
onClick: onSubmit
|
|
746
|
+
})));
|
|
577
747
|
};
|
|
578
748
|
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
|
|
579
|
-
var FieldEditor = ({ view, projection, field, registry,
|
|
749
|
+
var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
580
750
|
const { t } = (0, import_react_ui2.useTranslation)(translationKey);
|
|
581
751
|
const [props, setProps] = (0, import_react2.useState)(projection.getFieldProjection(field.id).props);
|
|
582
752
|
(0, import_react2.useEffect)(() => setProps(projection.getFieldProjection(field.id).props), [
|
|
@@ -647,22 +817,22 @@ var FieldEditor = ({ view, projection, field, registry, onClose, onCancel }) =>
|
|
|
647
817
|
view.fields,
|
|
648
818
|
field
|
|
649
819
|
]);
|
|
650
|
-
const
|
|
820
|
+
const handleSave = (0, import_react2.useCallback)((props2) => {
|
|
651
821
|
projection.setFieldProjection({
|
|
652
822
|
field,
|
|
653
823
|
props: props2
|
|
654
824
|
});
|
|
655
|
-
|
|
825
|
+
onSave();
|
|
656
826
|
}, [
|
|
657
827
|
projection,
|
|
658
828
|
field,
|
|
659
|
-
|
|
829
|
+
onSave
|
|
660
830
|
]);
|
|
661
831
|
const handleCancel = (0, import_react2.useCallback)(() => {
|
|
662
832
|
requestAnimationFrame(() => onCancel?.());
|
|
663
|
-
|
|
833
|
+
onSave();
|
|
664
834
|
}, [
|
|
665
|
-
|
|
835
|
+
onSave
|
|
666
836
|
]);
|
|
667
837
|
if (!fieldSchema) {
|
|
668
838
|
import_log.log.warn("invalid format", {
|
|
@@ -687,7 +857,7 @@ var FieldEditor = ({ view, projection, field, registry, onClose, onCancel }) =>
|
|
|
687
857
|
],
|
|
688
858
|
onValuesChanged: handleValuesChanged,
|
|
689
859
|
onValidate: handleValidate,
|
|
690
|
-
|
|
860
|
+
onSave: handleSave,
|
|
691
861
|
onCancel: handleCancel,
|
|
692
862
|
Custom: {
|
|
693
863
|
["format"]: (props2) => /* @__PURE__ */ import_react2.default.createElement(SelectInput, {
|
|
@@ -717,7 +887,7 @@ var ViewMetaSchema = import_echo_schema4.S.Struct({
|
|
|
717
887
|
name: import_echo_schema4.S.String.annotations({
|
|
718
888
|
[import_echo_schema4.AST.TitleAnnotationId]: "View"
|
|
719
889
|
}),
|
|
720
|
-
|
|
890
|
+
typename: import_echo_schema4.Format.DXN.annotations({
|
|
721
891
|
[import_echo_schema4.AST.TitleAnnotationId]: "Typename"
|
|
722
892
|
})
|
|
723
893
|
}).pipe(import_echo_schema4.S.mutable);
|
|
@@ -733,16 +903,16 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
733
903
|
name: view.name,
|
|
734
904
|
// TODO(burdon): Need to warn user of possible consequences of editing.
|
|
735
905
|
// TODO(burdon): Settings should have domain name owned by user.
|
|
736
|
-
|
|
906
|
+
typename: view.query.type
|
|
737
907
|
};
|
|
738
908
|
}, [
|
|
739
909
|
view
|
|
740
910
|
]);
|
|
741
|
-
const handleViewUpdate = (0, import_react8.useCallback)(({ name,
|
|
911
|
+
const handleViewUpdate = (0, import_react8.useCallback)(({ name, typename }) => {
|
|
742
912
|
requestAnimationFrame(() => {
|
|
743
913
|
view.name = name;
|
|
744
|
-
view.query.type =
|
|
745
|
-
schema.updateTypename(
|
|
914
|
+
view.query.type = typename;
|
|
915
|
+
schema.updateTypename(typename);
|
|
746
916
|
});
|
|
747
917
|
}, [
|
|
748
918
|
view,
|
|
@@ -771,7 +941,7 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
771
941
|
autoSave: true,
|
|
772
942
|
schema: ViewMetaSchema,
|
|
773
943
|
values: viewValues,
|
|
774
|
-
|
|
944
|
+
onSave: handleViewUpdate
|
|
775
945
|
}), /* @__PURE__ */ import_react8.default.createElement("div", null, /* @__PURE__ */ import_react8.default.createElement("div", {
|
|
776
946
|
role: "none",
|
|
777
947
|
className: "p-2"
|
|
@@ -805,7 +975,7 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
805
975
|
projection,
|
|
806
976
|
field,
|
|
807
977
|
registry,
|
|
808
|
-
|
|
978
|
+
onSave: handleClose
|
|
809
979
|
}), !readonly && !field && /* @__PURE__ */ import_react8.default.createElement("div", {
|
|
810
980
|
className: "flex p-2 justify-center"
|
|
811
981
|
}, /* @__PURE__ */ import_react8.default.createElement(import_react_ui7.IconButton, {
|
|
@@ -1036,6 +1206,7 @@ var formatForEditing = ({ type, format, value, locale = void 0 }) => {
|
|
|
1036
1206
|
DeprecatedFormInput,
|
|
1037
1207
|
FieldEditor,
|
|
1038
1208
|
Form,
|
|
1209
|
+
FormActions,
|
|
1039
1210
|
GeiPointInput,
|
|
1040
1211
|
InputHeader,
|
|
1041
1212
|
NumberInput,
|