@conform-to/react 1.0.0-rc.0 → 1.0.0-rc.1
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 +2 -2
- package/context.d.ts +18 -7
- package/context.js +26 -7
- package/context.mjs +28 -10
- package/helpers.d.ts +1 -1
- package/hooks.d.ts +2 -2
- package/hooks.js +1 -2
- package/hooks.mjs +2 -3
- package/index.d.ts +1 -1
- package/package.json +2 -2
package/README
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
Version 1.0.0-rc.0 / License MIT / Copyright (c) 2024 Edmund Hung
|
|
12
12
|
|
|
13
|
-
A type-safe form validation library utilizing web fundamentals to progressively enhance HTML Forms with full support for server frameworks like Remix
|
|
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
|
|
|
15
15
|
> Getting Started
|
|
16
16
|
|
|
@@ -21,7 +21,7 @@ Check out the overview and tutorial at our website https://conform.guide
|
|
|
21
21
|
The documentation is divided into several sections:
|
|
22
22
|
|
|
23
23
|
* Overview: https://conform.guide/overview
|
|
24
|
-
*
|
|
24
|
+
* Examples: https://conform.guide/examples
|
|
25
25
|
* Complex structures: https://conform.guide/complex-structures
|
|
26
26
|
* UI Integrations: https://conform.guide/integrations
|
|
27
27
|
* Accessibility Guide: https://conform.guide/accessibility
|
package/context.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type Constraint, type FormId, type FieldName, type FormContext, type FormValue, type FormState, type Intent, type SubscriptionScope, type SubscriptionSubject, type UnionKeyof, type UnionKeyType } from '@conform-to/dom';
|
|
2
|
-
import { type ReactElement, type ReactNode, type MutableRefObject } from 'react';
|
|
1
|
+
import { type Constraint, type FormId, type FieldName, type FormContext as BaseFormContext, type FormValue, type FormState, type Intent, type SubscriptionScope, type SubscriptionSubject, type UnionKeyof, type UnionKeyType, type FormOptions as BaseFormOptions } from '@conform-to/dom';
|
|
2
|
+
import { type FormEvent, type ReactElement, type ReactNode, type MutableRefObject } from 'react';
|
|
3
3
|
export type Pretty<T> = {
|
|
4
4
|
[K in keyof T]: T[K];
|
|
5
5
|
} & {};
|
|
@@ -35,16 +35,16 @@ export type FieldMetadata<Schema = unknown, FormSchema extends Record<string, an
|
|
|
35
35
|
};
|
|
36
36
|
getFieldList: unknown extends Schema ? () => unknown : Schema extends Array<infer Item> ? () => Array<FieldMetadata<Item, FormSchema, FormError>> : never;
|
|
37
37
|
};
|
|
38
|
-
export declare const Form: import("react").Context<FormContext[]>;
|
|
38
|
+
export declare const Form: import("react").Context<FormContext<any, string[], any>[]>;
|
|
39
39
|
declare const wrappedSymbol: unique symbol;
|
|
40
40
|
export type Wrapped<Type> = {
|
|
41
41
|
[wrappedSymbol]: Type;
|
|
42
42
|
};
|
|
43
43
|
export declare function getWrappedFormContext(context: Wrapped<FormContext>): FormContext;
|
|
44
|
-
export declare function useFormContext<Schema extends Record<string, any>, FormError>(formId?: FormId<Schema, FormError>): FormContext<Schema,
|
|
45
|
-
export declare function useFormState<FormError>(form: FormContext<any,
|
|
44
|
+
export declare function useFormContext<Schema extends Record<string, any>, FormError>(formId?: FormId<Schema, FormError>): FormContext<Schema, FormError, unknown>;
|
|
45
|
+
export declare function useFormState<FormError>(form: FormContext<any, FormError>, subjectRef?: MutableRefObject<SubscriptionSubject>): FormState<FormError>;
|
|
46
46
|
export declare function FormProvider(props: {
|
|
47
|
-
context: Wrapped<FormContext<any, any
|
|
47
|
+
context: Wrapped<FormContext<any, any>>;
|
|
48
48
|
children: ReactNode;
|
|
49
49
|
}): ReactElement;
|
|
50
50
|
export declare function FormStateInput(props: {
|
|
@@ -54,5 +54,16 @@ export declare function useSubjectRef(initialSubject?: SubscriptionSubject): Mut
|
|
|
54
54
|
export declare function updateSubjectRef(ref: MutableRefObject<SubscriptionSubject>, name: string, subject: keyof SubscriptionSubject, scope: keyof SubscriptionScope): void;
|
|
55
55
|
export declare function getMetadata<Schema, FormError, FormSchema extends Record<string, any>>(formId: FormId<FormSchema, FormError>, state: FormState<FormError>, subjectRef: MutableRefObject<SubscriptionSubject>, name?: FieldName<Schema, FormSchema, FormError>): Metadata<Schema, FormSchema, FormError>;
|
|
56
56
|
export declare function getFieldMetadata<Schema, FormSchema extends Record<string, any>, FormError>(formId: FormId<FormSchema, FormError>, state: FormState<FormError>, subjectRef: MutableRefObject<SubscriptionSubject>, prefix?: string, key?: string | number): FieldMetadata<Schema, FormSchema, FormError>;
|
|
57
|
-
export declare function getFormMetadata<Schema extends Record<string, any>,
|
|
57
|
+
export declare function getFormMetadata<Schema extends Record<string, any>, FormError = string[], FormValue = Schema>(formId: FormId<Schema, FormError>, state: FormState<FormError>, subjectRef: MutableRefObject<SubscriptionSubject>, context: FormContext<Schema, FormError, FormValue>, noValidate: boolean): FormMetadata<Schema, FormError>;
|
|
58
|
+
export type FormOptions<Schema extends Record<string, any> = any, FormError = string[], FormValue = Schema> = BaseFormOptions<Schema, FormError, FormValue> & {
|
|
59
|
+
/**
|
|
60
|
+
* A function to be called before the form is submitted.
|
|
61
|
+
*/
|
|
62
|
+
onSubmit?: (event: FormEvent<HTMLFormElement>, context: ReturnType<BaseFormContext<Schema, FormError, FormValue>['submit']>) => void;
|
|
63
|
+
};
|
|
64
|
+
export type FormContext<Schema extends Record<string, any> = any, FormError = string[], FormValue = Schema> = Omit<BaseFormContext<Schema, FormError, FormValue>, 'submit' | 'onUpdate'> & {
|
|
65
|
+
submit: (event: FormEvent<HTMLFormElement>) => void;
|
|
66
|
+
onUpdate: (options: Partial<FormOptions<Schema, FormError, FormValue>>) => void;
|
|
67
|
+
};
|
|
68
|
+
export declare function createFormContext<Schema extends Record<string, any> = any, FormError = string[], FormValue = Schema>(options: FormOptions<Schema, FormError, FormValue>): FormContext<Schema, FormError, FormValue>;
|
|
58
69
|
export {};
|
package/context.js
CHANGED
|
@@ -7,6 +7,7 @@ var dom = require('@conform-to/dom');
|
|
|
7
7
|
var react = require('react');
|
|
8
8
|
var jsxRuntime = require('react/jsx-runtime');
|
|
9
9
|
|
|
10
|
+
var _excluded = ["onSubmit"];
|
|
10
11
|
var Form = /*#__PURE__*/react.createContext([]);
|
|
11
12
|
|
|
12
13
|
// To hide the FormContext type from the public API
|
|
@@ -174,13 +175,7 @@ function getFormMetadata(formId, state, subjectRef, context, noValidate) {
|
|
|
174
175
|
case 'reorder':
|
|
175
176
|
return context[key];
|
|
176
177
|
case 'onSubmit':
|
|
177
|
-
return
|
|
178
|
-
var submitEvent = event.nativeEvent;
|
|
179
|
-
var submission = context.submit(submitEvent);
|
|
180
|
-
if (submission && submission.status !== 'success' && submission.error !== null) {
|
|
181
|
-
event.preventDefault();
|
|
182
|
-
}
|
|
183
|
-
};
|
|
178
|
+
return context.submit;
|
|
184
179
|
case 'noValidate':
|
|
185
180
|
return noValidate;
|
|
186
181
|
}
|
|
@@ -188,10 +183,34 @@ function getFormMetadata(formId, state, subjectRef, context, noValidate) {
|
|
|
188
183
|
}
|
|
189
184
|
});
|
|
190
185
|
}
|
|
186
|
+
function createFormContext(options) {
|
|
187
|
+
var {
|
|
188
|
+
onSubmit
|
|
189
|
+
} = options,
|
|
190
|
+
rest = _rollupPluginBabelHelpers.objectWithoutProperties(options, _excluded);
|
|
191
|
+
var context = dom.unstable_createFormContext(rest);
|
|
192
|
+
return _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, context), {}, {
|
|
193
|
+
submit(event) {
|
|
194
|
+
var submitEvent = event.nativeEvent;
|
|
195
|
+
var result = context.submit(submitEvent);
|
|
196
|
+
if (result.submission && result.submission.status !== 'success' && result.submission.error !== null) {
|
|
197
|
+
event.preventDefault();
|
|
198
|
+
} else {
|
|
199
|
+
var _onSubmit;
|
|
200
|
+
(_onSubmit = onSubmit) === null || _onSubmit === void 0 || _onSubmit(event, result);
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
onUpdate(options) {
|
|
204
|
+
onSubmit = options.onSubmit;
|
|
205
|
+
context.onUpdate(options);
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
}
|
|
191
209
|
|
|
192
210
|
exports.Form = Form;
|
|
193
211
|
exports.FormProvider = FormProvider;
|
|
194
212
|
exports.FormStateInput = FormStateInput;
|
|
213
|
+
exports.createFormContext = createFormContext;
|
|
195
214
|
exports.getFieldMetadata = getFieldMetadata;
|
|
196
215
|
exports.getFormMetadata = getFormMetadata;
|
|
197
216
|
exports.getMetadata = getMetadata;
|
package/context.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.mjs';
|
|
2
|
-
import { STATE, formatPaths, getPaths, isPrefix } from '@conform-to/dom';
|
|
1
|
+
import { objectWithoutProperties as _objectWithoutProperties, objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.mjs';
|
|
2
|
+
import { STATE, formatPaths, getPaths, unstable_createFormContext, 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
|
|
|
6
|
+
var _excluded = ["onSubmit"];
|
|
6
7
|
var Form = /*#__PURE__*/createContext([]);
|
|
7
8
|
|
|
8
9
|
// To hide the FormContext type from the public API
|
|
@@ -170,13 +171,7 @@ function getFormMetadata(formId, state, subjectRef, context, noValidate) {
|
|
|
170
171
|
case 'reorder':
|
|
171
172
|
return context[key];
|
|
172
173
|
case 'onSubmit':
|
|
173
|
-
return
|
|
174
|
-
var submitEvent = event.nativeEvent;
|
|
175
|
-
var submission = context.submit(submitEvent);
|
|
176
|
-
if (submission && submission.status !== 'success' && submission.error !== null) {
|
|
177
|
-
event.preventDefault();
|
|
178
|
-
}
|
|
179
|
-
};
|
|
174
|
+
return context.submit;
|
|
180
175
|
case 'noValidate':
|
|
181
176
|
return noValidate;
|
|
182
177
|
}
|
|
@@ -184,5 +179,28 @@ function getFormMetadata(formId, state, subjectRef, context, noValidate) {
|
|
|
184
179
|
}
|
|
185
180
|
});
|
|
186
181
|
}
|
|
182
|
+
function createFormContext(options) {
|
|
183
|
+
var {
|
|
184
|
+
onSubmit
|
|
185
|
+
} = options,
|
|
186
|
+
rest = _objectWithoutProperties(options, _excluded);
|
|
187
|
+
var context = unstable_createFormContext(rest);
|
|
188
|
+
return _objectSpread2(_objectSpread2({}, context), {}, {
|
|
189
|
+
submit(event) {
|
|
190
|
+
var submitEvent = event.nativeEvent;
|
|
191
|
+
var result = context.submit(submitEvent);
|
|
192
|
+
if (result.submission && result.submission.status !== 'success' && result.submission.error !== null) {
|
|
193
|
+
event.preventDefault();
|
|
194
|
+
} else {
|
|
195
|
+
var _onSubmit;
|
|
196
|
+
(_onSubmit = onSubmit) === null || _onSubmit === void 0 || _onSubmit(event, result);
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
onUpdate(options) {
|
|
200
|
+
onSubmit = options.onSubmit;
|
|
201
|
+
context.onUpdate(options);
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
}
|
|
187
205
|
|
|
188
|
-
export { Form, FormProvider, FormStateInput, getFieldMetadata, getFormMetadata, getMetadata, getWrappedFormContext, updateSubjectRef, useFormContext, useFormState, useSubjectRef };
|
|
206
|
+
export { Form, FormProvider, FormStateInput, createFormContext, getFieldMetadata, getFormMetadata, getMetadata, getWrappedFormContext, updateSubjectRef, useFormContext, useFormState, useSubjectRef };
|
package/helpers.d.ts
CHANGED
|
@@ -27,7 +27,7 @@ type FormControlOptions = {
|
|
|
27
27
|
ariaAttributes: false;
|
|
28
28
|
};
|
|
29
29
|
type InputProps = Pretty<FormControlProps & {
|
|
30
|
-
type: 'checkbox' | 'color' | 'date' | 'datetime-local' | 'email' | 'file' | 'hidden' | '
|
|
30
|
+
type: 'checkbox' | 'color' | 'date' | 'datetime-local' | 'email' | 'file' | 'hidden' | 'month' | 'number' | 'password' | 'radio' | 'range' | 'search' | 'tel' | 'text' | 'time' | 'url' | 'week';
|
|
31
31
|
minLength?: number;
|
|
32
32
|
maxLength?: number;
|
|
33
33
|
min?: string | number;
|
package/hooks.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { type FormId, type FieldName
|
|
1
|
+
import { type FormId, type FieldName } from '@conform-to/dom';
|
|
2
2
|
import { useEffect } from 'react';
|
|
3
|
-
import { type FormMetadata, type FieldMetadata, type Pretty } from './context';
|
|
3
|
+
import { type FormMetadata, type FieldMetadata, type Pretty, type FormOptions } from './context';
|
|
4
4
|
/**
|
|
5
5
|
* useLayoutEffect is client-only.
|
|
6
6
|
* This basically makes it a no-op on server
|
package/hooks.js
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var _rollupPluginBabelHelpers = require('./_virtual/_rollupPluginBabelHelpers.js');
|
|
6
|
-
var dom = require('@conform-to/dom');
|
|
7
6
|
var react = require('react');
|
|
8
7
|
var context = require('./context.js');
|
|
9
8
|
|
|
@@ -37,7 +36,7 @@ function useForm(options) {
|
|
|
37
36
|
} = options,
|
|
38
37
|
formConfig = _rollupPluginBabelHelpers.objectWithoutProperties(options, _excluded);
|
|
39
38
|
var formId = useFormId(id);
|
|
40
|
-
var [context$1] = react.useState(() =>
|
|
39
|
+
var [context$1] = react.useState(() => context.createFormContext(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, formConfig), {}, {
|
|
41
40
|
formId
|
|
42
41
|
})));
|
|
43
42
|
useSafeLayoutEffect(() => {
|
package/hooks.mjs
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { objectWithoutProperties as _objectWithoutProperties, objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.mjs';
|
|
2
|
-
import { unstable_createFormContext } from '@conform-to/dom';
|
|
3
2
|
import { useState, useEffect, useLayoutEffect, useId } from 'react';
|
|
4
|
-
import { useSubjectRef, useFormState, getFormMetadata, useFormContext, getFieldMetadata } from './context.mjs';
|
|
3
|
+
import { createFormContext, useSubjectRef, useFormState, getFormMetadata, useFormContext, getFieldMetadata } from './context.mjs';
|
|
5
4
|
|
|
6
5
|
var _excluded = ["id"];
|
|
7
6
|
|
|
@@ -33,7 +32,7 @@ function useForm(options) {
|
|
|
33
32
|
} = options,
|
|
34
33
|
formConfig = _objectWithoutProperties(options, _excluded);
|
|
35
34
|
var formId = useFormId(id);
|
|
36
|
-
var [context] = useState(() =>
|
|
35
|
+
var [context] = useState(() => createFormContext(_objectSpread2(_objectSpread2({}, formConfig), {}, {
|
|
37
36
|
formId
|
|
38
37
|
})));
|
|
39
38
|
useSafeLayoutEffect(() => {
|
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { type Submission, type SubmissionResult, type DefaultValue, type Intent, type FormId, type FieldName, parse, } from '@conform-to/dom';
|
|
2
2
|
export { type FieldMetadata, type FormMetadata, FormProvider, FormStateInput, } from './context';
|
|
3
3
|
export { useForm, useFormMetadata, useField } from './hooks';
|
|
4
|
-
export {
|
|
4
|
+
export { useInputControl } from './integrations';
|
|
5
5
|
export { getFormProps, getFieldsetProps, getInputProps, getSelectProps, getTextareaProps, getCollectionProps, } from './helpers';
|
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.0-rc.
|
|
6
|
+
"version": "1.0.0-rc.1",
|
|
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.0-rc.
|
|
33
|
+
"@conform-to/dom": "1.0.0-rc.1"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/react": "^18.2.43",
|