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