@dxos/react-ui-form 0.7.1-staging.8709ba7 → 0.7.2-staging.6d26b2a
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 +107 -81
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +100 -74
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +107 -81
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/Form/Custom.d.ts +2 -1
- package/dist/types/src/components/Form/Custom.d.ts.map +1 -1
- package/dist/types/src/components/Form/Defaults.d.ts +11 -4
- package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.d.ts +5 -4
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts +1 -4
- package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/Input.d.ts +3 -8
- package/dist/types/src/components/Form/Input.d.ts.map +1 -1
- package/dist/types/src/components/Form/factory.d.ts +2 -2
- package/dist/types/src/components/Form/factory.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
- package/dist/types/src/hooks/useForm.d.ts +5 -4
- package/dist/types/src/hooks/useForm.d.ts.map +1 -1
- package/package.json +22 -24
- package/src/components/Form/Custom.tsx +9 -9
- package/src/components/Form/Defaults.tsx +10 -5
- package/src/components/Form/Form.stories.tsx +2 -2
- package/src/components/Form/Form.tsx +43 -19
- package/src/components/Form/Input.tsx +3 -7
- package/src/components/Form/factory.tsx +4 -4
- package/src/components/ViewEditor/ViewEditor.stories.tsx +1 -2
- package/src/hooks/useForm.ts +7 -6
|
@@ -89,6 +89,8 @@ import { useTranslation as useTranslation3 } from "@dxos/react-ui";
|
|
|
89
89
|
import { getFormatSchema, getSchemaProperties as getSchemaProperties2, sortProperties } from "@dxos/schema";
|
|
90
90
|
|
|
91
91
|
// packages/ui/react-ui-form/src/components/Form/Form.tsx
|
|
92
|
+
import { pipe } from "effect";
|
|
93
|
+
import { capitalize } from "effect/String";
|
|
92
94
|
import React5, { useEffect as useEffect2, useMemo as useMemo2 } from "react";
|
|
93
95
|
import { AST, S } from "@dxos/echo-schema";
|
|
94
96
|
import { findNode, getDiscriminatedType, isDiscriminatedUnion } from "@dxos/effect";
|
|
@@ -98,12 +100,9 @@ import { mx } from "@dxos/react-ui-theme";
|
|
|
98
100
|
import { getSchemaProperties } from "@dxos/schema";
|
|
99
101
|
import { isNotFalsy } from "@dxos/util";
|
|
100
102
|
|
|
101
|
-
// packages/ui/react-ui-form/src/components/Form/
|
|
102
|
-
import { FormatEnum } from "@dxos/echo-schema";
|
|
103
|
-
|
|
104
|
-
// packages/ui/react-ui-form/src/components/Form/Custom.tsx
|
|
103
|
+
// packages/ui/react-ui-form/src/components/Form/Defaults.tsx
|
|
105
104
|
import React3 from "react";
|
|
106
|
-
import { Input as Input2,
|
|
105
|
+
import { Input as Input2, Select } from "@dxos/react-ui";
|
|
107
106
|
|
|
108
107
|
// packages/ui/react-ui-form/src/components/Form/Input.tsx
|
|
109
108
|
import React2 from "react";
|
|
@@ -124,57 +123,14 @@ var InputHeader = ({ children, error }) => {
|
|
|
124
123
|
}, /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null), error)));
|
|
125
124
|
};
|
|
126
125
|
|
|
127
|
-
// packages/ui/react-ui-form/src/components/Form/Custom.tsx
|
|
128
|
-
var LatLngInput = ({ property, type, label, disabled, getStatus, getValue, onValueChange, onBlur }) => {
|
|
129
|
-
const { t } = useTranslation(translationKey);
|
|
130
|
-
const { status, error } = getStatus?.(property);
|
|
131
|
-
const { lat = 0, lng = 0 } = getValue(property) ?? {};
|
|
132
|
-
return /* @__PURE__ */ React3.createElement(Input2.Root, {
|
|
133
|
-
validationValence: status
|
|
134
|
-
}, /* @__PURE__ */ React3.createElement(InputHeader, {
|
|
135
|
-
error
|
|
136
|
-
}, /* @__PURE__ */ React3.createElement(Input2.Label, null, label)), /* @__PURE__ */ React3.createElement("div", {
|
|
137
|
-
className: "grid grid-cols-2 gap-2"
|
|
138
|
-
}, /* @__PURE__ */ React3.createElement(Input2.TextInput, {
|
|
139
|
-
type: "number",
|
|
140
|
-
disabled,
|
|
141
|
-
placeholder: t("placeholder latitude"),
|
|
142
|
-
value: lat,
|
|
143
|
-
onChange: (event) => onValueChange(property, type, {
|
|
144
|
-
lat: safeParseFloat(event.target.value, 0),
|
|
145
|
-
lng
|
|
146
|
-
}),
|
|
147
|
-
onBlur
|
|
148
|
-
}), /* @__PURE__ */ React3.createElement(Input2.TextInput, {
|
|
149
|
-
type: "number",
|
|
150
|
-
disabled,
|
|
151
|
-
placeholder: t("placeholder longitude"),
|
|
152
|
-
value: lng,
|
|
153
|
-
onChange: (event) => onValueChange(property, type, {
|
|
154
|
-
lat,
|
|
155
|
-
lng: safeParseFloat(event.target.value, 0)
|
|
156
|
-
}),
|
|
157
|
-
onBlur
|
|
158
|
-
})));
|
|
159
|
-
};
|
|
160
|
-
var safeParseFloat = (str, defaultValue) => {
|
|
161
|
-
try {
|
|
162
|
-
return parseFloat(str);
|
|
163
|
-
} catch {
|
|
164
|
-
return defaultValue ?? 0;
|
|
165
|
-
}
|
|
166
|
-
};
|
|
167
|
-
|
|
168
126
|
// packages/ui/react-ui-form/src/components/Form/Defaults.tsx
|
|
169
|
-
import React4 from "react";
|
|
170
|
-
import { Input as Input3, Select } from "@dxos/react-ui";
|
|
171
127
|
var TextInput = ({ property, type, label, disabled, placeholder, getStatus, getValue, onValueChange, onBlur }) => {
|
|
172
128
|
const { status, error } = getStatus?.(property);
|
|
173
|
-
return /* @__PURE__ */
|
|
129
|
+
return /* @__PURE__ */ React3.createElement(Input2.Root, {
|
|
174
130
|
validationValence: status
|
|
175
|
-
}, /* @__PURE__ */
|
|
131
|
+
}, /* @__PURE__ */ React3.createElement(InputHeader, {
|
|
176
132
|
error
|
|
177
|
-
}, /* @__PURE__ */
|
|
133
|
+
}, /* @__PURE__ */ React3.createElement(Input2.Label, null, label)), /* @__PURE__ */ React3.createElement(Input2.TextInput, {
|
|
178
134
|
disabled,
|
|
179
135
|
placeholder,
|
|
180
136
|
value: getValue(property) ?? "",
|
|
@@ -184,11 +140,11 @@ var TextInput = ({ property, type, label, disabled, placeholder, getStatus, getV
|
|
|
184
140
|
};
|
|
185
141
|
var NumberInput = ({ property, type, label, disabled, placeholder, getStatus, getValue, onValueChange, onBlur }) => {
|
|
186
142
|
const { status, error } = getStatus?.(property);
|
|
187
|
-
return /* @__PURE__ */
|
|
143
|
+
return /* @__PURE__ */ React3.createElement(Input2.Root, {
|
|
188
144
|
validationValence: status
|
|
189
|
-
}, /* @__PURE__ */
|
|
145
|
+
}, /* @__PURE__ */ React3.createElement(InputHeader, {
|
|
190
146
|
error
|
|
191
|
-
}, /* @__PURE__ */
|
|
147
|
+
}, /* @__PURE__ */ React3.createElement(Input2.Label, null, label)), /* @__PURE__ */ React3.createElement(Input2.TextInput, {
|
|
192
148
|
type: "number",
|
|
193
149
|
disabled,
|
|
194
150
|
placeholder,
|
|
@@ -199,42 +155,88 @@ var NumberInput = ({ property, type, label, disabled, placeholder, getStatus, ge
|
|
|
199
155
|
};
|
|
200
156
|
var BooleanInput = ({ property, type, label, getStatus, getValue, onValueChange }) => {
|
|
201
157
|
const { status, error } = getStatus?.(property);
|
|
202
|
-
return /* @__PURE__ */
|
|
158
|
+
return /* @__PURE__ */ React3.createElement(Input2.Root, {
|
|
203
159
|
validationValence: status
|
|
204
|
-
}, /* @__PURE__ */
|
|
160
|
+
}, /* @__PURE__ */ React3.createElement(InputHeader, {
|
|
205
161
|
error
|
|
206
|
-
}, /* @__PURE__ */
|
|
162
|
+
}, /* @__PURE__ */ React3.createElement(Input2.Label, null, label)), /* @__PURE__ */ React3.createElement(Input2.Switch, {
|
|
207
163
|
checked: getValue(property),
|
|
208
164
|
onCheckedChange: (value) => onValueChange(property, type, value)
|
|
209
165
|
}));
|
|
210
166
|
};
|
|
211
167
|
var SelectInput = ({ property, type, label, disabled, placeholder, options, getStatus, getValue, onValueChange }) => {
|
|
212
168
|
const { status, error } = getStatus?.(property);
|
|
213
|
-
return /* @__PURE__ */
|
|
169
|
+
return /* @__PURE__ */ React3.createElement(Input2.Root, {
|
|
214
170
|
validationValence: status
|
|
215
|
-
}, /* @__PURE__ */
|
|
171
|
+
}, /* @__PURE__ */ React3.createElement(InputHeader, {
|
|
216
172
|
error
|
|
217
|
-
}, /* @__PURE__ */
|
|
173
|
+
}, /* @__PURE__ */ React3.createElement(Input2.Label, null, label)), /* @__PURE__ */ React3.createElement(Select.Root, {
|
|
218
174
|
value: getValue(property),
|
|
219
175
|
onValueChange: (value) => onValueChange(property, type, value)
|
|
220
|
-
}, /* @__PURE__ */
|
|
176
|
+
}, /* @__PURE__ */ React3.createElement(Select.TriggerButton, {
|
|
221
177
|
classNames: "is-full",
|
|
222
178
|
disabled,
|
|
223
179
|
placeholder
|
|
224
|
-
}), /* @__PURE__ */
|
|
180
|
+
}), /* @__PURE__ */ React3.createElement(Select.Portal, null, /* @__PURE__ */ React3.createElement(Select.Content, null, /* @__PURE__ */ React3.createElement(Select.Viewport, null, options?.map(({ value, label: label2 }) => (
|
|
225
181
|
// NOTE: Numeric values are converted to and from strings.
|
|
226
|
-
/* @__PURE__ */
|
|
182
|
+
/* @__PURE__ */ React3.createElement(Select.Option, {
|
|
227
183
|
key: String(value),
|
|
228
184
|
value: String(value)
|
|
229
185
|
}, label2 ?? String(value))
|
|
230
186
|
)))))));
|
|
231
187
|
};
|
|
232
188
|
|
|
189
|
+
// packages/ui/react-ui-form/src/components/Form/factory.tsx
|
|
190
|
+
import { FormatEnum } from "@dxos/echo-schema";
|
|
191
|
+
|
|
192
|
+
// packages/ui/react-ui-form/src/components/Form/Custom.tsx
|
|
193
|
+
import React4 from "react";
|
|
194
|
+
import { Input as Input3, useTranslation } from "@dxos/react-ui";
|
|
195
|
+
var GeiPointInput = ({ property, type, label, disabled, getStatus, getValue, onValueChange, onBlur }) => {
|
|
196
|
+
const { t } = useTranslation(translationKey);
|
|
197
|
+
const { status, error } = getStatus?.(property);
|
|
198
|
+
const [lng = 0, lat = 0] = getValue(property) ?? [];
|
|
199
|
+
return /* @__PURE__ */ React4.createElement(Input3.Root, {
|
|
200
|
+
validationValence: status
|
|
201
|
+
}, /* @__PURE__ */ React4.createElement(InputHeader, {
|
|
202
|
+
error
|
|
203
|
+
}, /* @__PURE__ */ React4.createElement(Input3.Label, null, label)), /* @__PURE__ */ React4.createElement("div", {
|
|
204
|
+
className: "grid grid-cols-2 gap-2"
|
|
205
|
+
}, /* @__PURE__ */ React4.createElement(Input3.TextInput, {
|
|
206
|
+
type: "number",
|
|
207
|
+
disabled,
|
|
208
|
+
placeholder: t("placeholder longitude"),
|
|
209
|
+
value: lng,
|
|
210
|
+
onChange: (event) => onValueChange(property, type, [
|
|
211
|
+
lat,
|
|
212
|
+
safeParseFloat(event.target.value, 0)
|
|
213
|
+
]),
|
|
214
|
+
onBlur
|
|
215
|
+
}), /* @__PURE__ */ React4.createElement(Input3.TextInput, {
|
|
216
|
+
type: "number",
|
|
217
|
+
disabled,
|
|
218
|
+
placeholder: t("placeholder latitude"),
|
|
219
|
+
value: lat,
|
|
220
|
+
onChange: (event) => onValueChange(property, type, [
|
|
221
|
+
safeParseFloat(event.target.value, 0),
|
|
222
|
+
lng
|
|
223
|
+
]),
|
|
224
|
+
onBlur
|
|
225
|
+
})));
|
|
226
|
+
};
|
|
227
|
+
var safeParseFloat = (str, defaultValue) => {
|
|
228
|
+
try {
|
|
229
|
+
return parseFloat(str);
|
|
230
|
+
} catch {
|
|
231
|
+
return defaultValue ?? 0;
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
|
|
233
235
|
// packages/ui/react-ui-form/src/components/Form/factory.tsx
|
|
234
236
|
var getInputComponent = (type, format) => {
|
|
235
237
|
switch (format) {
|
|
236
238
|
case FormatEnum.LatLng:
|
|
237
|
-
return
|
|
239
|
+
return GeiPointInput;
|
|
238
240
|
}
|
|
239
241
|
switch (type) {
|
|
240
242
|
case "string":
|
|
@@ -321,7 +323,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
321
323
|
} catch (err) {
|
|
322
324
|
log.catch(err, void 0, {
|
|
323
325
|
F: __dxlog_file,
|
|
324
|
-
L:
|
|
326
|
+
L: 165,
|
|
325
327
|
S: void 0,
|
|
326
328
|
C: (f, a) => f(...a)
|
|
327
329
|
});
|
|
@@ -376,7 +378,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
376
378
|
var createKeySet = (obj, value) => {
|
|
377
379
|
invariant(obj, void 0, {
|
|
378
380
|
F: __dxlog_file,
|
|
379
|
-
L:
|
|
381
|
+
L: 216,
|
|
380
382
|
S: void 0,
|
|
381
383
|
A: [
|
|
382
384
|
"obj",
|
|
@@ -414,11 +416,11 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
|
|
|
414
416
|
onValid,
|
|
415
417
|
onSubmit
|
|
416
418
|
});
|
|
417
|
-
const
|
|
418
|
-
const
|
|
419
|
-
const filtered = filter ? filter(
|
|
420
|
-
const findIndex = (
|
|
421
|
-
const idx =
|
|
419
|
+
const properties = useMemo2(() => {
|
|
420
|
+
const props = getSchemaProperties(schema.ast, values);
|
|
421
|
+
const filtered = filter ? filter(props) : props;
|
|
422
|
+
const findIndex = (props2, prop) => {
|
|
423
|
+
const idx = props2.findIndex((p) => p === prop);
|
|
422
424
|
return idx === -1 ? Infinity : idx;
|
|
423
425
|
};
|
|
424
426
|
return sort ? filtered.sort(({ name: a }, { name: b }) => findIndex(sort, a) - findIndex(sort, b)) : filtered;
|
|
@@ -433,7 +435,7 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
|
|
|
433
435
|
errors
|
|
434
436
|
}, {
|
|
435
437
|
F: __dxlog_file2,
|
|
436
|
-
L:
|
|
438
|
+
L: 96,
|
|
437
439
|
S: void 0,
|
|
438
440
|
C: (f, a) => f(...a)
|
|
439
441
|
});
|
|
@@ -444,16 +446,41 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
|
|
|
444
446
|
return /* @__PURE__ */ React5.createElement("div", {
|
|
445
447
|
role: "form",
|
|
446
448
|
className: mx("flex flex-col w-full gap-2 py-2", classNames)
|
|
447
|
-
},
|
|
449
|
+
}, properties.map((property) => {
|
|
450
|
+
const { ast, name, type, format, title, description, examples, options } = property;
|
|
448
451
|
const key = [
|
|
449
452
|
...path,
|
|
450
453
|
name
|
|
451
454
|
];
|
|
452
|
-
const
|
|
455
|
+
const label = pipe(title ?? name, capitalize);
|
|
456
|
+
const placeholder = examples?.length ? `Example: "${examples[0]}"` : description;
|
|
457
|
+
let InputComponent = Custom?.[key.join(".")];
|
|
458
|
+
if (!InputComponent) {
|
|
459
|
+
if (options) {
|
|
460
|
+
return /* @__PURE__ */ React5.createElement("div", {
|
|
461
|
+
key: name,
|
|
462
|
+
role: "none",
|
|
463
|
+
className: padding
|
|
464
|
+
}, /* @__PURE__ */ React5.createElement(SelectInput, {
|
|
465
|
+
type,
|
|
466
|
+
format,
|
|
467
|
+
property: name,
|
|
468
|
+
disabled: readonly,
|
|
469
|
+
label,
|
|
470
|
+
options: options.map((option) => ({
|
|
471
|
+
value: option,
|
|
472
|
+
label: String(option)
|
|
473
|
+
})),
|
|
474
|
+
placeholder,
|
|
475
|
+
...inputProps
|
|
476
|
+
}));
|
|
477
|
+
}
|
|
478
|
+
InputComponent = getInputComponent(type, format);
|
|
479
|
+
}
|
|
453
480
|
if (!InputComponent) {
|
|
454
481
|
if (type === "object") {
|
|
455
|
-
const baseNode = findNode(
|
|
456
|
-
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, values[name]) : findNode(
|
|
482
|
+
const baseNode = findNode(ast, isDiscriminatedUnion);
|
|
483
|
+
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, values[name]) : findNode(ast, AST.isTypeLiteral);
|
|
457
484
|
if (typeLiteral) {
|
|
458
485
|
const schema2 = S.make(typeLiteral);
|
|
459
486
|
return /* @__PURE__ */ React5.createElement("div", {
|
|
@@ -461,7 +488,7 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
|
|
|
461
488
|
role: "none"
|
|
462
489
|
}, /* @__PURE__ */ React5.createElement("div", {
|
|
463
490
|
className: padding
|
|
464
|
-
},
|
|
491
|
+
}, label), /* @__PURE__ */ React5.createElement(Form, {
|
|
465
492
|
schema: schema2,
|
|
466
493
|
path: key,
|
|
467
494
|
values: values[name] ?? {},
|
|
@@ -477,13 +504,12 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
|
|
|
477
504
|
type
|
|
478
505
|
}, {
|
|
479
506
|
F: __dxlog_file2,
|
|
480
|
-
L:
|
|
507
|
+
L: 160,
|
|
481
508
|
S: void 0,
|
|
482
509
|
C: (f, a) => f(...a)
|
|
483
510
|
});
|
|
484
511
|
return null;
|
|
485
512
|
}
|
|
486
|
-
const placeholder = examples?.length ? `Example: ${examples[0]}` : description;
|
|
487
513
|
return /* @__PURE__ */ React5.createElement("div", {
|
|
488
514
|
key: name,
|
|
489
515
|
role: "none",
|
|
@@ -493,7 +519,7 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
|
|
|
493
519
|
format,
|
|
494
520
|
property: name,
|
|
495
521
|
disabled: readonly,
|
|
496
|
-
label
|
|
522
|
+
label,
|
|
497
523
|
placeholder,
|
|
498
524
|
...inputProps
|
|
499
525
|
}));
|
|
@@ -992,8 +1018,8 @@ export {
|
|
|
992
1018
|
DeprecatedFormInput,
|
|
993
1019
|
FieldEditor,
|
|
994
1020
|
Form,
|
|
1021
|
+
GeiPointInput,
|
|
995
1022
|
InputHeader,
|
|
996
|
-
LatLngInput,
|
|
997
1023
|
NumberInput,
|
|
998
1024
|
SelectInput,
|
|
999
1025
|
TextInput,
|