Skip to content
Snippets Groups Projects
Unverified Commit d9aa16e2 authored by Emmad Usmani's avatar Emmad Usmani Committed by GitHub
Browse files

Mantine Switch (#34005)


* wip

* Add comma and fix spelling error

* Added some padding and things

* switch control styles

* text styles

* add storybook examples

* Add guidance text

* Add top padding for small switches

* change default size from `sm` to `md`

* fix missing default `size` prop

* fix paddings

* remove label padding if empty

* use `getStylesRef`

---------

Co-authored-by: default avatarOisin Coveney <oisin@metabase.com>
Co-authored-by: default avatarMaz Ameli <maz@metabase.com>
parent bfd51fd3
No related branches found
No related tags found
No related merge requests found
import { Canvas, Story, Meta } from "@storybook/addon-docs";
import { Switch, Stack } from "metabase/ui";
export const args = {
labelPosition: "right",
label: "Eat all the cheese",
description: undefined,
size: "md",
disabled: false,
};
export const argTypes = {
labelPosition: {
control: { type: "inline-radio" },
options: ["left", "right"],
},
label: {
control: { type: "text" },
},
description: {
control: { type: "text" },
},
size: {
control: { type: "inline-radio" },
options: ["xs", "sm", "md"],
},
disabled: {
control: { type: "boolean" },
},
};
<Meta
title="Inputs/Switch"
component={Switch}
args={args}
argTypes={argTypes}
/>
# Switch
Our themed wrapper around [Mantine Switch](https://mantine.dev/core/switch/).
## When to use Switch
Use Switch when you have a setting that can be only either on or off, or enabled/disabled. If there are multiple related options in a list that could be selected or chosen, use a checkbox group instead.
## Docs
- [Figma File](https://www.figma.com/file/xdNKMROC99J6Z4Sqg6V3JI/Input-%2F-Switch?type=design&node-id=1-96&mode=design&t=0K7GSP6rqj8M2muz-0)
- [Mantine Checkbox Docs](https://mantine.dev/core/switch/)
## Usage guidelines
In most situations you should use the `md` size variant, with the label on the left and the toggle on the right. (This allows users to read what the setting or option is first.)
## Examples
export const DefaultTemplate = args => <Switch {...args} />;
export const StateTemplate = args => (
<Stack>
<Switch {...args} label="Unchecked switch" checked={false} />
<Switch {...args} label="Checked switch" checked />
<Switch {...args} label="Disabled unchecked switch" disabled />
<Switch {...args} label="Disabled checked switch" disabled checked />
</Stack>
);
export const Default = DefaultTemplate.bind({});
<Canvas>
<Story name="Default">{Default}</Story>
</Canvas>
### Label
export const Label = StateTemplate.bind({});
<Canvas>
<Story name="Label">{Label}</Story>
</Canvas>
### Left label position
export const LabelLeft = StateTemplate.bind({});
LabelLeft.args = {
labelPosition: "left",
};
<Canvas>
<Story name="Label, left position" args={LabelLeft.args}>
{LabelLeft}
</Story>
</Canvas>
### Description
export const Description = StateTemplate.bind({});
Description.args = {
description: "Every type of cheese will be consumed, regardless of stink.",
};
<Canvas>
<Story name="Description">{Description}</Story>
</Canvas>
### Left description position
export const DescriptionLeft = StateTemplate.bind({});
DescriptionLeft.args = {
labelPosition: "left",
description: "Every type of cheese will be consumed, regardless of stink.",
};
<Canvas>
<Story name="Description, left position">{DescriptionLeft}</Story>
</Canvas>
import type { MantineThemeOverride, SwitchStylesParams } from "@mantine/core";
import { rem, getSize, getStylesRef } from "@mantine/core";
import { color } from "metabase/lib/colors";
const LABEL_FONT_SIZES = {
xs: rem(12),
sm: rem(14),
md: rem(16),
};
const LABEL_LINE_HEIGHT = {
xs: rem(16),
sm: rem(24),
md: rem(24),
};
const SWITCH_PADDING = {
xs: rem(8),
sm: rem(8),
md: rem(16),
};
const TRACK_HEIGHTS = {
xs: rem(16),
sm: rem(20),
md: rem(24),
};
const TRACK_WIDTHS = {
xs: rem(32),
sm: rem(40),
md: rem(48),
lg: rem(64),
};
const THUMB_SIZES = {
xs: rem(12),
sm: rem(14),
md: rem(18),
};
const TRACK_PADDING_TOP = {
xs: rem(0),
sm: rem(2),
md: rem(0),
};
export const getSwitchOverrides = (): MantineThemeOverride["components"] => ({
Switch: {
defaultProps: {
color: "brand",
size: "md",
},
styles: (
theme,
{ error, labelPosition }: SwitchStylesParams,
{ size = "md" },
) => {
return {
labelWrapper: {
[labelPosition === "left" ? "paddingRight" : "paddingLeft"]: getSize({
size,
sizes: SWITCH_PADDING,
}),
"&:empty": {
padding: 0,
},
},
label: {
padding: 0,
fontWeight: 700,
fontSize: getSize({ size, sizes: LABEL_FONT_SIZES }),
lineHeight: getSize({ size, sizes: LABEL_LINE_HEIGHT }),
color: theme.colors.text[2],
cursor: "pointer",
"&[data-disabled]": {
color: theme.colors.text[0],
cursor: "default",
},
},
description: {
padding: 0,
marginTop: rem(8),
fontSize: rem(12),
color: theme.colors.text[1],
},
error: {
padding: 0,
marginTop: rem(8),
fontSize: rem(12),
color: theme.colors.error[0],
},
track: {
backgroundColor: theme.colors.bg[1],
border: error ? `1px solid ${color("accent3")}` : "none",
boxSizing: "border-box",
borderRadius: rem(24),
height: getSize({ size, sizes: TRACK_HEIGHTS }),
width: getSize({ size, sizes: TRACK_WIDTHS }),
cursor: "pointer",
[`${getStylesRef("input")}:disabled + &`]: {
backgroundColor: theme.colors.bg[1],
},
marginTop: getSize({ size, sizes: TRACK_PADDING_TOP }),
},
thumb: {
backgroundColor: theme.white,
border: "none",
borderRadius: rem(22),
height: getSize({ size, sizes: THUMB_SIZES }),
width: getSize({ size, sizes: THUMB_SIZES }),
[`${getStylesRef("input")}:disabled + * > &`]: {
backgroundColor: theme.colors.bg[0],
},
},
};
},
},
});
export { Switch } from "@mantine/core";
export type { SwitchProps, SwitchGroupProps } from "@mantine/core";
export { getSwitchOverrides } from "./Switch.styled";
......@@ -5,4 +5,5 @@ export * from "./NumberInput";
export * from "./Radio";
export * from "./Select";
export * from "./Textarea";
export * from "./Switch";
export * from "./TextInput";
......@@ -15,6 +15,7 @@ import {
getPaperOverrides,
getSelectOverrides,
getTextareaOverrides,
getSwitchOverrides,
getTextInputOverrides,
getTextOverrides,
getTitleOverrides,
......@@ -115,6 +116,7 @@ export const getThemeOverrides = (): MantineThemeOverride => ({
...getPaperOverrides(),
...getSelectOverrides(),
...getTextareaOverrides(),
...getSwitchOverrides(),
...getTextInputOverrides(),
...getTextOverrides(),
...getTitleOverrides(),
......
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