Skip to content

Commit 2cf4502

Browse files
Andrewjeskarazor-xseambot
authored
Add Switch component (#377)
Co-authored-by: Evan Sosenko <[email protected]> Co-authored-by: Seam Bot <[email protected]>
1 parent f1b539d commit 2cf4502

File tree

4 files changed

+129
-0
lines changed

4 files changed

+129
-0
lines changed

src/lib/ui/Switch/Switch.stories.tsx

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { useArgs } from '@storybook/preview-api'
2+
import type { Meta, StoryObj } from '@storybook/react'
3+
4+
import Switch from './Switch.js'
5+
6+
const meta: Meta<typeof Switch> = {
7+
title: 'Library/Switch',
8+
tags: ['autodocs'],
9+
component: Switch,
10+
}
11+
12+
type Story = StoryObj<typeof Switch>
13+
14+
export const Content: Story = {
15+
render: (props) => {
16+
const [, setArgs] = useArgs()
17+
18+
const onChange = (checked: boolean): void => {
19+
setArgs({ checked })
20+
}
21+
22+
return (
23+
<Switch
24+
enableLabel={props.enableLabel}
25+
checked={props.checked}
26+
onChange={onChange}
27+
/>
28+
)
29+
},
30+
}
31+
32+
Content.args = {
33+
checked: false,
34+
}
35+
36+
export default meta

src/lib/ui/Switch/Switch.tsx

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import classNames from 'classnames'
2+
3+
export interface SwitchProps {
4+
checked: boolean
5+
onChange: (checked: boolean) => void
6+
enableLabel?: boolean
7+
}
8+
9+
function Switch({
10+
checked,
11+
onChange,
12+
enableLabel = false,
13+
}: SwitchProps): JSX.Element {
14+
return (
15+
<div className='seam-switch-container'>
16+
{enableLabel && (
17+
<label className='seam-switch-label'>{checked ? t.on : t.off}</label>
18+
)}
19+
<div
20+
className={classNames('seam-switch', {
21+
'seam-switch-checked': checked,
22+
})}
23+
onClick={() => {
24+
onChange(!checked)
25+
}}
26+
>
27+
<div className='seam-switch-slider' />
28+
</div>
29+
</div>
30+
)
31+
}
32+
33+
const t = {
34+
on: 'On',
35+
off: 'Off',
36+
}
37+
38+
export default Switch

src/styles/_main.scss

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
@use './thermostat';
2121
@use './tooltip';
2222
@use './seam-table';
23+
@use './switch';
2324

2425
.seam-components {
2526
// Reset
@@ -38,6 +39,7 @@
3839
@include checkbox.all;
3940
@include radio-field.all;
4041
@include tooltip.all;
42+
@include switch.all;
4143

4244
// Components
4345
@include device-details.all;

src/styles/_switch.scss

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
@use './colors';
2+
3+
@mixin all {
4+
.seam-switch-container {
5+
display: flex;
6+
align-items: center;
7+
gap: 8px;
8+
9+
.seam-switch-label {
10+
font-style: normal;
11+
font-weight: 400;
12+
line-height: 118%;
13+
font-size: 14px;
14+
color: colors.$text-gray-2-5;
15+
}
16+
17+
.seam-switch {
18+
position: relative;
19+
cursor: pointer;
20+
21+
.seam-switch-slider::before {
22+
position: absolute;
23+
content: '';
24+
height: 20px;
25+
width: 20px;
26+
left: 0;
27+
bottom: -3px;
28+
background-color: colors.$bg-aa;
29+
transition: 0.4s;
30+
border-radius: 50%;
31+
filter: drop-shadow(0 1px 4px rgb(0 0 0 / 25%));
32+
}
33+
34+
.seam-switch-slider {
35+
inset: 0;
36+
width: 34px;
37+
height: 14px;
38+
background-color: #ccc;
39+
transition: 0.4s;
40+
border-radius: 20px;
41+
}
42+
43+
&.seam-switch-checked .seam-switch-slider::before {
44+
transform: translateX(14px);
45+
background-color: colors.$primary;
46+
}
47+
48+
&.seam-switch-checked .seam-switch-slider {
49+
background-color: colors.$primary-dim;
50+
}
51+
}
52+
}
53+
}

0 commit comments

Comments
 (0)