Socket
Socket
Sign inDemoInstall

@conform-to/react

Package Overview
Dependencies
4
Maintainers
1
Versions
62
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.4.0-pre.1 to 0.4.0-pre.2

10

hooks.d.ts

@@ -43,3 +43,3 @@ import { type FieldConfig, type FieldElement, type FieldValue, type FieldsetConstraint, type ListCommand, type Primitive, type Submission } from '@conform-to/dom';

*/
onValidate?: (context: FormContext<Schema>) => void;
onValidate?: (context: FormContext<Schema>) => Array<[string, string]>;
/**

@@ -69,3 +69,3 @@ * The submit event handler of the form. It will be called

*
* @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.1/packages/conform-react/README.md#useform
* @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.2/packages/conform-react/README.md#useform
*/

@@ -111,3 +111,3 @@ export declare function useForm<Schema extends Record<string, any>>(config?: FormConfig<Schema>): Form<Schema>;

*
* @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.1/packages/conform-react/README.md#usefieldset
* @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.2/packages/conform-react/README.md#usefieldset
*/

@@ -139,3 +139,3 @@ export declare function useFieldset<Schema extends Record<string, any>>(ref: RefObject<HTMLFormElement | HTMLFieldSetElement>, config?: FieldsetConfig<Schema>): Fieldset<Schema>;

*
* @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.1/packages/conform-react/README.md#usefieldlist
* @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.2/packages/conform-react/README.md#usefieldlist
*/

