(react) react-hook-form Switch example

Our form elements needs to be usable with react-hook-form
This commit is contained in:
Romain Le Cellier
2023-07-26 16:52:38 +02:00
parent b72d0d5c90
commit e3bf4cadf2
3 changed files with 89 additions and 33 deletions

View File

@@ -99,6 +99,14 @@ In order to control the value of the switch, you can use the `checked` or `defau
<Story id="components-forms-switch--controlled"/> <Story id="components-forms-switch--controlled"/>
</Canvas> </Canvas>
## Usage with react-hook-form
You can use this input with [react-hook-form](https://react-hook-form.com/docs)
<Canvas sourceState="shown">
<Story id="components-forms-switch--react-hook-form"/>
</Canvas>
## Props ## Props
The props of this component are as close as possible to the native checkbox component. You can see the list of props below. The props of this component are as close as possible to the native checkbox component. You can see the list of props below.

View File

@@ -1,7 +1,15 @@
import { yupResolver } from "@hookform/resolvers/yup";
import { Meta } from "@storybook/react"; import { Meta } from "@storybook/react";
import { useForm } from "react-hook-form";
import * as Yup from "yup";
import React from "react"; import React from "react";
import { Switch } from ":/components/Forms/Switch/index"; import { Switch } from ":/components/Forms/Switch/index";
import { Button } from ":/components/Button"; import { Button } from ":/components/Button";
import {
getFieldState,
getFieldErrorMessage,
onSubmit,
} from ":/tests/reactHookFormUtils";
export default { export default {
title: "Components/Forms/Switch", title: "Components/Forms/Switch",
@@ -122,6 +130,49 @@ export const Controlled = {
}, },
}; };
export const ReactHookForm = () => {
interface SwitchExampleFormValues {
terms: boolean;
}
const switchExampleSchema = Yup.object().shape({
terms: Yup.boolean()
.required()
.oneOf([true], "You have to accept the terms of use"),
});
const { register, handleSubmit, formState } =
useForm<SwitchExampleFormValues>({
defaultValues: {
terms: false,
},
mode: "onChange",
reValidateMode: "onChange",
resolver: yupResolver(switchExampleSchema),
});
return (
<form
style={{
display: "flex",
flexDirection: "column",
gap: "1rem",
width: "400px",
}}
onSubmit={handleSubmit(onSubmit)}
>
<Switch
label="I accept the terms of use"
fullWidth
state={getFieldState("terms", formState)}
text={getFieldErrorMessage("terms", formState)}
{...register("terms")}
/>
<Button fullWidth={true}>Log-in</Button>
</form>
);
};
export const FormExample = { export const FormExample = {
render: () => { render: () => {
return ( return (

View File

@@ -1,4 +1,4 @@
import React, { InputHTMLAttributes } from "react"; import React, { InputHTMLAttributes, forwardRef } from "react";
import classNames from "classnames"; import classNames from "classnames";
import { Field, FieldProps } from ":/components/Forms/Field"; import { Field, FieldProps } from ":/components/Forms/Field";
@@ -8,36 +8,33 @@ type Props = InputHTMLAttributes<HTMLInputElement> &
labelSide?: "left" | "right"; labelSide?: "left" | "right";
}; };
export const Switch = ({ export const Switch = forwardRef<HTMLInputElement, Props>(
label, (
text, { label, text, state, fullWidth, labelSide = "left", ...props }: Props,
state, ref,
fullWidth, ) => {
labelSide = "left", return (
<label
...props className={classNames(
}: Props) => { "c__checkbox",
return ( "c__switch",
<label "c__switch--" + labelSide,
className={classNames( {
"c__checkbox", "c__checkbox--disabled": props.disabled,
"c__switch", "c__switch--full-width": fullWidth,
"c__switch--" + labelSide, },
{ )}
"c__checkbox--disabled": props.disabled, >
"c__switch--full-width": fullWidth, <Field text={text} compact={true} state={state} fullWidth={fullWidth}>
}, <div className="c__checkbox__container">
)} {label && <div className="c__checkbox__label">{label}</div>}
> <div className="c__switch__rail__wrapper">
<Field text={text} compact={true} state={state} fullWidth={fullWidth}> <input type="checkbox" {...props} ref={ref} />
<div className="c__checkbox__container"> <div className="c__switch__rail" />
{label && <div className="c__checkbox__label">{label}</div>} </div>
<div className="c__switch__rail__wrapper">
<input type="checkbox" {...props} />
<div className="c__switch__rail" />
</div> </div>
</div> </Field>
</Field> </label>
</label> );
); },
}; );