Skip to content

Commit

Permalink
feat: add field checkbox and fieldswitch
Browse files Browse the repository at this point in the history
update their theme
  • Loading branch information
yoannfleurydev committed Jul 22, 2024
1 parent 74de78b commit 0b07555
Show file tree
Hide file tree
Showing 10 changed files with 703 additions and 2 deletions.
135 changes: 135 additions & 0 deletions src/components/Form/FieldCheckbox/FieldCheckbox.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { FormLabel } from '@chakra-ui/react';
import { expect, test, vi } from 'vitest';
import { z } from 'zod';

import { render, screen, setupUser } from '@/tests/utils';

import { FormField } from '../FormField';
import { FormFieldController } from '../FormFieldController';
import { FormMocked } from '../form-test-utils';

test('update value', async () => {
const user = setupUser();
const mockedSubmit = vi.fn();

render(
<FormMocked
schema={z.object({
doit: z.boolean().default(false),
})}
onSubmit={mockedSubmit}
>
{({ form }) => (
<FormField>
<FormLabel>Should I do something?</FormLabel>
<FormFieldController
type="checkbox"
control={form.control}
name="doit"
checkboxProps={{
children: 'Yes, do it!',
}}
/>
</FormField>
)}
</FormMocked>
);
await user.click(screen.getByLabelText('Should I do something?'));
await user.click(screen.getByRole('button', { name: 'Submit' }));
expect(mockedSubmit).toHaveBeenCalledWith({ doit: true });
});

test('double click', async () => {
const user = setupUser();
const mockedSubmit = vi.fn();

render(
<FormMocked
schema={z.object({
doit: z.boolean().default(false),
})}
onSubmit={mockedSubmit}
>
{({ form }) => (
<FormField>
<FormLabel>Should I do something?</FormLabel>
<FormFieldController
type="checkbox"
control={form.control}
name="doit"
checkboxProps={{
children: 'Yes, do it!',
}}
/>
</FormField>
)}
</FormMocked>
);
await user.click(screen.getByLabelText('Should I do something?'));
await user.click(screen.getByLabelText('Should I do something?'));
await user.click(screen.getByRole('button', { name: 'Submit' }));
expect(mockedSubmit).toHaveBeenCalledWith({ doit: false });
});

test('default value', async () => {
const user = setupUser();
const mockedSubmit = vi.fn();

render(
<FormMocked
schema={z.object({
doit: z.boolean().default(false),
})}
useFormOptions={{ defaultValues: { doit: true } }}
onSubmit={mockedSubmit}
>
{({ form }) => (
<FormField>
<FormLabel>Should I do something?</FormLabel>
<FormFieldController
type="checkbox"
control={form.control}
name="doit"
checkboxProps={{
children: 'Yes, do it!',
}}
/>
</FormField>
)}
</FormMocked>
);
await user.click(screen.getByLabelText('Should I do something?'));
await user.click(screen.getByRole('button', { name: 'Submit' }));
expect(mockedSubmit).toHaveBeenCalledWith({ doit: false });
});

test('disabled', async () => {
const user = setupUser();
const mockedSubmit = vi.fn();

render(
<FormMocked
schema={z.object({
doit: z.boolean().default(false),
})}
useFormOptions={{ defaultValues: { doit: false } }}
onSubmit={mockedSubmit}
>
{({ form }) => (
<FormField>
<FormLabel>Should I do something?</FormLabel>
<FormFieldController
type="checkbox"
control={form.control}
name="doit"
isDisabled
checkboxProps={{ children: 'Yes, do it!' }}
/>
</FormField>
)}
</FormMocked>
);
await user.click(screen.getByLabelText('Should I do something?'));
await user.click(screen.getByRole('button', { name: 'Submit' }));
expect(mockedSubmit).toHaveBeenCalledWith({ doit: false });
});
143 changes: 143 additions & 0 deletions src/components/Form/FieldCheckbox/docs.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import { Box, Button, Stack } from '@chakra-ui/react';
import { useForm } from 'react-hook-form';
import { z } from 'zod';

import {
Form,
FormField,
FormFieldController,
FormFieldHelper,
FormFieldLabel,
} from '../';