@@ -170,3 +170,3 @@ export declare function useFieldList<Payload = any>(ref: RefObject<HTMLFormElement | HTMLFieldSetElement>, config: FieldConfig<Array<Payload>>): [

*
* @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.1/packages/conform-react/README.md#usecontrolledinput
* @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.2/packages/conform-react/README.md#usecontrolledinput
*/

@@ -173,0 +173,0 @@ export declare function useControlledInput<Element extends {

@@ -14,3 +14,3 @@ 'use strict';

*
* @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.1/packages/conform-react/README.md#useform
* @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.2/packages/conform-react/README.md#useform
*/

@@ -186,38 +186,42 @@ function useForm() {

var formData = dom.getFormData(form, submitter);
var submission = dom.parse(formData);
var context = {
form,
formData,
submission
}; // Touch all fields only if the submitter is not a command button
try {
var formData = dom.getFormData(form, submitter);
var submission = dom.parse(formData);
var _context = {
form,
formData,
submission
}; // Touch all fields only if the submitter is not a command button
if (!submission.type) {
for (var field of form.elements) {
if (dom.isFieldElement(field)) {
// Mark the field as touched
field.dataset.conformTouched = 'true';
if (submission.context === 'submit') {
for (var field of form.elements) {
if (dom.isFieldElement(field)) {
// Mark the field as touched
field.dataset.conformTouched = 'true';
}
}
}
}
try {
if (!config.noValidate && !submitter.formNoValidate) {
var _config$onValidate;
var _error;
(_config$onValidate = config.onValidate) === null || _config$onValidate === void 0 ? void 0 : _config$onValidate.call(config, context);
if (typeof config.onValidate === 'function') {
_error = config.onValidate(_context);
} else {
if (config.mode !== 'server-validation') {
// Clear previous result
dom.setFormError(form, {
context: 'submit',
value: {},
error: []
});
}
if (!form.reportValidity()) {
dom.focusFirstInvalidField(form);
event.preventDefault();
}
_error = dom.getFormError(form);
}
} catch (e) {
if (e !== form) {
console.warn(e);
if (_error.length > 0) {
submission.error.push(..._error);
}
}
if (!event.defaultPrevented) {
if (config.mode !== 'server-validation' && submission.type === 'validate') {
if (!config.noValidate && !submitter.formNoValidate && dom.hasError(submission.error) || submission.context === 'validate' && config.mode !== 'server-validation') {
event.preventDefault();

@@ -227,4 +231,14 @@ } else {

(_config$onSubmit = config.onSubmit) === null || _config$onSubmit === void 0 ? void 0 : _config$onSubmit.call(config, event, context);
(_config$onSubmit = config.onSubmit) === null || _config$onSubmit === void 0 ? void 0 : _config$onSubmit.call(config, event, _context);
}
if (event.defaultPrevented) {
dom.setFormError(form, submission);
if (!form.reportValidity()) {
dom.focusFirstInvalidField(form);
}
}
} catch (e) {
console.warn(e);
}

@@ -429,3 +443,3 @@ }

*
* @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.1/packages/conform-react/README.md#usefieldlist
* @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.2/packages/conform-react/README.md#usefieldlist
*/

@@ -574,3 +588,3 @@ function useFieldList(ref, config) {

*
* @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.1/packages/conform-react/README.md#usecontrolledinput
* @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.2/packages/conform-react/README.md#usecontrolledinput
*/

@@ -577,0 +591,0 @@ function useControlledInput(config) {

@@ -1,3 +0,3 @@

export { type FieldsetConstraint, type Submission, hasError, isFieldElement, parse, setFormError, shouldValidate, } from '@conform-to/dom';
export { type FieldsetConstraint, type Submission, getFormError, hasError, isFieldElement, parse, shouldValidate, } from '@conform-to/dom';
export * from './hooks';
export * as conform from './helpers';

@@ -11,2 +11,6 @@ 'use strict';

Object.defineProperty(exports, 'getFormError', {
enumerable: true,
get: function () { return dom.getFormError; }
});
Object.defineProperty(exports, 'hasError', {

@@ -24,6 +28,2 @@ enumerable: true,

});
Object.defineProperty(exports, 'setFormError', {
enumerable: true,
get: function () { return dom.setFormError; }
});
Object.defineProperty(exports, 'shouldValidate', {

@@ -30,0 +30,0 @@ enumerable: true,

import { objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.js';
import { getSubmissionType, setFormError, focusFirstInvalidField, requestSubmit, isFieldElement, getFormData, parse, getPaths, getName, requestValidate, getFormElement, parseListCommand, updateList } from '@conform-to/dom';
import { getSubmissionType, setFormError, focusFirstInvalidField, requestSubmit, isFieldElement, getFormData, parse, getFormError, hasError, getPaths, getName, requestValidate, getFormElement, parseListCommand, updateList } from '@conform-to/dom';
import { useRef, useState, useEffect } from 'react';

@@ -10,3 +10,3 @@ import { input } from './helpers.js';

*
* @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.1/packages/conform-react/README.md#useform
* @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.2/packages/conform-react/README.md#useform
*/

@@ -182,38 +182,42 @@ function useForm() {

var formData = getFormData(form, submitter);
var submission = parse(formData);
var context = {
form,
formData,
submission
}; // Touch all fields only if the submitter is not a command button
try {
var formData = getFormData(form, submitter);
var submission = parse(formData);
var _context = {
form,
formData,
submission
}; // Touch all fields only if the submitter is not a command button
if (!submission.type) {
for (var field of form.elements) {
if (isFieldElement(field)) {
// Mark the field as touched
field.dataset.conformTouched = 'true';
if (submission.context === 'submit') {
for (var field of form.elements) {
if (isFieldElement(field)) {
// Mark the field as touched
field.dataset.conformTouched = 'true';
}
}
}
}
try {
if (!config.noValidate && !submitter.formNoValidate) {
var _config$onValidate;
var _error;
(_config$onValidate = config.onValidate) === null || _config$onValidate === void 0 ? void 0 : _config$onValidate.call(config, context);
if (typeof config.onValidate === 'function') {
_error = config.onValidate(_context);
} else {
if (config.mode !== 'server-validation') {
// Clear previous result
setFormError(form, {
context: 'submit',
value: {},
error: []
});
}
if (!form.reportValidity()) {
focusFirstInvalidField(form);
event.preventDefault();
}
_error = getFormError(form);
}
} catch (e) {
if (e !== form) {
console.warn(e);
if (_error.length > 0) {
submission.error.push(..._error);
}
}
if (!event.defaultPrevented) {
if (config.mode !== 'server-validation' && submission.type === 'validate') {
if (!config.noValidate && !submitter.formNoValidate && hasError(submission.error) || submission.context === 'validate' && config.mode !== 'server-validation') {
event.preventDefault();

@@ -223,4 +227,14 @@ } else {

(_config$onSubmit = config.onSubmit) === null || _config$onSubmit === void 0 ? void 0 : _config$onSubmit.call(config, event, context);
(_config$onSubmit = config.onSubmit) === null || _config$onSubmit === void 0 ? void 0 : _config$onSubmit.call(config, event, _context);
}
if (event.defaultPrevented) {
setFormError(form, submission);
if (!form.reportValidity()) {
focusFirstInvalidField(form);
}
}
} catch (e) {
console.warn(e);
}

@@ -425,3 +439,3 @@ }

*
* @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.1/packages/conform-react/README.md#usefieldlist
* @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.2/packages/conform-react/README.md#usefieldlist
*/

@@ -570,3 +584,3 @@ function useFieldList(ref, config) {

*
* @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.1/packages/conform-react/README.md#usecontrolledinput
* @see https://github.com/edmundhung/conform/tree/v0.4.0-pre.2/packages/conform-react/README.md#usecontrolledinput
*/

@@ -573,0 +587,0 @@ function useControlledInput(config) {

@@ -1,4 +0,4 @@

export { hasError, isFieldElement, parse, setFormError, shouldValidate } from '@conform-to/dom';
export { getFormError, hasError, isFieldElement, parse, shouldValidate } from '@conform-to/dom';
export { useControlledInput, useFieldList, useFieldset, useForm } from './hooks.js';
import * as helpers from './helpers.js';
export { helpers as conform };

@@ -5,3 +5,3 @@ {

"license": "MIT",
"version": "0.4.0-pre.1",
"version": "0.4.0-pre.2",
"main": "index.js",

@@ -23,3 +23,3 @@ "module": "module/index.js",

"dependencies": {
"@conform-to/dom": "0.4.0-pre.1"
"@conform-to/dom": "0.4.0-pre.2"
},

@@ -26,0 +26,0 @@ "peerDependencies": {

@@ -13,4 +13,8 @@ # @conform-to/react

- [useControlledInput](#usecontrolledinput)
- [createValidate](#createvalidate)
- [conform](#conform)
- [hasError](#haserror)
- [isFieldElement](#isfieldelement)
- [parse](#parse)
- [setFormError](#setformerror)
- [shouldValidate](#shouldvalidate)

@@ -25,4 +29,4 @@ <!-- /aside -->

1. It lets you hook up custom validation logic into different form events. For example, revalidation will be triggered whenever something changed.
2. It provides options for you to decide the best timing to start reporting errors. This could be as earliest as the user start typing, or also as late as the user try submitting the form.
1. It enhances form validation with custom rules by subscribing to different DOM events and reporting the errors only when it is configured to do so.
2. It unifies client and server validation in one place.
3. It exposes the state of each field in the form of [data attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/data-*), such as `data-conform-touched`, allowing flexible styling across your form without the need to manipulate the class names.

@@ -34,4 +38,12 @@

function LoginForm() {
const formProps = useForm({
const form = useForm({
/**
* Validation mode.
* Support "client-only" or "server-validation".
*
* Default to `client-only`.
*/
mode: 'client-only',
/**
* Define when the error should be reported initially.

@@ -45,2 +57,12 @@ * Support "onSubmit", "onChange", "onBlur".

/**
* An object representing the initial value of the form.
*/
defaultValue: undefined;
/**
* An object describing the state from the last submission
*/
state: undefined;
/**
* Enable native validation before hydation.

@@ -61,4 +83,5 @@ *

* A function to be called when the form should be (re)validated.
* Only sync validation is supported
*/
validate(form, submitter) {
onValidate({ form, formData, submission }) {
// ...

@@ -70,3 +93,3 @@ },

*/
onSubmit(event) {
onSubmit(event, { form, formData, submission }) {
// ...

@@ -76,9 +99,3 @@ },

return (
<form {...formProps}>
<input type="email" name="email" required />
<input type="password" name="password" required />
<button type="submit">Login</button>
</form>
);
// ...
}

@@ -88,3 +105,3 @@ ```

<details>
<summary>What is `formProps`?</summary>
<summary>What is `form.props`?</summary>

@@ -95,9 +112,9 @@ It is a group of properties properties required to hook into form events. They can also be set explicitly as shown below:

function RandomForm() {
const formProps = useForm();
const form = useForm();
return (
<form
ref={formProps.ref}
onSubmit={formProps.onSubmit}
noValidate={formProps.noValidate}
ref={form.props.ref}
onSubmit={form.props.onSubmit}
noValidate={form.props.noValidate}
>

@@ -115,3 +132,3 @@ {/* ... */}

Yes! It will fallback to native form submission if the submit event handler is omitted or the event is not default prevented.
Yes! It will fallback to native form submission as long as the submit event is not default prevented.

@@ -123,6 +140,6 @@ ```tsx

function LoginForm() {
const formProps = useForm();
const form = useForm();
return (
<Form method="post" action="/login" {...formProps}>
<Form method="post" action="/login" {...form.props}>
{/* ... */}

@@ -137,5 +154,5 @@ </Form>

<details>
<summary>Is the `validate` function required?</summary>
<summary>Is the `onValidate` function required?</summary>
The `validate` function is not required if the validation logic can be fully covered by the [native constraints](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Constraint_validation#validation-related_attributes), e.g. **required** / **min** / **pattern** etc.
The `onValidate` function is not required if the validation logic can be fully covered by the [native constraints](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Constraint_validation#validation-related_attributes), e.g. **required** / **min** / **pattern** etc.

@@ -171,6 +188,6 @@ ```tsx

This hook can be used to monitor the state of each field and help fields configuration. It lets you:
This hook can be used to monitor the state of each field and help configuration. It lets you:
1. Capturing errors at the form/fieldset level, removing the need to setup invalid handler on each field.
2. Defining config in one central place. e.g. name, default value and constraint, then distributing it to each field using the [conform](#conform) helpers.
2. Defining config in one central place. e.g. name, default value and constraint, then distributing it to each field with the [conform](#conform) helpers.

@@ -509,3 +526,3 @@ ```tsx

</fieldset>
)
);
}

@@ -516,53 +533,2 @@ ```

### createValidate
This help you configure a validate function to check the validity of each fields and setup custom messages using the Constraint Validation APIs.
```tsx
import { useForm, createValidate } from '@conform-to/react';
export default function SignupForm() {
const formProps = useForm({
validate: createValidate((field, formData) => {
switch (field.name) {
case 'email':
if (field.validity.valueMissing) {
field.setCustomValidity('Email is required');
} else if (field.validity.typeMismatch) {
field.setCustomValidity('Please enter a valid email');
} else {
field.setCustomValidity('');
}
break;
case 'password':
if (field.validity.valueMissing) {
field.setCustomValidity('Password is required');
} else if (field.validity.tooShort) {
field.setCustomValidity(
'The password should be at least 10 characters long',
);
} else {
field.setCustomValidity('');
}
break;
case 'confirm-password': {
if (field.validity.valueMissing) {
field.setCustomValidity('Confirm Password is required');
} else if (field.value !== formData.get('password')) {
field.setCustomValidity('The password does not match');
} else {
field.setCustomValidity('');
}
break;
}
}
}),
});
return <form {...formProps}>{/* ... */}</form>;
}
```
---
### conform

@@ -633,1 +599,144 @@

```
### hasError
This helper checks if there is any message defined in error array with the provided name.
```ts
import { hasError } from '@conform-to/react';
/**
* Assume the error looks like this:
*/
const error = [['email', 'Email is required']];
// This will log `true`
console.log(hasError(error, 'email'));
// This will log `false`
console.log(hasError(error, 'password'));
```
---
### isFieldElement
This checks if the provided element is an `input` / `select` / `textarea` or `button` HTML element with type guard. Useful when you need to access the validityState of the fields and modify the validation message manually.
```tsx
import { isFieldElement } from '@conform-to/react';
export default function SignupForm() {
const form = useForm({
onValidate({ form }) {
for (const element of form.elements) {
if (isFieldElement(element)) {
switch (field.name) {
case 'email':
if (field.validity.valueMissing) {
field.setCustomValidity('Email is required');
} else if (field.validity.typeMismatch) {
field.setCustomValidity('Please enter a valid email');
} else {
field.setCustomValidity('');
}
break;
case 'password':
if (field.validity.valueMissing) {
field.setCustomValidity('Password is required');
} else if (field.validity.tooShort) {
field.setCustomValidity(
'The password should be at least 10 characters long',
);
} else {
field.setCustomValidity('');
}
break;
case 'confirm-password': {
if (field.validity.valueMissing) {
field.setCustomValidity('Confirm Password is required');
} else if (field.value !== formData.get('password')) {
field.setCustomValidity('The password does not match');
} else {
field.setCustomValidity('');
}
break;
}
}
}
}
},
});
// ...
}
```
---
### parse
It parses the formData based on the [naming convention](/docs/submission).
```tsx
import { parse } from '@conform-to/react';
const formData = new FormData(formElement);
const submission = parse(formData);
console.log(submission);
```
---
### setFormError
This helpers updates the form error based on the submission result by looping through all elements in the form and update the error with the [setCustomValidity](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setCustomValidity) API.
```tsx
import { setFormError } from '@conform-to/react';
function ExampleForm() {
const form = useForm({
onValidate({ form, submission }) {
const error = validate(submission);
setFormError(form, {
...submission,
error,
});
},
});
// ...
}
```
---
### shouldValidate
This helper checks if the scope of validation includes a specific field by checking the submission:
```tsx
import { shouldValidate } from '@conform-to/react';
/**
* The submission type and metadata give us hint on what should be valdiated.
* If the type is 'validate', only the field with name matching the metadata must be validated.
*
* However, if the type is `undefined`, both will log true (Default submission)
*/
const submission = {
type: 'validate',
metadata: 'email',
value: {},
error: [],
};
// This will log 'true'
console.log(shouldValidate(submission, 'email'));
// This will log 'false'
console.log(shouldValidate(submission, 'password'));
```
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc