Skip to content

Commit

Permalink
forms module
Browse files Browse the repository at this point in the history
  • Loading branch information
kuroidoruido committed May 27, 2024
1 parent 38d6f5c commit 7b6f419
Show file tree
Hide file tree
Showing 78 changed files with 9,886 additions and 3 deletions.
Binary file added docs/assets/images/formik.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/images/react-hook-form.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions docs/markdown/07-formulaires/10-vanilla.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<!-- .slide: class="transition bg-pink" -->

# Basis
72 changes: 72 additions & 0 deletions docs/markdown/07-formulaires/11-field.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<!-- .slide: class="with-code" -->

# One input form

```TypeScript
function MyForm() {
return <input />;
}
```

<!-- .element: class="big-code" -->

##==##

<!-- .slide: class="with-code" -->

# One input form

With initial value

```TypeScript
type MyFormProps = { initialValue?: string }

function MyForm({ initialValue = '' }: MyFormProps) {
return <input defaultValue={initialValue} />;
}
```

<!-- .element: class="big-code" -->

##==##

<!-- .slide: class="with-code" -->

# One input form

Follow the value change

```TypeScript [4,5,6]
type MyFormProps = { initialValue?: string }

function MyForm({ initialValue = '' }: MyFormProps) {
const [value, setValue] = useState(initialValue);
const handleChange=(event: ChangeEvent<HtmlInputElement>) => setValue(event.target.value);
return <input defaultValue={initialValue} onChange={handleChange} />;
}
```

<!-- .element: class="big-code" -->

##==##

<!-- .slide: class="with-code" -->

# One input form

Give access to the state change

```TypeScript [1,3,7]
type MyFormProps = { initialValue?: string, onChange: ({ input: string }) => void }

function MyForm({ initialValue = '', onChange }: MyFormProps) {
const [value, setValue] = useState(initialValue);
const handleChange = (event: ChangeEvent<HtmlInputElement>) => {
setValue(event.target.value);
onChange({ input: event.target.value });
};
return <input defaultValue={initialValue} onChange={handleChange} />;
}
```

<!-- .element: class="big-code" -->
90 changes: 90 additions & 0 deletions docs/markdown/07-formulaires/12-form.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<!-- .slide: class="with-code" -->

# With form context

```TypeScript [9,11]
type MyFormProps = { initialValue?: string, onChange: ({ input: string }) => void }

function MyForm({ initialValue = '', onChange }: MyFormProps) {
const [value, setValue] = useState(initialValue);
const handleChange = (event: ChangeEvent<HtmlInputElement>) => {
setValue(event.target.value);
onChange({ input: event.target.value });
};
return <form>
<input defaultValue={initialValue} onChange={handleChange} />
</form>;
}
```

<!-- .element: class="big-code" -->

##==##

<!-- .slide: class="with-code" -->

# With submit button

```TypeScript [3,4,7,9]
type MyFormProps = {
initialValue?: string, onChange: ({ input: string }) => void,
onSubmit: ({ input: string }) => void }
function MyForm({ initialValue = '', onChange, onSubmit }: MyFormProps) {
const [value, setValue] = useState(initialValue);
const handleChange = (event: ChangeEvent<HtmlInputElement>) => { /* ... */ };
return <form onSubmit={() => onSubmit({ input: event.target.value })}>
<input defaultValue={initialValue} onChange={handleChange} />
<button type="submit">Send</button>
</form>;
}
```

<!-- .element: class="big-code" -->

##==##

<!-- .slide: class="with-code" -->

# Full form

```TypeScript
type InputProps = { defaultValue?: string, onChange: ({ input: string }) => void, name: string }

function Input({ name, defaultValue = '', onChange }: InputProps) {
const handleChange = (event: ChangeEvent<HtmlInputElement>) => {
onChange(event.target.value);
}
return <input name={name} defaultValue={defaultValue} onChange={handleChange} />;
}
```

<!-- .element: class="big-code" -->

##==##

<!-- .slide: class="with-code" -->

# Full form

```TypeScript
type MyFormValues = { firstname: string; lastname: string; }
type MyFormProps = { initialValue?: Partial<MyFormValues>, onSubmit: (state: MyFormValues) => void }
```
<!-- .element: class="big-code" -->
```TypeScript
function MyForm({ initialValue = {}, onSubmit }: MyFormProps) {
const [values, setValues] = useState<MyFormValues>({ firstname: '', lastname: '', ...initialValue });
const handleChange = (name: string) => (newValue: string) => {
setValues({ ...values, [name]: newValue });
}
return <form onSubmit={() => onSubmit(values)}>
<Input name="firstname" defaultValue={values.firstname} onChange={handleChange('firstname')} />;
<Input name="lastname" defaultValue={values.lastname} onChange={handleChange('lastname')} />;
<button type="submit">Save</button>
</form>
}
```

<!-- .element: class="big-code" -->
34 changes: 34 additions & 0 deletions docs/markdown/07-formulaires/20-uncontrolled.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!-- .slide: class="transition bg-pink" -->

# Uncontrolled VS Controlled

##==##

<!-- .slide: class="quote-slide" -->