export default {
title: 'Form/FieldCheckbox',
};

type FormSchema = z.infer<ReturnType<typeof zFormSchema>>;
const zFormSchema = () =>
z.object({
doit: z.boolean().default(false),
});

export const Default = () => {
const form = useForm<FormSchema>();

return (
<Form {...form} onSubmit={(values) => console.log(values)}>
<Stack spacing={4}>
<FormField>
<FormFieldLabel>Should I do something?</FormFieldLabel>
<FormFieldController
control={form.control}
type="checkbox"
name="doit"
checkboxProps={{
children: 'Yes, do it!',
}}
/>
<FormFieldHelper>Helper</FormFieldHelper>
</FormField>
<Box>
<Button type="submit" variant="@primary">
Submit
</Button>
</Box>
</Stack>
</Form>
);
};

export const DefaultValues = () => {
const form = useForm<FormSchema>({
defaultValues: {
doit: true,
},
});

return (
<Form {...form} onSubmit={(values) => console.log(values)}>
<Stack spacing={4}>
<FormField>
<FormFieldLabel>Should I do something?</FormFieldLabel>
<FormFieldController
control={form.control}
type="checkbox"
name="doit"
checkboxProps={{
children: 'Yes, do it!',
}}
/>
<FormFieldHelper>Helper</FormFieldHelper>
</FormField>
<Box>
<Button type="submit" variant="@primary">
Submit
</Button>
</Box>
</Stack>
</Form>
);
};

export const Disabled = () => {
const form = useForm<FormSchema>();

return (
<Form {...form} onSubmit={(values) => console.log(values)}>
<Stack spacing={4}>
<FormField>
<FormFieldLabel>Should I do something?</FormFieldLabel>
<FormFieldController
control={form.control}
type="checkbox"
name="doit"
isDisabled
checkboxProps={{
children: 'Yes, do it!',
}}
/>
<FormFieldHelper>Helper</FormFieldHelper>
</FormField>
<Box>
<Button type="submit" variant="@primary">
Submit
</Button>
</Box>
</Stack>
</Form>
);
};

export const DisabledDefaultValues = () => {
const form = useForm<FormSchema>({
defaultValues: {
doit: true,
},
});

return (
<Form {...form} onSubmit={(values) => console.log(values)}>
<Stack spacing={4}>
<FormField>
<FormFieldLabel>Should I do something?</FormFieldLabel>
<FormFieldController
control={form.control}
type="checkbox"
name="doit"
isDisabled
checkboxProps={{
children: 'Yes, do it!',
}}
/>
<FormFieldHelper>Helper</FormFieldHelper>
</FormField>
<Box>
<Button type="submit" variant="@primary">
Submit
</Button>
</Box>
</Stack>
</Form>
);
};
51 changes: 51 additions & 0 deletions src/components/Form/FieldCheckbox/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Checkbox, CheckboxProps, Flex } from '@chakra-ui/react';
import {
Controller,
ControllerRenderProps,
FieldPath,
FieldValues,
} from 'react-hook-form';

import { FieldCommonProps } from '../FormFieldController';
import { FormFieldError } from '../FormFieldError';

export type CheckboxRootProps = Pick<CheckboxProps, 'size'>;

export type FieldCheckboxProps<
TFieldValues extends FieldValues = FieldValues,
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
> = {
type: 'checkbox';
checkboxProps?: RemoveFromType<
RemoveFromType<
Omit<CheckboxProps, 'isChecked' | 'isDisabled'>,
CheckboxRootProps
>,
ControllerRenderProps
>;
} & CheckboxRootProps &
FieldCommonProps<TFieldValues, TName>;

export const FieldCheckbox = <
TFieldValues extends FieldValues = FieldValues,
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
>(
props: FieldCheckboxProps<TFieldValues, TName>
) => {
return (
<Controller
{...props}
render={({ field: { value, ...field } }) => (
<Flex direction="column" gap={1.5}>
<Checkbox
isChecked={!!value}
isDisabled={props.isDisabled}
{...props.checkboxProps}
{...field}
/>
<FormFieldError />
</Flex>
)}
/>
);
};
Loading

0 comments on commit 0b07555

Please sign in to comment.