Skip to content

Commit 4a420ed

Browse files
authored
docs(form): add more informations in readme (#5307)
* docs(form): add more informations in readme * docs: add form validation doc
1 parent 21a6194 commit 4a420ed

File tree

1 file changed

+192
-4
lines changed

1 file changed

+192
-4
lines changed

packages/form/README.md

Lines changed: 192 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ It is using [React Hook Form](https://react-hook-form.com/) under the hood.
88
## Get Started
99

1010
```sh
11-
$ pnpm add @ultraviolet/form @emotion/react @emotion/styled
11+
$ pnpm add @ultraviolet/ui @ultraviolet/form @emotion/react @emotion/styled
1212
```
1313

1414
### Usage
@@ -21,18 +21,206 @@ import { Form, TextInputField } from '@ultraviolet/form'
2121
import { theme } from '@ultraviolet/ui'
2222
import { useForm } from '@ultraviolet/form'
2323

24+
// Here are the input types of your form
25+
type FormValues = {
26+
firstName: string
27+
lastName: string
28+
}
29+
30+
// We define the initial values of the form
31+
const INITIAL_VALUES: FormValues = {
32+
firstName: 'Marc',
33+
lastName: 'Scout',
34+
} as const
35+
36+
export default function App() {
37+
const methods = useForm<FormValues>({
38+
defaultValues: INITIAL_VALUES,
39+
mode: 'onChange',
40+
})
41+
42+
const formErrors = {
43+
required: () => 'This field is required',
44+
// Add more error messages as needed for min, max, etc.
45+
}
46+
47+
const onSubmit = async ({
48+
firstName,
49+
lastName,
50+
}: FormValues) => {
51+
// Add your form submission logic here
52+
console.log('Form submitted with values:', { firstName, lastName })
53+
}
54+
55+
return (
56+
<ThemeProvider theme={theme}>
57+
<Form methods={methods} errors={formErrors} onSubmit={onSubmit}>
58+
<TextInputField name="firstName" />
59+
<TextInputField name="lastName" />
60+
</Form>
61+
</ThemeProvider>
62+
)
63+
}
64+
```
65+
66+
### `useWatch` Hook
67+
68+
You can use the `useWatch` hook from `@ultraviolet/form` to watch specific fields in your form thus subscribing to their changes.
69+
It can be useful for displaying real-time updates or triggering actions based on field values.
70+
71+
```tsx
72+
// FirstNameWatched is a component that needs to watch the firstName field
73+
function FirstNameWatched({ control }: { control: Control<FormInputs> }) {
74+
const firstName = useWatch({
75+
control,
76+
name: "firstName",
77+
})
78+
79+
return <p>Watch: {firstName}</p>
80+
}
81+
2482
export default function App() {
25-
const methods = useForm()
83+
... // same setup as before
84+
2685
return (
2786
<ThemeProvider theme={theme}>
28-
<Form methods={methods}>
29-
<TextInputField name="example" />
87+
<Form methods={methods} errors={formErrors} onSubmit={onSubmit}>
88+
<TextInputField name="firstName" />
89+
<TextInputField name="lastName" />
90+
91+
<FirstNameWatched control={control} />
3092
</Form>
3193
</ThemeProvider>
3294
)
3395
}
3496
```
3597

98+
### Form Validation
99+
100+
You can validate each fields passing either `regex` or `validate` to any field that support it. Not all field supports `regex` for instance but all fields support `validate`.
101+
In addition many field support `required`, `minLength`, `maxLength`, `min`, and `max` validation.
102+
103+
#### Native Validation
104+
105+
```tsx
106+
<TextInputField
107+
name="firstName"
108+
required
109+
minLength={2}
110+
maxLength={30}
111+
/>
112+
```
113+
114+
#### With Validate
115+
116+
```tsx
117+
const EXISTING_IPS = ['192.168.1.1']
118+
119+
<TextInputField
120+
name="ip"
121+
validate={{
122+
ipAlreadyExists: (ip: string) =>
123+
EXISTING_IPS.includes(ip) ? 'This ip is already in use' : undefined,
124+
}}
125+
/>
126+
```
127+
128+
#### With Regex
129+
130+
```tsx
131+
<TextInputField
132+
name="email"
133+
regex={[/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/]}
134+
/>
135+
```
136+
137+
We all know regex can be tricky, so to help you with that we made [Scaleway Regex](https://github.com/scaleway/scaleway-lib/tree/main/packages/regex) library that contains a lot of useful regexes that you can use in your forms.
138+
You can easily install it with:
139+
140+
```sh
141+
pnpm add @scaleway/regex
142+
```
143+
144+
You can then use it like this:
145+
146+
```tsx
147+
import { email } from '@scaleway/regex'
148+
149+
<TextInputField
150+
name="email"
151+
regex={[email]}
152+
/>
153+
```
154+
155+
Check all the available regexes in the [Scaleway Regex file](https://github.com/scaleway/scaleway-lib/blob/main/packages/regex/src/index.ts)
156+
157+
### Resolvers | Zod
158+
159+
You can use [Zod](https://zod.dev/) for validation by integrating it with `@ultraviolet/form`. First you will need to install Zod and the Zod resolver for React Hook Form:
160+
161+
```sh
162+
pnpm add zod @hookform/resolvers
163+
```
164+
165+
166+
Here's how you can do it:
167+
168+
```tsx
169+
import { ThemeProvider } from '@emotion/react'
170+
import { Form, TextInputField } from '@ultraviolet/form'
171+
import { theme } from '@ultraviolet/ui'
172+
import { useForm } from '@ultraviolet/form'
173+
import { zodResolver } from "@hookform/resolvers/zod"
174+
import * as z from "zod"
175+
176+
// Define your Zod schema for validation
177+
const schema = z.object({
178+
firstName: z.string(),
179+
lastName: z.string(),
180+
})
181+
182+
// Types are inferred from the Zod schema
183+
type FormValues = z.infer<typeof schema>
184+
185+
// We define the initial values of the form
186+
const INITIAL_VALUES: FormValues = {
187+
firstName: 'Marc',
188+
lastName: 'Scout',
189+
} as const
190+
191+
export default function App() {
192+
const methods = useForm<FormValues>({
193+
defaultValues: INITIAL_VALUES,
194+
resolver: zodResolver(schema),
195+
mode: 'onChange',
196+
})
197+
198+
const formErrors = {
199+
required: () => 'This field is required',
200+
// Add more error messages as needed for min, max, etc.
201+
}
202+
203+
const onSubmit = async ({
204+
firstName,
205+
lastName,
206+
}: FormValues) => {
207+
// Add your form submission logic here
208+
console.log('Form submitted with values:', { firstName, lastName })
209+
}
210+
211+
return (
212+
<ThemeProvider theme={theme}>
213+
<Form methods={methods} errors={formErrors} onSubmit={onSubmit}>
214+
<TextInputField name="firstName" />
215+
<TextInputField name="lastName" />
216+
</Form>
217+
</ThemeProvider>
218+
)
219+
}
220+
```
221+
222+
If you need more examples with other resolvers we invite you to check [React Hook Form Resolvers Documentation](https://github.com/react-hook-form/resolvers#quickstart)
223+
36224
## Documentation
37225

38226
Checkout our [documentation website](https://storybook.ultraviolet.scaleway.com/).

0 commit comments

Comments
 (0)