Skip to content
Snippets Groups Projects
Unverified Commit 38916190 authored by Oisin Coveney's avatar Oisin Coveney Committed by GitHub
Browse files

Mantine Checkbox (#32336)

parent 5509fa31
Branches jest-role-hidden
No related tags found
No related merge requests found
import { Canvas, Story, Meta } from "@storybook/addon-docs";
import { Checkbox } from "./";
<Meta title="Inputs/Checkbox & Checkbox Group" component={Checkbox} />
# Checkbox & Checkbox.Group
Our themed wrapper around [Mantine Checkbox](https://mantine.dev/core/checkbox/).
## When to use Checkbox
Checkbox buttons allow users to select a single option from a list of mutually exclusive options. All possible options are exposed up front for users to compare.
## Docs
- [Figma File](https://www.figma.com/file/sF1qSHk6yVqO1rFgmH0nzT/Input-%2F-Checkbox?type=design&node-id=1-96&t=4851xqAoQVenSrTX-11)
- [Mantine Checkbox Docs](https://mantine.dev/core/checkbox/)
## Caveats
- As of right now, don't use the size prop.
- Please don't use the `error` prop on Checkbox components (We'll standardize on this as other inputs get converted).
## Usage guidelines
- **Use this component if there are more than 5 options**. If there are fewer options, feel free to check out Checkbox or Select.
- For option ordering, try to use your best judgement on a sensible order. For example, Yes should come before No. Alphabetical ordering is usually a good fallback if there's no inherent order in your set of choices.
- In almost all circumstances you'll want to use `<Checkbox.Group>` to provide a set of options and help with defaultValues and state management between them.
## General
<Canvas>
<Story name="Default">
<Checkbox.Group defaultValue="yes">
<Checkbox label="Yes" value="yes" />
<Checkbox label="No" value="no" />
<Checkbox label="I'm not sure" indeterminate />
</Checkbox.Group>
</Story>
</Canvas>
## Disabled
<Canvas>
<Story name="Disabled">
<Checkbox.Group value={["yes"]}>
<Checkbox label="Yes" value="yes" disabled />
<Checkbox label="No" value="no" disabled />
<Checkbox label="I'm not sure" indeterminate disabled />
</Checkbox.Group>
</Story>
</Canvas>
## Description
If needed you can add a description value to a Checkbox button to give more context about the choice.
<Canvas>
<Story name="Descriptions">
<Checkbox.Group defaultValue={["chocolate"]}>
<Checkbox
label="Chocolate"
value="chocolate"
description="One of our most popular flavors"
/>
<Checkbox
label="Vanilla"
value="vanilla"
description="A classic for all seasons"
/>
<Checkbox
label="Strawberry, no description needed!"
value="strawberry"
/>
<Checkbox
label="Swirl"
value="swirl"
description="Why not have it both ways?"
/>
</Checkbox.Group>
</Story>
</Canvas>
## Using the Checkbox group props
You can use `label` and `description` on the Checkbox.Group component to provide a label and description for the set of choices.
<Canvas>
<Story name="Checkbox Group props">
<Checkbox.Group
label="A set of options"
description="You could so something like this if there was a deprecated setting that a user needs to update."
defaultValue={["one"]}
>
<Checkbox label="Old bad setting" value="one" disabled />
<Checkbox label="A better newer setting" value="two" />
</Checkbox.Group>
</Story>
</Canvas>
## Related components
- Select
- Checkbox
/* eslint-disable react/prop-types */
import type { CheckboxProps } from "@mantine/core";
import { Icon } from "metabase/core/components/Icon";
export const CheckboxIcon: CheckboxProps["icon"] = ({
indeterminate,
className,
}) => {
const iconName = indeterminate ? "dash" : "check";
return <Icon className={className} name={iconName} />;
};
export { Checkbox } from "@mantine/core";
export * from "./Radio";
export * from "./Checkbox";
import type { MantineThemeOverride } from "@mantine/core";
import { color } from "metabase/lib/colors";
import { CheckboxIcon } from "metabase/ui/components/inputs/Checkbox/CheckboxIcon";
export const theme: MantineThemeOverride = {
colors: {
......@@ -45,6 +46,71 @@ export const theme: MantineThemeOverride = {
};
},
},
Checkbox: {
defaultProps: {
icon: CheckboxIcon,
},
styles(theme, params) {
return {
root: {
marginBottom: theme.spacing.xs,
},
label: {
fontWeight: 700,
color: theme.colors.text[2],
[`padding${params.labelPosition === "left" ? "Right" : "Left"}`]:
theme.spacing.xs,
},
input: {
"&:focus": {
outline: `2px solid ${theme.colors.brand[1]}`,
},
"&:disabled": {
background: theme.colors.border[0],
border: 0,
"& + svg > *": {
fill: theme.colors.text[0],
},
},
cursor: "pointer",
...(params.indeterminate && {
background: theme.colors.brand[1],
border: `1px solid ${theme.colors.brand[1]}`,
}),
},
...(params.indeterminate && {
icon: {
"& > *": {
fill: color("white"),
},
},
}),
};
},
},
CheckboxGroup: {
styles(theme) {
/* Note: we need the ':has' selector to target the space just
* above the first checkbox since we don't seem to have selector
* or a way to use params to detect whether group label/description
* exists. This is a bit of a hack, but it works. */
return {
label: {
fontWeight: 700,
color: theme.colors.text[2],
"&:has(+ .mantine-Checkbox-root)": {
marginBottom: theme.spacing.sm,
},
},
description: {
"&:has(+ .mantine-Checkbox-root)": {
marginBottom: theme.spacing.sm,
},
},
};
},
},
Accordion: {
styles(theme) {
return {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment