nextui/packages/components/checkbox/stories/checkbox-group.stories.tsx
Ryo Matsukawa 540aa2124b
feat: switch default validationBehavior to aria and allow switching via props (#2987)
* chore: add support validationBehavior aria

* chore: add validationBehavior to Provider

* chore: add autocomplete validation test

* chore: add checkbox validation test

* fix(input): require condition

* docs: add description of validationBehavior props

* chore: add support validationBehavior props for date components

* docs(dates): add description of validationBehavior props

* chore: add changeset

* chore: format

* chore: fix test

* fix: select validationBehavior is not support yet

* fix: select validationBehavior not supported yet

* chore(docs): validation behavior prop added to nextui-provider

---------

Co-authored-by: Junior Garcia <jrgarciadev@gmail.com>
2024-05-22 17:50:39 -03:00

273 lines
5.9 KiB
TypeScript

import type {ValidationResult} from "@react-types/shared";
import React from "react";
import {Meta} from "@storybook/react";
import {checkbox} from "@nextui-org/theme";
import {button} from "@nextui-org/theme";
import {CheckboxGroup, Checkbox, CheckboxGroupProps} from "../src";
export default {
title: "Components/CheckboxGroup",
component: CheckboxGroup,
argTypes: {
color: {
control: {
type: "select",
},
options: ["default", "primary", "secondary", "success", "warning", "danger"],
},
radius: {
control: {
type: "select",
},
options: ["none", "sm", "md", "lg", "full"],
},
size: {
control: {
type: "select",
},
options: ["sm", "md", "lg"],
},
lineThrough: {
control: {
type: "boolean",
},
},
isDisabled: {
control: {
type: "boolean",
},
},
validationBehavior: {
control: {
type: "select",
},
options: ["aria", "native"],
},
},
} as Meta<typeof Checkbox>;
const defaultProps = {
...checkbox.defaultVariants,
};
const Template = (args: CheckboxGroupProps) => (
<CheckboxGroup {...args}>
<Checkbox value="buenos-aires">Buenos Aires</Checkbox>
<Checkbox value="sydney">Sydney</Checkbox>
<Checkbox value="san-francisco">San Francisco</Checkbox>
<Checkbox value="london">London</Checkbox>
<Checkbox value="tokyo">Tokyo</Checkbox>
</CheckboxGroup>
);
const InvalidTemplate = (args: CheckboxGroupProps) => {
const [isInvalid, setIsInvalid] = React.useState(true);
return (
<>
<CheckboxGroup
{...args}
isRequired
description="Select the cities you want to visit"
isInvalid={isInvalid}
label="Select cities"
onValueChange={(value) => {
setIsInvalid(value.length < 1);
}}
>
<Checkbox value="buenos-aires">Buenos Aires</Checkbox>
<Checkbox value="sydney">Sydney</Checkbox>
<Checkbox value="san-francisco">San Francisco</Checkbox>
<Checkbox value="london">London</Checkbox>
<Checkbox value="tokyo">Tokyo</Checkbox>
</CheckboxGroup>
</>
);
};
const FormTemplate = (args: CheckboxGroupProps) => {
return (
<form
className="flex flex-col items-start gap-4"
onSubmit={(e) => {
const formData = new FormData(e.currentTarget);
const selectedCities = formData.getAll("favorite-cities");
alert(`Submitted values: ${selectedCities.join(", ")}`);
e.preventDefault();
}}
>
<CheckboxGroup {...args} label="Select cities" name="favorite-cities">
<Checkbox value="buenos-aires">Buenos Aires</Checkbox>
<Checkbox value="sydney">Sydney</Checkbox>
<Checkbox value="san-francisco">San Francisco</Checkbox>
<Checkbox value="london">London</Checkbox>
<Checkbox value="tokyo">Tokyo</Checkbox>
</CheckboxGroup>
<button className={button({color: "primary"})} type="submit">
Submit
</button>
</form>
);
};
const ControlledTemplate = (args: CheckboxGroupProps) => {
const [selected, setSelected] = React.useState<string[]>(["buenos-aires"]);
React.useEffect(() => {
// eslint-disable-next-line no-console
console.log("Checkbox ", selected);
}, [selected]);
return (
<div className="flex flex-col gap-2">
<CheckboxGroup {...args} label="Select cities" value={selected} onValueChange={setSelected}>
<Checkbox value="buenos-aires">Buenos Aires</Checkbox>
<Checkbox value="sydney">Sydney</Checkbox>
<Checkbox value="san-francisco">San Francisco</Checkbox>
<Checkbox value="london">London</Checkbox>
<Checkbox value="tokyo">Tokyo</Checkbox>
</CheckboxGroup>
<p className="text-default-500">Selected: {selected.join(", ")}</p>
</div>
);
};
export const Default = {
render: Template,
args: {
...defaultProps,
},
};
export const WithLabel = {
render: Template,
args: {
label: "Select cities",
},
};
export const DefaultValue = {
render: Template,
args: {
...defaultProps,
label: "Select cities",
defaultValue: ["buenos-aires", "london"],
},
};
export const Controlled = {
render: ControlledTemplate,
args: {
...defaultProps,
},
};
export const Horizontal = {
render: Template,
args: {
label: "Select cities",
orientation: "horizontal",
},
};
export const IsDisabled = {
render: Template,
args: {
label: "Select cities",
isDisabled: true,
},
};
export const LineThrough = {
render: Template,
args: {
label: "Select cities",
lineThrough: true,
},
};
export const WithDescription = {
render: Template,
args: {
...defaultProps,
description: "Select the cities you want to visit",
},
};
export const IsInvalid = {
render: InvalidTemplate,
args: {
...defaultProps,
},
};
export const WithErrorMessage = {
render: Template,
args: {
...defaultProps,
isInvalid: true,
errorMessage: "The selected cities cannot be visited at the same time",
},
};
export const WithErrorMessageFunction = {
render: FormTemplate,
args: {
...defaultProps,
isRequired: true,
errorMessage: (value: ValidationResult) => {
if (value.validationDetails.valueMissing) {
return "At least one option must be selected";
}
},
},
};
export const WithValidation = {
render: FormTemplate,
args: {
...defaultProps,
description: "Please select at least 2 options",
validate: (value: string[]) => {
if (value.length < 2) {
return "You must select at least 2 options";
}
return null;
},
},
};
export const DisableAnimation = {
render: Template,
args: {
label: "Select cities",
disableAnimation: true,
},
};
export const IsRequired = {
render: FormTemplate,
args: {
...defaultProps,
isRequired: true,
},
};