fix(hooks): usage of useForm
This commit is contained in:
parent
17656c149a
commit
a2edafdc22
@ -1,9 +1,11 @@
|
|||||||
|
# For more information see: https://editorconfig.org/
|
||||||
|
|
||||||
root = true
|
root = true
|
||||||
|
|
||||||
[*]
|
[*]
|
||||||
charset = utf-8
|
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
end_of_line = lf
|
end_of_line = lf
|
||||||
insert_final_newline = true
|
charset = utf-8
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
21
README.md
21
README.md
@ -41,7 +41,7 @@ import React from 'react'
|
|||||||
import { Form } from 'react-component-form'
|
import { Form } from 'react-component-form'
|
||||||
import type { HandleForm } from 'react-component-form'
|
import type { HandleForm } from 'react-component-form'
|
||||||
|
|
||||||
const Example = () => {
|
export const Example = () => {
|
||||||
const handleSubmit: HandleForm = (formData, formElement) => {
|
const handleSubmit: HandleForm = (formData, formElement) => {
|
||||||
console.log(formData) // { inputName: 'value of the input' }
|
console.log(formData) // { inputName: 'value of the input' }
|
||||||
formElement.reset()
|
formElement.reset()
|
||||||
@ -72,27 +72,30 @@ You can see a more detailled example in the [./example](./example) folder.
|
|||||||
```tsx
|
```tsx
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { Form, useForm } from 'react-component-form'
|
import { Form, useForm } from 'react-component-form'
|
||||||
import type { HandleSubmitCallback } from 'react-component-form'
|
import type { HandleUseFormCallback } from 'react-component-form'
|
||||||
|
|
||||||
const schema = {
|
const schema = {
|
||||||
inputName: {
|
inputName: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
required: true,
|
|
||||||
minLength: 3,
|
minLength: 3,
|
||||||
maxLength: 10
|
maxLength: 20
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Example = () => {
|
export const Example = () => {
|
||||||
const { errors, handleSubmit } = useForm(schema)
|
const { errors, handleUseForm } = useForm(schema)
|
||||||
|
|
||||||
const onSubmit: HandleSubmitCallback<typeof schema> = (formData, formElement) => {
|
const onSubmit: HandleUseFormCallback<typeof schema> = (
|
||||||
console.log(formData) // { inputName: 'value of the input' }
|
formData,
|
||||||
|
formElement
|
||||||
|
) => {
|
||||||
|
console.log(formData) // { inputName: 'value of the input validated' }
|
||||||
formElement.reset()
|
formElement.reset()
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form onSubmit={handleSubmit(onSubmit)}>
|
<Form onSubmit={handleUseForm(onSubmit)}>
|
||||||
<input type='text' name='inputName' />
|
<input type='text' name='inputName' />
|
||||||
{errors.inputName != null && <p>{errors.inputName[0].message}</p>}
|
{errors.inputName != null && <p>{errors.inputName[0].message}</p>}
|
||||||
|
|
||||||
|
@ -1,65 +1,38 @@
|
|||||||
import React from 'react'
|
|
||||||
import { createRoot } from 'react-dom/client'
|
import { createRoot } from 'react-dom/client'
|
||||||
import { Form, HandleForm } from 'react-component-form'
|
import React from 'react'
|
||||||
|
import { Form, useForm } from 'react-component-form'
|
||||||
|
import type { HandleUseFormCallback } from 'react-component-form'
|
||||||
|
|
||||||
import './index.css'
|
const schema = {
|
||||||
import GitHubLogo from 'url:./github.jpg'
|
inputName: {
|
||||||
|
type: 'string',
|
||||||
const App: React.FC = () => {
|
minLength: 3,
|
||||||
const handleSubmit: HandleForm = (formData, formElement) => {
|
maxLength: 20
|
||||||
console.clear()
|
}
|
||||||
console.log('onSubmit: ', formData)
|
|
||||||
formElement.reset()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleChange: HandleForm = (formData) => {
|
export const Example = () => {
|
||||||
console.log('onChange: ', formData)
|
const { errors, handleUseForm } = useForm(schema)
|
||||||
|
|
||||||
|
const onSubmit: HandleUseFormCallback<typeof schema> = (
|
||||||
|
formData,
|
||||||
|
formElement
|
||||||
|
) => {
|
||||||
|
console.log(formData) // { inputName: 'value of the input validated' }
|
||||||
|
formElement.reset()
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='container'>
|
<Form onSubmit={handleUseForm(onSubmit)}>
|
||||||
<h2>{'<Form />'}</h2>
|
<input type='text' name='inputName' />
|
||||||
<h5 className='title-install'>npm install --save react-component-form</h5>
|
{errors.inputName != null && <p>{errors.inputName[0].message}</p>}
|
||||||
|
|
||||||
<Form onSubmit={handleSubmit} onChange={handleChange}>
|
<button type='submit'>Submit</button>
|
||||||
<div className='form-group'>
|
|
||||||
<label htmlFor='name'>Name :</label>
|
|
||||||
<input
|
|
||||||
className='form-control'
|
|
||||||
type='text'
|
|
||||||
name='name'
|
|
||||||
id='name'
|
|
||||||
placeholder='name'
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button type='submit' className='btn btn-primary'>
|
|
||||||
Submit
|
|
||||||
</button>
|
|
||||||
</Form>
|
</Form>
|
||||||
|
|
||||||
<div className='result-container'>
|
|
||||||
<h4>
|
|
||||||
Try the form and Inspect the console{' '}
|
|
||||||
<span role='img' aria-label='smiley'>
|
|
||||||
😃
|
|
||||||
</span>
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='github-logo'>
|
|
||||||
<a
|
|
||||||
target='_blank'
|
|
||||||
rel='noopener noreferrer'
|
|
||||||
href='https://github.com/Divlo/react-component-form'
|
|
||||||
>
|
|
||||||
<img width='30px' alt='github' src={GitHubLogo} />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const container = document.getElementById('root') as HTMLElement
|
const container = document.getElementById('root') as HTMLElement
|
||||||
const root = createRoot(container)
|
const root = createRoot(container)
|
||||||
root.render(<App />)
|
root.render(<Example />)
|
||||||
|
16
example/package-lock.json
generated
16
example/package-lock.json
generated
@ -15,6 +15,7 @@
|
|||||||
"@types/react": "18.0.17",
|
"@types/react": "18.0.17",
|
||||||
"@types/react-dom": "18.0.6",
|
"@types/react-dom": "18.0.6",
|
||||||
"parcel": "2.7.0",
|
"parcel": "2.7.0",
|
||||||
|
"process": "^0.11.10",
|
||||||
"typescript": "4.7.4"
|
"typescript": "4.7.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -2505,6 +2506,15 @@
|
|||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/process": {
|
||||||
|
"version": "0.11.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
|
||||||
|
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react": {
|
"node_modules/react": {
|
||||||
"resolved": "../node_modules/react",
|
"resolved": "../node_modules/react",
|
||||||
"link": true
|
"link": true
|
||||||
@ -4350,6 +4360,12 @@
|
|||||||
"is-json": "^2.0.1"
|
"is-json": "^2.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"process": {
|
||||||
|
"version": "0.11.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
|
||||||
|
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"react": {
|
"react": {
|
||||||
"version": "file:../node_modules/react",
|
"version": "file:../node_modules/react",
|
||||||
"requires": {
|
"requires": {
|
||||||
|
@ -8,14 +8,15 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"react": "file:../node_modules/react",
|
"react": "file:../node_modules/react",
|
||||||
"react-dom": "file:../node_modules/react-dom",
|
"react-component-form": "file:..",
|
||||||
"react-component-form": "file:.."
|
"react-dom": "file:../node_modules/react-dom"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@parcel/transformer-image": "2.7.0",
|
"@parcel/transformer-image": "2.7.0",
|
||||||
"@types/react": "18.0.17",
|
"@types/react": "18.0.17",
|
||||||
"@types/react-dom": "18.0.6",
|
"@types/react-dom": "18.0.6",
|
||||||
"parcel": "2.7.0",
|
"parcel": "2.7.0",
|
||||||
|
"process": "^0.11.10",
|
||||||
"typescript": "4.7.4"
|
"typescript": "4.7.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { useMemo, useState } from 'react'
|
import { useMemo, useState } from 'react'
|
||||||
import { Static, TObject, TProperties, Type } from '@sinclair/typebox'
|
import { SchemaOptions, Static, TObject, Type } from '@sinclair/typebox'
|
||||||
import type { ErrorObject } from 'ajv'
|
import type { ErrorObject } from 'ajv'
|
||||||
|
|
||||||
import type { HandleForm } from '../components/Form'
|
import type { HandleForm } from '../components/Form'
|
||||||
@ -8,19 +8,21 @@ import { ajv } from '../utils/ajv'
|
|||||||
import { handleCheckboxBoolean } from '../utils/handleCheckboxBoolean'
|
import { handleCheckboxBoolean } from '../utils/handleCheckboxBoolean'
|
||||||
import { handleOptionalEmptyStringToNull } from '../utils/handleOptionalEmptyStringToNull'
|
import { handleOptionalEmptyStringToNull } from '../utils/handleOptionalEmptyStringToNull'
|
||||||
|
|
||||||
|
export type Schema = SchemaOptions
|
||||||
|
|
||||||
export type Error = ErrorObject
|
export type Error = ErrorObject
|
||||||
|
|
||||||
export type ErrorsObject<K extends TProperties> = {
|
export type ErrorsObject<K extends Schema> = {
|
||||||
[key in keyof Partial<K>]: Error[] | undefined
|
[key in keyof Partial<K>]: Error[] | undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
export type HandleSubmitCallback<K extends TProperties> = (
|
export type HandleUseFormCallback<K extends Schema> = (
|
||||||
formData: Static<TObject<K>>,
|
formData: Static<TObject<K>>,
|
||||||
formElement: HTMLFormElement
|
formElement: HTMLFormElement
|
||||||
) => Promise<Message<K> | null>
|
) => Promise<Message<K> | null> | Message<K> | null
|
||||||
|
|
||||||
export type HandleSubmit<K extends TProperties> = (
|
export type HandleUseForm<K extends Schema> = (
|
||||||
callback: HandleSubmitCallback<K>
|
callback?: HandleUseFormCallback<K>
|
||||||
) => HandleForm
|
) => HandleForm
|
||||||
|
|
||||||
export interface GlobalMessage {
|
export interface GlobalMessage {
|
||||||
@ -29,18 +31,16 @@ export interface GlobalMessage {
|
|||||||
properties?: undefined
|
properties?: undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PropertiesMessage<K extends TProperties> {
|
export interface PropertiesMessage<K extends Schema> {
|
||||||
type: 'error'
|
type: 'error'
|
||||||
value?: string
|
value?: string
|
||||||
properties: { [key in keyof Partial<K>]: string }
|
properties: { [key in keyof Partial<K>]: string }
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Message<K extends TProperties> =
|
export type Message<K extends Schema> = GlobalMessage | PropertiesMessage<K>
|
||||||
| GlobalMessage
|
|
||||||
| PropertiesMessage<K>
|
|
||||||
|
|
||||||
export interface UseFormResult<K extends TProperties> {
|
export interface UseFormResult<K extends Schema> {
|
||||||
handleSubmit: HandleSubmit<K>
|
handleUseForm: HandleUseForm<K>
|
||||||
|
|
||||||
readonly fetchState: FetchState
|
readonly fetchState: FetchState
|
||||||
setFetchState: React.Dispatch<React.SetStateAction<FetchState>>
|
setFetchState: React.Dispatch<React.SetStateAction<FetchState>>
|
||||||
@ -61,7 +61,7 @@ export interface UseFormResult<K extends TProperties> {
|
|||||||
readonly errors: ErrorsObject<K>
|
readonly errors: ErrorsObject<K>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useForm = <K extends TProperties>(
|
export const useForm = <K extends Schema>(
|
||||||
validationSchema: K
|
validationSchema: K
|
||||||
): UseFormResult<typeof validationSchema> => {
|
): UseFormResult<typeof validationSchema> => {
|
||||||
const validationSchemaObject = useMemo(() => {
|
const validationSchemaObject = useMemo(() => {
|
||||||
@ -78,7 +78,7 @@ export const useForm = <K extends TProperties>(
|
|||||||
return ajv.compile(validationSchemaObject)
|
return ajv.compile(validationSchemaObject)
|
||||||
}, [validationSchemaObject])
|
}, [validationSchemaObject])
|
||||||
|
|
||||||
const handleSubmit: HandleSubmit<typeof validationSchema> = (callback) => {
|
const handleUseForm: HandleUseForm<typeof validationSchema> = (callback) => {
|
||||||
return async (formData, formElement) => {
|
return async (formData, formElement) => {
|
||||||
setErrors({} as any)
|
setErrors({} as any)
|
||||||
setMessage(null)
|
setMessage(null)
|
||||||
@ -103,6 +103,7 @@ export const useForm = <K extends TProperties>(
|
|||||||
setErrors(errors)
|
setErrors(errors)
|
||||||
} else {
|
} else {
|
||||||
setErrors({} as any)
|
setErrors({} as any)
|
||||||
|
if (callback != null) {
|
||||||
setFetchState('loading')
|
setFetchState('loading')
|
||||||
const message = await callback(
|
const message = await callback(
|
||||||
formData as Static<TObject<typeof validationSchema>>,
|
formData as Static<TObject<typeof validationSchema>>,
|
||||||
@ -122,7 +123,8 @@ export const useForm = <K extends TProperties>(
|
|||||||
message: properties[property],
|
message: properties[property],
|
||||||
instancePath: `/${property}`,
|
instancePath: `/${property}`,
|
||||||
schemaPath: `#/properties/${property}/message`,
|
schemaPath: `#/properties/${property}/message`,
|
||||||
params: {}
|
params: {},
|
||||||
|
data: formData[property]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -132,9 +134,10 @@ export const useForm = <K extends TProperties>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
handleSubmit,
|
handleUseForm,
|
||||||
fetchState,
|
fetchState,
|
||||||
setFetchState,
|
setFetchState,
|
||||||
message,
|
message,
|
||||||
|
@ -3,7 +3,8 @@ import Ajv from 'ajv'
|
|||||||
|
|
||||||
export const ajv = addFormats(
|
export const ajv = addFormats(
|
||||||
new Ajv({
|
new Ajv({
|
||||||
allErrors: true
|
allErrors: true,
|
||||||
|
verbose: true
|
||||||
}),
|
}),
|
||||||
[
|
[
|
||||||
'date-time',
|
'date-time',
|
||||||
|
Reference in New Issue
Block a user