<blockquote>
<cite>
It is common to call a component with some local state “uncontrolled”.
</cite>
</blockquote>

##==##

<!-- .slide: class="with-code" -->

# Uncontrolled

```TypeScript
type InputProps = { defaultValue?: string, onChange: ({ input: string }) => void, name: string }

function Input({ name, defaultValue = '', onChange }: InputProps) {
const [value, setValue] = useState(defaultValue);
const handleChange = (event: ChangeEvent<HtmlInputElement>) => {
setValue(event.target.value);
onChange(event.target.value);
}
return <input name={name} value={value} onChange={handleChange} />;
}
```

<!-- .element: class="big-code" -->
26 changes: 26 additions & 0 deletions docs/markdown/07-formulaires/21-controlled.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!-- .slide: class="quote-slide" -->

<blockquote>
<cite>
You might say a component is “controlled” when the important information in it is driven by props rather than its own local state.
</cite>
</blockquote>

##==##

<!-- .slide: class="with-code" -->

# Controlled

```TypeScript
type InputProps = { value?: string, onChange: ({ input: string }) => void, name: string }

function Input({ name, value = '', onChange }: InputProps) {
const handleChange = (event: ChangeEvent<HtmlInputElement>) => {
onChange(event.target.value);
}
return <input name={name} value={defaultValue} onChange={handleChange} />;
}
```

<!-- .element: class="big-code" -->
26 changes: 26 additions & 0 deletions docs/markdown/07-formulaires/22-uncontroller-vs-controlled.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!-- .slide: class="with-code" -->

# Controlled or uncontrolled?

```TypeScript
type InputProps = { defaultValue?: string, onChange: ({ input: string }) => void, name: string }

function Input({ name, defaultValue = '', onChange }: InputProps) {
const handleChange = (event: ChangeEvent<HtmlInputElement>) => {
onChange(event.target.value);
}
return <input name={name} defaultValue={defaultValue} onChange={handleChange} />;
}
```

<!-- .element: class="big-code" -->

##==##

<!-- .slide: class="quote-slide" -->

<blockquote>
<cite>
In practice, “controlled” and “uncontrolled” aren’t strict technical terms—each component usually has some mix of both local state and props. However, this is a useful way to talk about how components are designed and what capabilities they offer.
</cite>
</blockquote>
87 changes: 87 additions & 0 deletions docs/markdown/07-formulaires/30-react-hook-form.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<!-- .slide: class="transition bg-pink" -->

# React Hook Form

##==##

![center](./assets/images/react-hook-form.png)

[https://react-hook-form.com/](https://react-hook-form.com/)

##==##

<!-- .slide: class="with-code" -->

# Before react-hook-form

```TypeScript
type MyFormValues = { firstname: string; lastname: string; }
type MyFormProps = { initialValue?: Partial<MyFormValues>, onSubmit: (state: MyFormValues) => void }
```
<!-- .element: class="big-code" -->
```TypeScript
function MyForm({ initialValue = {}, onSubmit }: MyFormProps) {
const [values, setValues] = useState<MyFormValues>({ firstname: '', lastname: '', ...initialValue });
const handleChange = (name: string) => (newValue: string) => {
setValues({ ...values, [name]: newValue });
}
return <form onSubmit={() => onSubmit(values)}>
<input name="firstname" defaultValue={values.firstname} onChange={handleChange('firstname')} />;
<input name="lastname" defaultValue={values.lastname} onChange={handleChange('lastname')} />;
<button type="submit">Save</button>
</form>
}
```

<!-- .element: class="big-code" -->

##==##

<!-- .slide: class="with-code" -->

# With react-hook-form

```TypeScript [1|3,4|3,6-7|3,5|3,8|]
import { useForm } from 'react-hook-form';
function MyForm({ initialValue = {}, onSubmit }: MyFormProps) {
const { register, formState: { errors }, handleSubmit } = useForm<MyFormValues>({
defaultValues:initialValue });
return <form onSubmit={handleSubmit(onSubmit)}>
<input {...register("firstname")} />;
<input {...register("lastname"), { required: true }} />;
{errors.lastnameRequired && <span>Lastname field is required</span>}
<button type="submit">Save</button>
</form>
}
```
<!-- .element: class="big-code" -->
##==##
<!-- .slide: class="with-code" -->
# Watch
```TypeScript [4,6-8]
import { useForm, SubmitHandler } from 'react-hook-form';

function MyForm({ initialValue = {}, onSubmit }: MyFormProps) {
const { register, formState: { errors }, handleSubmit, watch } = useForm<MyFormValues>({
defaultValues:initialValue });
const firstname = watch('firstname');
const values = watch();
console.log('form values', { firstname, values });
const onSubmit: SubmitHandler<Inputs> = onSubmit;
return <form onSubmit={handleSubmit(onSubmit)}>
<input {...register("firstname")} />;
<input {...register("lastname"), { required: true }} />;
{errors.lastnameRequired && <span>Lastname field is required</span>}
<button type="submit">Save</button>
</form>
}
```

<!-- .element: class="big-code" -->
Loading

0 comments on commit 7b6f419

Please sign in to comment.