@dxos/react-ui-form 0.7.2-main.f1adc9f → 0.7.2
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 +31 -31
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +31 -31
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +31 -31
- 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/Custom.d.ts +1 -1
- package/dist/types/src/components/Form/Custom.d.ts.map +1 -1
- package/dist/types/src/components/Form/Defaults.d.ts +5 -5
- package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.d.ts +4 -4
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Input.d.ts +2 -2
- package/dist/types/src/components/Form/Input.d.ts.map +1 -1
- package/dist/types/src/components/Form/factory.d.ts +1 -1
- package/dist/types/src/components/Form/factory.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
- package/dist/types/src/hooks/useForm.d.ts +6 -6
- package/dist/types/src/hooks/useForm.d.ts.map +1 -1
- package/package.json +22 -22
- package/src/components/FieldEditor/FieldEditor.stories.tsx +2 -2
- package/src/components/FieldEditor/FieldEditor.tsx +8 -8
- package/src/components/Form/Custom.tsx +1 -1
- package/src/components/Form/Defaults.tsx +5 -5
- package/src/components/Form/Form.stories.tsx +4 -4
- package/src/components/Form/Form.tsx +13 -13
- package/src/components/Form/Input.tsx +2 -2
- package/src/components/Form/factory.tsx +1 -1
- package/src/components/ViewEditor/ViewEditor.tsx +7 -8
- package/src/hooks/useForm.ts +16 -16
|
@@ -14,7 +14,7 @@ import { type FormHandler } from '../../hooks';
|
|
|
14
14
|
/**
|
|
15
15
|
* Props passed to input components.
|
|
16
16
|
*/
|
|
17
|
-
export type InputProps<T extends BaseObject
|
|
17
|
+
export type InputProps<T extends BaseObject> = {
|
|
18
18
|
property: PropertyKey<T>;
|
|
19
19
|
type: SimpleType;
|
|
20
20
|
format?: FormatEnum;
|
|
@@ -26,7 +26,7 @@ export type InputProps<T extends BaseObject<T>> = {
|
|
|
26
26
|
/**
|
|
27
27
|
* Form input component.
|
|
28
28
|
*/
|
|
29
|
-
export type InputComponent<T extends BaseObject
|
|
29
|
+
export type InputComponent<T extends BaseObject> = FC<InputProps<T>>;
|
|
30
30
|
|
|
31
31
|
export type InputHeaderProps = PropsWithChildren<{
|
|
32
32
|
error?: string;
|
|
@@ -12,7 +12,7 @@ import { type InputComponent } from './Input';
|
|
|
12
12
|
/**
|
|
13
13
|
* Get property input component.
|
|
14
14
|
*/
|
|
15
|
-
export const getInputComponent = <T extends BaseObject
|
|
15
|
+
export const getInputComponent = <T extends BaseObject>(
|
|
16
16
|
type: SimpleType,
|
|
17
17
|
format?: FormatEnum,
|
|
18
18
|
): InputComponent<T> | undefined => {
|
|
@@ -22,7 +22,7 @@ const ViewMetaSchema = S.Struct({
|
|
|
22
22
|
name: S.String.annotations({
|
|
23
23
|
[AST.TitleAnnotationId]: 'View',
|
|
24
24
|
}),
|
|
25
|
-
|
|
25
|
+
type: Format.DXN.annotations({
|
|
26
26
|
[AST.TitleAnnotationId]: 'Typename',
|
|
27
27
|
}),
|
|
28
28
|
}).pipe(S.mutable);
|
|
@@ -60,16 +60,16 @@ export const ViewEditor = ({
|
|
|
60
60
|
name: view.name,
|
|
61
61
|
// TODO(burdon): Need to warn user of possible consequences of editing.
|
|
62
62
|
// TODO(burdon): Settings should have domain name owned by user.
|
|
63
|
-
|
|
63
|
+
type: view.query.type,
|
|
64
64
|
};
|
|
65
65
|
}, [view]);
|
|
66
66
|
|
|
67
67
|
const handleViewUpdate = useCallback(
|
|
68
|
-
({ name,
|
|
68
|
+
({ name, type }: ViewMetaType) => {
|
|
69
69
|
requestAnimationFrame(() => {
|
|
70
70
|
view.name = name;
|
|
71
|
-
view.query.
|
|
72
|
-
schema.updateTypename(
|
|
71
|
+
view.query.type = type;
|
|
72
|
+
schema.updateTypename(type);
|
|
73
73
|
});
|
|
74
74
|
},
|
|
75
75
|
[view, schema],
|
|
@@ -95,7 +95,7 @@ export const ViewEditor = ({
|
|
|
95
95
|
|
|
96
96
|
return (
|
|
97
97
|
<div role='none' className={mx('flex flex-col w-full divide-y divide-separator', classNames)}>
|
|
98
|
-
<Form<ViewMetaType> autoFocus autoSave schema={ViewMetaSchema} values={viewValues}
|
|
98
|
+
<Form<ViewMetaType> autoFocus autoSave schema={ViewMetaSchema} values={viewValues} onSubmit={handleViewUpdate} />
|
|
99
99
|
|
|
100
100
|
<div>
|
|
101
101
|
{/* TODO(burdon): Clean up common form ux. */}
|
|
@@ -139,10 +139,9 @@ export const ViewEditor = ({
|
|
|
139
139
|
projection={projection}
|
|
140
140
|
field={field}
|
|
141
141
|
registry={registry}
|
|
142
|
-
|
|
142
|
+
onClose={handleClose}
|
|
143
143
|
/>
|
|
144
144
|
)}
|
|
145
|
-
|
|
146
145
|
{!readonly && !field && (
|
|
147
146
|
<div className='flex p-2 justify-center'>
|
|
148
147
|
<IconButton
|
package/src/hooks/useForm.ts
CHANGED
|
@@ -13,7 +13,7 @@ import { validateSchema, type ValidationError } from '@dxos/schema';
|
|
|
13
13
|
/**
|
|
14
14
|
* Return type from `useForm` hook.
|
|
15
15
|
*/
|
|
16
|
-
export type FormHandler<T extends BaseObject
|
|
16
|
+
export type FormHandler<T extends BaseObject> = {
|
|
17
17
|
//
|
|
18
18
|
// Form state management.
|
|
19
19
|
//
|
|
@@ -22,8 +22,8 @@ export type FormHandler<T extends BaseObject<T>> = {
|
|
|
22
22
|
errors: Record<PropertyKey<T>, string>;
|
|
23
23
|
touched: Record<PropertyKey<T>, boolean>;
|
|
24
24
|
changed: Record<PropertyKey<T>, boolean>;
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
canSubmit: boolean;
|
|
26
|
+
handleSubmit: () => void;
|
|
27
27
|
|
|
28
28
|
//
|
|
29
29
|
// Form input component helpers.
|
|
@@ -38,7 +38,7 @@ export type FormHandler<T extends BaseObject<T>> = {
|
|
|
38
38
|
/**
|
|
39
39
|
* Hook options.
|
|
40
40
|
*/
|
|
41
|
-
export interface FormOptions<T extends BaseObject
|
|
41
|
+
export interface FormOptions<T extends BaseObject> {
|
|
42
42
|
schema: S.Schema<T>;
|
|
43
43
|
|
|
44
44
|
// TODO(burdon): Are these reactive?
|
|
@@ -67,20 +67,20 @@ export interface FormOptions<T extends BaseObject<T>> {
|
|
|
67
67
|
/**
|
|
68
68
|
* Called when the form is submitted and passes validation.
|
|
69
69
|
*/
|
|
70
|
-
|
|
70
|
+
onSubmit?: (values: T, meta: { changed: FormHandler<T>['changed'] }) => void;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
/**
|
|
74
74
|
* Creates a hook for managing form state, including values, validation, and submission.
|
|
75
75
|
* Deeply integrated with `@dxos/schema` for schema-based validation.
|
|
76
76
|
*/
|
|
77
|
-
export const useForm = <T extends BaseObject
|
|
77
|
+
export const useForm = <T extends BaseObject>({
|
|
78
78
|
schema,
|
|
79
79
|
initialValues,
|
|
80
80
|
onValuesChanged,
|
|
81
81
|
onValidate,
|
|
82
82
|
onValid,
|
|
83
|
-
|
|
83
|
+
onSubmit,
|
|
84
84
|
}: FormOptions<T>): FormHandler<T> => {
|
|
85
85
|
const [values, setValues] = useState<T>(initialValues);
|
|
86
86
|
useEffect(() => {
|
|
@@ -123,7 +123,7 @@ export const useForm = <T extends BaseObject<T>>({
|
|
|
123
123
|
* NOTE: We can submit if there is no touched field that has an error.
|
|
124
124
|
* Basically, if there's a validation message visible in the form, submit should be disabled.
|
|
125
125
|
*/
|
|
126
|
-
const
|
|
126
|
+
const canSubmit = useMemo(
|
|
127
127
|
() =>
|
|
128
128
|
Object.keys(values).every(
|
|
129
129
|
(property) => touched[property as PropertyKey<T>] === false || !errors[property as PropertyKey<T>],
|
|
@@ -131,11 +131,11 @@ export const useForm = <T extends BaseObject<T>>({
|
|
|
131
131
|
[values, touched, errors],
|
|
132
132
|
);
|
|
133
133
|
|
|
134
|
-
const
|
|
134
|
+
const handleSubmit = useCallback(() => {
|
|
135
135
|
if (validate(values)) {
|
|
136
|
-
|
|
136
|
+
onSubmit?.(values, { changed });
|
|
137
137
|
}
|
|
138
|
-
}, [values, validate,
|
|
138
|
+
}, [values, validate, onSubmit]);
|
|
139
139
|
|
|
140
140
|
//
|
|
141
141
|
// Fields.
|
|
@@ -185,7 +185,7 @@ export const useForm = <T extends BaseObject<T>>({
|
|
|
185
185
|
|
|
186
186
|
// TODO(Zan): This should be configurable behavior.
|
|
187
187
|
if (event.relatedTarget?.getAttribute('type') === 'submit') {
|
|
188
|
-
// NOTE: We do this here instead of
|
|
188
|
+
// NOTE: We do this here instead of onSubmit because the blur event is triggered before the submit event
|
|
189
189
|
// and results in the submit button being disabled when the form is invalid.
|
|
190
190
|
setTouched(createKeySet(values, true));
|
|
191
191
|
}
|
|
@@ -201,8 +201,8 @@ export const useForm = <T extends BaseObject<T>>({
|
|
|
201
201
|
errors,
|
|
202
202
|
touched,
|
|
203
203
|
changed,
|
|
204
|
-
|
|
205
|
-
|
|
204
|
+
canSubmit,
|
|
205
|
+
handleSubmit,
|
|
206
206
|
|
|
207
207
|
// Field utils.
|
|
208
208
|
getStatus,
|
|
@@ -212,12 +212,12 @@ export const useForm = <T extends BaseObject<T>>({
|
|
|
212
212
|
} satisfies FormHandler<T>;
|
|
213
213
|
};
|
|
214
214
|
|
|
215
|
-
const createKeySet = <T extends BaseObject
|
|
215
|
+
const createKeySet = <T extends BaseObject, V>(obj: T, value: V): Record<PropertyKey<T>, V> => {
|
|
216
216
|
invariant(obj);
|
|
217
217
|
return Object.keys(obj).reduce((acc, key) => ({ ...acc, [key]: value }), {} as Record<PropertyKey<T>, V>);
|
|
218
218
|
};
|
|
219
219
|
|
|
220
|
-
const flatMap = <T extends BaseObject
|
|
220
|
+
const flatMap = <T extends BaseObject>(errors: ValidationError[]) => {
|
|
221
221
|
return errors.reduce(
|
|
222
222
|
(result, { path, message }) => {
|
|
223
223
|
if (!(path in result)) {
|