@conform-to/react 1.0.6 → 1.1.0
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/README +1 -1
- package/context.d.ts +5 -4
- package/context.js +53 -30
- package/context.mjs +54 -31
- package/helpers.d.ts +3 -3
- package/helpers.js +1 -1
- package/helpers.mjs +1 -1
- package/hooks.d.ts +1 -1
- package/hooks.js +9 -7
- package/hooks.mjs +9 -7
- package/package.json +2 -2
package/README
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
╚══════╝ ╚═════╝ ╚═╝ ╚══╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
Version 1.0
|
|
11
|
+
Version 1.1.0 / License MIT / Copyright (c) 2024 Edmund Hung
|
|
12
12
|
|
|
13
13
|
A type-safe form validation library utilizing web fundamentals to progressively enhance HTML Forms with full support for server frameworks like Remix and Next.js.
|
|
14
14
|
|
package/context.d.ts
CHANGED
|
@@ -53,10 +53,11 @@ export declare function FormStateInput(props: {
|
|
|
53
53
|
formId?: string;
|
|
54
54
|
}): React.ReactElement;
|
|
55
55
|
export declare function useSubjectRef(initialSubject?: SubscriptionSubject): MutableRefObject<SubscriptionSubject>;
|
|
56
|
-
export declare function updateSubjectRef(ref: MutableRefObject<SubscriptionSubject>,
|
|
57
|
-
export declare function
|
|
58
|
-
export declare function
|
|
59
|
-
export declare function
|
|
56
|
+
export declare function updateSubjectRef(ref: MutableRefObject<SubscriptionSubject>, subject: 'status' | 'formId'): void;
|
|
57
|
+
export declare function updateSubjectRef(ref: MutableRefObject<SubscriptionSubject>, subject: Exclude<keyof SubscriptionSubject, 'status' | 'formId'>, scope: keyof SubscriptionScope, name: string): void;
|
|
58
|
+
export declare function getMetadata<Schema, FormError, FormSchema extends Record<string, any>>(context: FormContext<FormSchema, FormError, any>, subjectRef: MutableRefObject<SubscriptionSubject>, stateSnapshot: FormState<FormError>, name?: FieldName<Schema, FormSchema, FormError>): Metadata<Schema, FormSchema, FormError>;
|
|
59
|
+
export declare function getFieldMetadata<Schema, FormSchema extends Record<string, any>, FormError>(context: FormContext<FormSchema, FormError, any>, subjectRef: MutableRefObject<SubscriptionSubject>, stateSnapshot: FormState<FormError>, prefix?: string, key?: string | number): FieldMetadata<Schema, FormSchema, FormError>;
|
|
60
|
+
export declare function getFormMetadata<Schema extends Record<string, any>, FormError = string[], FormValue = Schema>(context: FormContext<Schema, FormError, FormValue>, subjectRef: MutableRefObject<SubscriptionSubject>, stateSnapshot: FormState<FormError>, noValidate: boolean): FormMetadata<Schema, FormError>;
|
|
60
61
|
export type FormOptions<Schema extends Record<string, any> = any, FormError = string[], FormValue = Schema> = BaseFormOptions<Schema, FormError, FormValue> & {
|
|
61
62
|
/**
|
|
62
63
|
* A function to be called before the form is submitted.
|
package/context.js
CHANGED
|
@@ -17,7 +17,7 @@ function getWrappedFormContext(context) {
|
|
|
17
17
|
}
|
|
18
18
|
function useFormContext(formId) {
|
|
19
19
|
var contexts = react.useContext(Form);
|
|
20
|
-
var form = formId ? contexts.find(context =>
|
|
20
|
+
var form = formId ? contexts.find(context => formId === context.getFormId()) : contexts[0];
|
|
21
21
|
if (!form) {
|
|
22
22
|
throw new Error('Form context is not available');
|
|
23
23
|
}
|
|
@@ -56,19 +56,20 @@ function useSubjectRef() {
|
|
|
56
56
|
subjectRef.current = initialSubject;
|
|
57
57
|
return subjectRef;
|
|
58
58
|
}
|
|
59
|
-
function updateSubjectRef(ref,
|
|
60
|
-
if (subject === 'status') {
|
|
59
|
+
function updateSubjectRef(ref, subject, scope, name) {
|
|
60
|
+
if (subject === 'status' || subject === 'formId') {
|
|
61
61
|
ref.current[subject] = true;
|
|
62
|
-
} else {
|
|
62
|
+
} else if (typeof scope !== 'undefined' && typeof name !== 'undefined') {
|
|
63
63
|
var _ref$current$subject$, _ref$current$subject;
|
|
64
64
|
ref.current[subject] = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, ref.current[subject]), {}, {
|
|
65
65
|
[scope]: ((_ref$current$subject$ = (_ref$current$subject = ref.current[subject]) === null || _ref$current$subject === void 0 ? void 0 : _ref$current$subject[scope]) !== null && _ref$current$subject$ !== void 0 ? _ref$current$subject$ : []).concat(name)
|
|
66
66
|
});
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
|
-
function getMetadata(
|
|
69
|
+
function getMetadata(context, subjectRef, stateSnapshot) {
|
|
70
70
|
var name = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '';
|
|
71
|
-
var id = name ? "".concat(
|
|
71
|
+
var id = name ? "".concat(context.getFormId(), "-").concat(name) : context.getFormId();
|
|
72
|
+
var state = context.getState();
|
|
72
73
|
return new Proxy({
|
|
73
74
|
id,
|
|
74
75
|
name,
|
|
@@ -108,7 +109,7 @@ function getMetadata(formId, state, subjectRef) {
|
|
|
108
109
|
return () => new Proxy({}, {
|
|
109
110
|
get(target, key, receiver) {
|
|
110
111
|
if (typeof key === 'string') {
|
|
111
|
-
return getFieldMetadata(
|
|
112
|
+
return getFieldMetadata(context, subjectRef, stateSnapshot, name, key);
|
|
112
113
|
}
|
|
113
114
|
return Reflect.get(target, key, receiver);
|
|
114
115
|
}
|
|
@@ -116,34 +117,48 @@ function getMetadata(formId, state, subjectRef) {
|
|
|
116
117
|
}
|
|
117
118
|
}, {
|
|
118
119
|
get(target, key, receiver) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
120
|
+
// We want to minize re-render by identifying whether the field is used in a callback only
|
|
121
|
+
// but there is no clear way to know if it is accessed during render or not
|
|
122
|
+
// if the stateSnapshot is not the latest, then it must be accessed in a callback
|
|
123
|
+
if (state === stateSnapshot) {
|
|
124
|
+
switch (key) {
|
|
125
|
+
case 'id':
|
|
126
|
+
case 'errorId':
|
|
127
|
+
case 'descriptionId':
|
|
128
|
+
updateSubjectRef(subjectRef, 'formId');
|
|
129
|
+
break;
|
|
130
|
+
case 'key':
|
|
131
|
+
case 'initialValue':
|
|
132
|
+
case 'value':
|
|
133
|
+
case 'valid':
|
|
134
|
+
case 'dirty':
|
|
135
|
+
updateSubjectRef(subjectRef, key, 'name', name);
|
|
136
|
+
break;
|
|
137
|
+
case 'errors':
|
|
138
|
+
case 'allErrors':
|
|
139
|
+
updateSubjectRef(subjectRef, 'error', key === 'errors' ? 'name' : 'prefix', name);
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
131
142
|
}
|
|
132
143
|
return Reflect.get(target, key, receiver);
|
|
133
144
|
}
|
|
134
145
|
});
|
|
135
146
|
}
|
|
136
|
-
function getFieldMetadata(
|
|
147
|
+
function getFieldMetadata(context, subjectRef, stateSnapshot) {
|
|
137
148
|
var prefix = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '';
|
|
138
149
|
var key = arguments.length > 4 ? arguments[4] : undefined;
|
|
139
150
|
var name = typeof key === 'undefined' ? prefix : dom.formatPaths([...dom.getPaths(prefix), key]);
|
|
140
|
-
var metadata = getMetadata(formId, state, subjectRef, name);
|
|
141
151
|
return new Proxy({}, {
|
|
142
152
|
get(_, key, receiver) {
|
|
143
153
|
var _state$constraint$nam;
|
|
154
|
+
var metadata = getMetadata(context, subjectRef, stateSnapshot, name);
|
|
155
|
+
var state = context.getState();
|
|
144
156
|
switch (key) {
|
|
145
157
|
case 'formId':
|
|
146
|
-
|
|
158
|
+
if (state === stateSnapshot) {
|
|
159
|
+
updateSubjectRef(subjectRef, 'formId');
|
|
160
|
+
}
|
|
161
|
+
return context.getFormId();
|
|
147
162
|
case 'required':
|
|
148
163
|
case 'minLength':
|
|
149
164
|
case 'maxLength':
|
|
@@ -158,11 +173,13 @@ function getFieldMetadata(formId, state, subjectRef) {
|
|
|
158
173
|
return () => {
|
|
159
174
|
var _state$initialValue$n;
|
|
160
175
|
var initialValue = (_state$initialValue$n = state.initialValue[name]) !== null && _state$initialValue$n !== void 0 ? _state$initialValue$n : [];
|
|
161
|
-
|
|
176
|
+
if (state === stateSnapshot) {
|
|
177
|
+
updateSubjectRef(subjectRef, 'initialValue', 'name', name);
|
|
178
|
+
}
|
|
162
179
|
if (!Array.isArray(initialValue)) {
|
|
163
180
|
throw new Error('The initial value at the given name is not a list');
|
|
164
181
|
}
|
|
165
|
-
return Array(initialValue.length).fill(0).map((_, index) => getFieldMetadata(
|
|
182
|
+
return Array(initialValue.length).fill(0).map((_, index) => getFieldMetadata(context, subjectRef, stateSnapshot, name, index));
|
|
166
183
|
};
|
|
167
184
|
}
|
|
168
185
|
}
|
|
@@ -170,16 +187,20 @@ function getFieldMetadata(formId, state, subjectRef) {
|
|
|
170
187
|
}
|
|
171
188
|
});
|
|
172
189
|
}
|
|
173
|
-
function getFormMetadata(
|
|
174
|
-
var metadata = getMetadata(formId, state, subjectRef);
|
|
190
|
+
function getFormMetadata(context, subjectRef, stateSnapshot, noValidate) {
|
|
175
191
|
return new Proxy({}, {
|
|
176
192
|
get(_, key, receiver) {
|
|
193
|
+
var metadata = getMetadata(context, subjectRef, stateSnapshot);
|
|
194
|
+
var state = context.getState();
|
|
177
195
|
switch (key) {
|
|
178
196
|
case 'context':
|
|
179
197
|
return {
|
|
180
198
|
[wrappedSymbol]: context
|
|
181
199
|
};
|
|
182
200
|
case 'status':
|
|
201
|
+
if (state === stateSnapshot) {
|
|
202
|
+
updateSubjectRef(subjectRef, 'status');
|
|
203
|
+
}
|
|
183
204
|
return state.submissionStatus;
|
|
184
205
|
case 'validate':
|
|
185
206
|
case 'update':
|
|
@@ -207,11 +228,13 @@ function createFormContext(options) {
|
|
|
207
228
|
submit(event) {
|
|
208
229
|
var submitEvent = event.nativeEvent;
|
|
209
230
|
var result = context.submit(submitEvent);
|
|
210
|
-
if (result.submission
|
|
211
|
-
|
|
231
|
+
if (!result.submission || result.submission.status === 'success' || result.submission.error === null) {
|
|
232
|
+
if (!result.formData.has(dom.INTENT)) {
|
|
233
|
+
var _onSubmit;
|
|
234
|
+
(_onSubmit = onSubmit) === null || _onSubmit === void 0 || _onSubmit(event, result);
|
|
235
|
+
}
|
|
212
236
|
} else {
|
|
213
|
-
|
|
214
|
-
(_onSubmit = onSubmit) === null || _onSubmit === void 0 || _onSubmit(event, result);
|
|
237
|
+
event.preventDefault();
|
|
215
238
|
}
|
|
216
239
|
},
|
|
217
240
|
onUpdate(options) {
|
package/context.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { objectWithoutProperties as _objectWithoutProperties, objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.mjs';
|
|
2
|
-
import { STATE, formatPaths, getPaths, unstable_createFormContext, isPrefix } from '@conform-to/dom';
|
|
2
|
+
import { STATE, formatPaths, getPaths, unstable_createFormContext, INTENT, isPrefix } from '@conform-to/dom';
|
|
3
3
|
import { useContext, useMemo, createContext, useCallback, useSyncExternalStore, useRef } from 'react';
|
|
4
4
|
import { jsx } from 'react/jsx-runtime';
|
|
5
5
|
|
|
@@ -13,7 +13,7 @@ function getWrappedFormContext(context) {
|
|
|
13
13
|
}
|
|
14
14
|
function useFormContext(formId) {
|
|
15
15
|
var contexts = useContext(Form);
|
|
16
|
-
var form = formId ? contexts.find(context =>
|
|
16
|
+
var form = formId ? contexts.find(context => formId === context.getFormId()) : contexts[0];
|
|
17
17
|
if (!form) {
|
|
18
18
|
throw new Error('Form context is not available');
|
|
19
19
|
}
|
|
@@ -52,19 +52,20 @@ function useSubjectRef() {
|
|
|
52
52
|
subjectRef.current = initialSubject;
|
|
53
53
|
return subjectRef;
|
|
54
54
|
}
|
|
55
|
-
function updateSubjectRef(ref,
|
|
56
|
-
if (subject === 'status') {
|
|
55
|
+
function updateSubjectRef(ref, subject, scope, name) {
|
|
56
|
+
if (subject === 'status' || subject === 'formId') {
|
|
57
57
|
ref.current[subject] = true;
|
|
58
|
-
} else {
|
|
58
|
+
} else if (typeof scope !== 'undefined' && typeof name !== 'undefined') {
|
|
59
59
|
var _ref$current$subject$, _ref$current$subject;
|
|
60
60
|
ref.current[subject] = _objectSpread2(_objectSpread2({}, ref.current[subject]), {}, {
|
|
61
61
|
[scope]: ((_ref$current$subject$ = (_ref$current$subject = ref.current[subject]) === null || _ref$current$subject === void 0 ? void 0 : _ref$current$subject[scope]) !== null && _ref$current$subject$ !== void 0 ? _ref$current$subject$ : []).concat(name)
|
|
62
62
|
});
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
|
-
function getMetadata(
|
|
65
|
+
function getMetadata(context, subjectRef, stateSnapshot) {
|
|
66
66
|
var name = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '';
|
|
67
|
-
var id = name ? "".concat(
|
|
67
|
+
var id = name ? "".concat(context.getFormId(), "-").concat(name) : context.getFormId();
|
|
68
|
+
var state = context.getState();
|
|
68
69
|
return new Proxy({
|
|
69
70
|
id,
|
|
70
71
|
name,
|
|
@@ -104,7 +105,7 @@ function getMetadata(formId, state, subjectRef) {
|
|
|
104
105
|
return () => new Proxy({}, {
|
|
105
106
|
get(target, key, receiver) {
|
|
106
107
|
if (typeof key === 'string') {
|
|
107
|
-
return getFieldMetadata(
|
|
108
|
+
return getFieldMetadata(context, subjectRef, stateSnapshot, name, key);
|
|
108
109
|
}
|
|
109
110
|
return Reflect.get(target, key, receiver);
|
|
110
111
|
}
|
|
@@ -112,34 +113,48 @@ function getMetadata(formId, state, subjectRef) {
|
|
|
112
113
|
}
|
|
113
114
|
}, {
|
|
114
115
|
get(target, key, receiver) {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
116
|
+
// We want to minize re-render by identifying whether the field is used in a callback only
|
|
117
|
+
// but there is no clear way to know if it is accessed during render or not
|
|
118
|
+
// if the stateSnapshot is not the latest, then it must be accessed in a callback
|
|
119
|
+
if (state === stateSnapshot) {
|
|
120
|
+
switch (key) {
|
|
121
|
+
case 'id':
|
|
122
|
+
case 'errorId':
|
|
123
|
+
case 'descriptionId':
|
|
124
|
+
updateSubjectRef(subjectRef, 'formId');
|
|
125
|
+
break;
|
|
126
|
+
case 'key':
|
|
127
|
+
case 'initialValue':
|
|
128
|
+
case 'value':
|
|
129
|
+
case 'valid':
|
|
130
|
+
case 'dirty':
|
|
131
|
+
updateSubjectRef(subjectRef, key, 'name', name);
|
|
132
|
+
break;
|
|
133
|
+
case 'errors':
|
|
134
|
+
case 'allErrors':
|
|
135
|
+
updateSubjectRef(subjectRef, 'error', key === 'errors' ? 'name' : 'prefix', name);
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
127
138
|
}
|
|
128
139
|
return Reflect.get(target, key, receiver);
|
|
129
140
|
}
|
|
130
141
|
});
|
|
131
142
|
}
|
|
132
|
-
function getFieldMetadata(
|
|
143
|
+
function getFieldMetadata(context, subjectRef, stateSnapshot) {
|
|
133
144
|
var prefix = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '';
|
|
134
145
|
var key = arguments.length > 4 ? arguments[4] : undefined;
|
|
135
146
|
var name = typeof key === 'undefined' ? prefix : formatPaths([...getPaths(prefix), key]);
|
|
136
|
-
var metadata = getMetadata(formId, state, subjectRef, name);
|
|
137
147
|
return new Proxy({}, {
|
|
138
148
|
get(_, key, receiver) {
|
|
139
149
|
var _state$constraint$nam;
|
|
150
|
+
var metadata = getMetadata(context, subjectRef, stateSnapshot, name);
|
|
151
|
+
var state = context.getState();
|
|
140
152
|
switch (key) {
|
|
141
153
|
case 'formId':
|
|
142
|
-
|
|
154
|
+
if (state === stateSnapshot) {
|
|
155
|
+
updateSubjectRef(subjectRef, 'formId');
|
|
156
|
+
}
|
|
157
|
+
return context.getFormId();
|
|
143
158
|
case 'required':
|
|
144
159
|
case 'minLength':
|
|
145
160
|
case 'maxLength':
|
|
@@ -154,11 +169,13 @@ function getFieldMetadata(formId, state, subjectRef) {
|
|
|
154
169
|
return () => {
|
|
155
170
|
var _state$initialValue$n;
|
|
156
171
|
var initialValue = (_state$initialValue$n = state.initialValue[name]) !== null && _state$initialValue$n !== void 0 ? _state$initialValue$n : [];
|
|
157
|
-
|
|
172
|
+
if (state === stateSnapshot) {
|
|
173
|
+
updateSubjectRef(subjectRef, 'initialValue', 'name', name);
|
|
174
|
+
}
|
|
158
175
|
if (!Array.isArray(initialValue)) {
|
|
159
176
|
throw new Error('The initial value at the given name is not a list');
|
|
160
177
|
}
|
|
161
|
-
return Array(initialValue.length).fill(0).map((_, index) => getFieldMetadata(
|
|
178
|
+
return Array(initialValue.length).fill(0).map((_, index) => getFieldMetadata(context, subjectRef, stateSnapshot, name, index));
|
|
162
179
|
};
|
|
163
180
|
}
|
|
164
181
|
}
|
|
@@ -166,16 +183,20 @@ function getFieldMetadata(formId, state, subjectRef) {
|
|
|
166
183
|
}
|
|
167
184
|
});
|
|
168
185
|
}
|
|
169
|
-
function getFormMetadata(
|
|
170
|
-
var metadata = getMetadata(formId, state, subjectRef);
|
|
186
|
+
function getFormMetadata(context, subjectRef, stateSnapshot, noValidate) {
|
|
171
187
|
return new Proxy({}, {
|
|
172
188
|
get(_, key, receiver) {
|
|
189
|
+
var metadata = getMetadata(context, subjectRef, stateSnapshot);
|
|
190
|
+
var state = context.getState();
|
|
173
191
|
switch (key) {
|
|
174
192
|
case 'context':
|
|
175
193
|
return {
|
|
176
194
|
[wrappedSymbol]: context
|
|
177
195
|
};
|
|
178
196
|
case 'status':
|
|
197
|
+
if (state === stateSnapshot) {
|
|
198
|
+
updateSubjectRef(subjectRef, 'status');
|
|
199
|
+
}
|
|
179
200
|
return state.submissionStatus;
|
|
180
201
|
case 'validate':
|
|
181
202
|
case 'update':
|
|
@@ -203,11 +224,13 @@ function createFormContext(options) {
|
|
|
203
224
|
submit(event) {
|
|
204
225
|
var submitEvent = event.nativeEvent;
|
|
205
226
|
var result = context.submit(submitEvent);
|
|
206
|
-
if (result.submission
|
|
207
|
-
|
|
227
|
+
if (!result.submission || result.submission.status === 'success' || result.submission.error === null) {
|
|
228
|
+
if (!result.formData.has(INTENT)) {
|
|
229
|
+
var _onSubmit;
|
|
230
|
+
(_onSubmit = onSubmit) === null || _onSubmit === void 0 || _onSubmit(event, result);
|
|
231
|
+
}
|
|
208
232
|
} else {
|
|
209
|
-
|
|
210
|
-
(_onSubmit = onSubmit) === null || _onSubmit === void 0 || _onSubmit(event, result);
|
|
233
|
+
event.preventDefault();
|
|
211
234
|
}
|
|
212
235
|
},
|
|
213
236
|
onUpdate(options) {
|
package/helpers.d.ts
CHANGED
|
@@ -175,7 +175,7 @@ export declare function getTextareaProps<Schema>(metadata: FieldMetadata<Schema,
|
|
|
175
175
|
* Derives the properties of a collection of checkboxes or radio buttons based on the field metadata,
|
|
176
176
|
* including common form control attributes like `key`, `id`, `name`, `form`, `autoFocus`, `aria-invalid`, `aria-describedby` and `required`.
|
|
177
177
|
*
|
|
178
|
-
* @see https://conform.guide/api/react/
|
|
178
|
+
* @see https://conform.guide/api/react/getCollectionProps
|
|
179
179
|
* @example
|
|
180
180
|
* ```tsx
|
|
181
181
|
* <fieldset>
|
|
@@ -191,7 +191,7 @@ export declare function getTextareaProps<Schema>(metadata: FieldMetadata<Schema,
|
|
|
191
191
|
* </fieldset>
|
|
192
192
|
* ```
|
|
193
193
|
*/
|
|
194
|
-
export declare function getCollectionProps<Schema extends Array<string | boolean> | string | boolean | undefined | unknown
|
|
194
|
+
export declare function getCollectionProps<Schema extends Array<string | boolean> | string | boolean | undefined | unknown, Options extends Pretty<FormControlOptions & {
|
|
195
195
|
/**
|
|
196
196
|
* The input type. Use `checkbox` for multiple selection or `radio` for single selection.
|
|
197
197
|
*/
|
|
@@ -204,5 +204,5 @@ export declare function getCollectionProps<Schema extends Array<string | boolean
|
|
|
204
204
|
* Decide whether defaultValue should be returned. Pass `false` if you want to manage the value yourself.
|
|
205
205
|
*/
|
|
206
206
|
value?: boolean;
|
|
207
|
-
}
|
|
207
|
+
}>>(metadata: FieldMetadata<Schema, any, any>, options: Options): Array<InputProps & Pick<Options, 'type'> & Pick<Required<InputProps>, 'value'>>;
|
|
208
208
|
export {};
|
package/helpers.js
CHANGED
|
@@ -179,7 +179,7 @@ function getTextareaProps(metadata) {
|
|
|
179
179
|
* Derives the properties of a collection of checkboxes or radio buttons based on the field metadata,
|
|
180
180
|
* including common form control attributes like `key`, `id`, `name`, `form`, `autoFocus`, `aria-invalid`, `aria-describedby` and `required`.
|
|
181
181
|
*
|
|
182
|
-
* @see https://conform.guide/api/react/
|
|
182
|
+
* @see https://conform.guide/api/react/getCollectionProps
|
|
183
183
|
* @example
|
|
184
184
|
* ```tsx
|
|
185
185
|
* <fieldset>
|
package/helpers.mjs
CHANGED
|
@@ -175,7 +175,7 @@ function getTextareaProps(metadata) {
|
|
|
175
175
|
* Derives the properties of a collection of checkboxes or radio buttons based on the field metadata,
|
|
176
176
|
* including common form control attributes like `key`, `id`, `name`, `form`, `autoFocus`, `aria-invalid`, `aria-describedby` and `required`.
|
|
177
177
|
*
|
|
178
|
-
* @see https://conform.guide/api/react/
|
|
178
|
+
* @see https://conform.guide/api/react/getCollectionProps
|
|
179
179
|
* @example
|
|
180
180
|
* ```tsx
|
|
181
181
|
* <fieldset>
|
package/hooks.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ export declare function useForm<Schema extends Record<string, any>, FormValue =
|
|
|
23
23
|
FormMetadata<Schema, FormError>,
|
|
24
24
|
ReturnType<FormMetadata<Schema, FormError>['getFieldset']>
|
|
25
25
|
];
|
|
26
|
-
export declare function useFormMetadata<Schema extends Record<string, any>, FormError = string[]>(formId
|
|
26
|
+
export declare function useFormMetadata<Schema extends Record<string, any>, FormError = string[]>(formId?: FormId<Schema, FormError>, options?: {
|
|
27
27
|
defaultNoValidate?: boolean;
|
|
28
28
|
}): FormMetadata<Schema, FormError>;
|
|
29
29
|
export declare function useField<FieldSchema, FormSchema extends Record<string, unknown> = Record<string, unknown>, FormError = string[]>(name: FieldName<FieldSchema, FormSchema, FormError>, options?: {
|
package/hooks.js
CHANGED
|
@@ -40,10 +40,12 @@ function useForm(options) {
|
|
|
40
40
|
formId
|
|
41
41
|
})));
|
|
42
42
|
useSafeLayoutEffect(() => {
|
|
43
|
+
var disconnect = context$1.observe();
|
|
43
44
|
document.addEventListener('input', context$1.onInput);
|
|
44
45
|
document.addEventListener('focusout', context$1.onBlur);
|
|
45
46
|
document.addEventListener('reset', context$1.onReset);
|
|
46
47
|
return () => {
|
|
48
|
+
disconnect();
|
|
47
49
|
document.removeEventListener('input', context$1.onInput);
|
|
48
50
|
document.removeEventListener('focusout', context$1.onBlur);
|
|
49
51
|
document.removeEventListener('reset', context$1.onReset);
|
|
@@ -55,26 +57,26 @@ function useForm(options) {
|
|
|
55
57
|
}));
|
|
56
58
|
});
|
|
57
59
|
var subjectRef = context.useSubjectRef();
|
|
58
|
-
var
|
|
60
|
+
var stateSnapshot = context.useFormState(context$1, subjectRef);
|
|
59
61
|
var noValidate = useNoValidate(options.defaultNoValidate);
|
|
60
|
-
var form = context.getFormMetadata(
|
|
62
|
+
var form = context.getFormMetadata(context$1, subjectRef, stateSnapshot, noValidate);
|
|
61
63
|
return [form, form.getFieldset()];
|
|
62
64
|
}
|
|
63
65
|
function useFormMetadata(formId) {
|
|
64
66
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
65
67
|
var subjectRef = context.useSubjectRef();
|
|
66
68
|
var context$1 = context.useFormContext(formId);
|
|
67
|
-
var
|
|
69
|
+
var stateSnapshot = context.useFormState(context$1, subjectRef);
|
|
68
70
|
var noValidate = useNoValidate(options.defaultNoValidate);
|
|
69
|
-
return context.getFormMetadata(context$1
|
|
71
|
+
return context.getFormMetadata(context$1, subjectRef, stateSnapshot, noValidate);
|
|
70
72
|
}
|
|
71
73
|
function useField(name) {
|
|
72
74
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
73
75
|
var subjectRef = context.useSubjectRef();
|
|
74
76
|
var context$1 = context.useFormContext(options.formId);
|
|
75
|
-
var
|
|
76
|
-
var field = context.getFieldMetadata(context$1
|
|
77
|
-
var form = context.getFormMetadata(context$1
|
|
77
|
+
var stateSnapshot = context.useFormState(context$1, subjectRef);
|
|
78
|
+
var field = context.getFieldMetadata(context$1, subjectRef, stateSnapshot, name);
|
|
79
|
+
var form = context.getFormMetadata(context$1, subjectRef, stateSnapshot, false);
|
|
78
80
|
return [field, form];
|
|
79
81
|
}
|
|
80
82
|
|
package/hooks.mjs
CHANGED
|
@@ -36,10 +36,12 @@ function useForm(options) {
|
|
|
36
36
|
formId
|
|
37
37
|
})));
|
|
38
38
|
useSafeLayoutEffect(() => {
|
|
39
|
+
var disconnect = context.observe();
|
|
39
40
|
document.addEventListener('input', context.onInput);
|
|
40
41
|
document.addEventListener('focusout', context.onBlur);
|
|
41
42
|
document.addEventListener('reset', context.onReset);
|
|
42
43
|
return () => {
|
|
44
|
+
disconnect();
|
|
43
45
|
document.removeEventListener('input', context.onInput);
|
|
44
46
|
document.removeEventListener('focusout', context.onBlur);
|
|
45
47
|
document.removeEventListener('reset', context.onReset);
|
|
@@ -51,26 +53,26 @@ function useForm(options) {
|
|
|
51
53
|
}));
|
|
52
54
|
});
|
|
53
55
|
var subjectRef = useSubjectRef();
|
|
54
|
-
var
|
|
56
|
+
var stateSnapshot = useFormState(context, subjectRef);
|
|
55
57
|
var noValidate = useNoValidate(options.defaultNoValidate);
|
|
56
|
-
var form = getFormMetadata(
|
|
58
|
+
var form = getFormMetadata(context, subjectRef, stateSnapshot, noValidate);
|
|
57
59
|
return [form, form.getFieldset()];
|
|
58
60
|
}
|
|
59
61
|
function useFormMetadata(formId) {
|
|
60
62
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
61
63
|
var subjectRef = useSubjectRef();
|
|
62
64
|
var context = useFormContext(formId);
|
|
63
|
-
var
|
|
65
|
+
var stateSnapshot = useFormState(context, subjectRef);
|
|
64
66
|
var noValidate = useNoValidate(options.defaultNoValidate);
|
|
65
|
-
return getFormMetadata(context
|
|
67
|
+
return getFormMetadata(context, subjectRef, stateSnapshot, noValidate);
|
|
66
68
|
}
|
|
67
69
|
function useField(name) {
|
|
68
70
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
69
71
|
var subjectRef = useSubjectRef();
|
|
70
72
|
var context = useFormContext(options.formId);
|
|
71
|
-
var
|
|
72
|
-
var field = getFieldMetadata(context
|
|
73
|
-
var form = getFormMetadata(context
|
|
73
|
+
var stateSnapshot = useFormState(context, subjectRef);
|
|
74
|
+
var field = getFieldMetadata(context, subjectRef, stateSnapshot, name);
|
|
75
|
+
var form = getFormMetadata(context, subjectRef, stateSnapshot, false);
|
|
74
76
|
return [field, form];
|
|
75
77
|
}
|
|
76
78
|
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Conform view adapter for react",
|
|
4
4
|
"homepage": "https://conform.guide",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"version": "1.0
|
|
6
|
+
"version": "1.1.0",
|
|
7
7
|
"main": "index.js",
|
|
8
8
|
"module": "index.mjs",
|
|
9
9
|
"types": "index.d.ts",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"url": "https://github.com/edmundhung/conform/issues"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@conform-to/dom": "1.0
|
|
33
|
+
"@conform-to/dom": "1.1.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/react": "^18.2.43",
|