diff --git a/src/atoms/switch/index.js b/src/atoms/switch/index.js
new file mode 100644
index 0000000..be21a9d
--- /dev/null
+++ b/src/atoms/switch/index.js
@@ -0,0 +1 @@
+export { default as Switch } from './switch';
diff --git a/src/atoms/switch/switch.js b/src/atoms/switch/switch.js
new file mode 100644
index 0000000..f94870e
--- /dev/null
+++ b/src/atoms/switch/switch.js
@@ -0,0 +1,46 @@
+import React from 'react';
+import clsx from 'clsx';
+
+import { Box } from '../box';
+import { Icon } from '../icon';
+
+import './switch.scss';
+
+const Switch = ({
+ borderless = true,
+ children,
+ className,
+ disabled,
+ paddingless = 'horizontal',
+ block = false,
+ trailing,
+ ...others
+}) => {
+ return (
+
+
+
+
+ }
+ >
+ {children}
+
+ );
+};
+
+export default Switch;
diff --git a/src/atoms/switch/switch.scss b/src/atoms/switch/switch.scss
new file mode 100644
index 0000000..394a715
--- /dev/null
+++ b/src/atoms/switch/switch.scss
@@ -0,0 +1,61 @@
+@import '../../styles/tools/_tools.mixins';
+
+.cb-switch {
+ @include font;
+ @include disableable;
+ @include interactable;
+
+ align-items: center;
+ justify-content: flex-start;
+
+ .check {
+ @include transition(left);
+
+ @include var(color, color-white);
+
+ fill: currentColor;
+ position: absolute;
+ left: 2px;
+ }
+
+ .selector:first-of-type {
+ @include focusable;
+ @include bordered;
+ @include rounded(0.5rem);
+
+ @include transition(background color border-color);
+
+ cursor: pointer !important;
+ appearance: none;
+ outline: none;
+
+ @include var(border-color, color-gray-300);
+ @include var(background-color, color-gray-300);
+
+ flex-shrink: 0;
+
+ @include var(height, spacing-4);
+ @include var(width, spacing-8);
+
+ &:checked {
+ @include var(border-color, color-primary-500);
+ @include var(background-color, color-primary-500);
+ }
+
+ &:checked + .check {
+ left: calc(32px - 16px);
+ }
+ }
+
+ @include hoverable {
+ .selector {
+ @include var(border-color, color-gray-400);
+ @include var(background-color, color-gray-400);
+
+ &:checked {
+ @include var(border-color, color-primary-700);
+ @include var(background-color, color-primary-700);
+ }
+ }
+ }
+}
diff --git a/src/atoms/switch/switch.stories.js b/src/atoms/switch/switch.stories.js
new file mode 100644
index 0000000..383e5f9
--- /dev/null
+++ b/src/atoms/switch/switch.stories.js
@@ -0,0 +1,31 @@
+import React from 'react';
+
+import Switch from './switch';
+import generator from '../../../test/data-generator';
+
+export default {
+ title: 'Atoms/Switch',
+ component: Switch,
+ docs: {
+ description: {
+ story: 'some story *a*markdown**',
+ },
+ },
+};
+
+const Template = args => {
+ return (
+
+
+ This is me, a cool Switch family ready to be played around. Try me :)
+
+
+ {generator.name()}
+ {generator.name()}
+ {generator.name()}
+
+
+ );
+};
+
+export const Playground = Template.bind({});
diff --git a/src/atoms/switch/switch.test.js b/src/atoms/switch/switch.test.js
new file mode 100644
index 0000000..1b29c56
--- /dev/null
+++ b/src/atoms/switch/switch.test.js
@@ -0,0 +1,28 @@
+import React from 'react';
+
+import { render, fireEvent } from '../../../test/helpers';
+import { Switch } from './index';
+import generator from '../../../test/data-generator';
+
+describe('Switch', () => {
+ const props = {
+ children: generator.word(),
+ onChange: jest.fn(),
+ };
+
+ const { getByTestId } = render();
+
+ const component = getByTestId('cb-switch');
+ const selector = getByTestId('selector');
+
+ it('renders correctly', () => {
+ expect(component).toHaveTextContent(props.children);
+ expect(selector).toHaveAttribute('type', 'checkbox');
+ });
+
+ it('triggers onChange when clicked', () => {
+ expect(selector.checked).toBe(false);
+ fireEvent.click(selector);
+ expect(selector.checked).toBe(true);
+ });
+});