diff --git a/src/components/Switch/Switch.stories.tsx b/src/components/Switch/Switch.stories.tsx
new file mode 100644
index 00000000..6cac3b90
--- /dev/null
+++ b/src/components/Switch/Switch.stories.tsx
@@ -0,0 +1,92 @@
+// import { action } from '@storybook/addon-actions';
+import React from 'react';
+import Switch from './Switch';
+
+export default {
+ title: 'Switch',
+ component: Switch,
+};
+
+export const DefaultSwitch = () => {
+ const [showOn, setShowOn] = React.useState(false);
+ const handleChange = () => {
+ setShowOn(!showOn);
+ };
+ return (
+
+ );
+};
+
+export const DiffSizeSwitch = () => {
+ const [showOn, setShowOn] = React.useState(false);
+ return (
+
+ setShowOn(!showOn)}
+ isChecked={showOn}
+ label="Small Switch with default color"
+ />
+
+
+
+ );
+};
+
+export const DiffColorSwitch = () => {
+ const [showOnP, setShowOnP] = React.useState(false);
+ const [showOnS, setShowOnS] = React.useState(false);
+
+ console.log(showOnP);
+ return (
+
+ {
+ setShowOnP(!showOnP);
+ }}
+ label="Primary color Switch"
+ isChecked={showOnP}
+ />
+
+ setShowOnS(!showOnS)}
+ isChecked={showOnS}
+ label="Secondary color Switch"
+ />
+
+ );
+};
+
+export const DiffTypeSwitch = () => {
+ const [showOn, setShowOn] = React.useState(false);
+ const [defaultOn, setDefaultOn] = React.useState(true);
+ return (
+
+ {
+ setShowOn(!showOn);
+ }}
+ isChecked={showOn}
+ label="Default Switch"
+ />
+
+
+
+ {
+ setDefaultOn(!defaultOn);
+ }}
+ isChecked={defaultOn}
+ label="On as default switch"
+ />
+
+ console.log('clicked')}
+ />
+
+ );
+};
diff --git a/src/components/Switch/Switch.test.tsx b/src/components/Switch/Switch.test.tsx
new file mode 100644
index 00000000..d4211f94
--- /dev/null
+++ b/src/components/Switch/Switch.test.tsx
@@ -0,0 +1,103 @@
+import React from 'react';
+import Switch, { PatSwitchProps } from './Switch';
+import { render, fireEvent, screen } from '@testing-library/react';
+
+describe('Switch', () => {
+ it('should match snapshot', () => {
+ const { asFragment } = render();
+ expect(asFragment()).toMatchSnapshot();
+ });
+
+ it('should render default switch', () => {
+ render();
+ const element = screen.getByTestId('switch-element');
+ const checkbox = screen.getByRole('checkbox');
+ const label = screen.getByText('Default Switch');
+ const slider = screen.getByTestId('test-slider');
+
+ expect(element).toBeInTheDocument();
+ expect(checkbox).toBeInTheDocument();
+ expect(label).toBeInTheDocument();
+ expect(slider).toBeInTheDocument();
+ expect(slider).toHaveClass('switch-slider');
+ expect(element).toHaveClass('switch switch-sm');
+ expect(checkbox).not.toBeChecked();
+ fireEvent.click(checkbox);
+ expect(checkbox).toBeChecked();
+ expect(element).toHaveClass('switch-default');
+ });
+
+ it('should render corrsonding button based on props', () => {
+ const switchLargePrimary: PatSwitchProps = {
+ switchColor: 'primary',
+ switchSize: 'lg',
+ className: 'test',
+ };
+
+ render(
+
+ );
+ const element = screen.getByTestId('switch-element');
+ const checkbox = screen.getByRole('checkbox');
+ const label = screen.getByText('Large Primary Switch');
+ const slider = screen.getByTestId('test-slider');
+
+ expect(element).toBeInTheDocument();
+ expect(checkbox).toBeInTheDocument();
+ expect(label).toBeInTheDocument();
+ expect(slider).toBeInTheDocument();
+ expect(slider).toHaveClass('switch-slider');
+ expect(element).toHaveClass('switch switch-lg test');
+ expect(checkbox).not.toBeChecked();
+ fireEvent.click(checkbox);
+ expect(checkbox).toBeChecked();
+ });
+
+ it('should render on switch', () => {
+ const switchDefualtOn: PatSwitchProps = {
+ isChecked: true,
+ };
+
+ render();
+ const element = screen.getByTestId('switch-element');
+ const checkbox = screen.getByRole('checkbox');
+ const label = screen.getByText('Default On Switch');
+ const slider = screen.getByTestId('test-slider');
+
+ expect(element).toBeInTheDocument();
+ expect(checkbox).toBeInTheDocument();
+ expect(label).toBeInTheDocument();
+ expect(slider).toBeInTheDocument();
+ expect(slider).toHaveClass('switch-slider');
+ expect(element).toHaveClass('switch switch-default switch-sm');
+ fireEvent.click(checkbox);
+ expect(checkbox).toBeChecked();
+ expect(checkbox).toHaveAttribute('checked', '');
+ });
+
+ it('should render a disabled switch', () => {
+ const disabledSwitchProp: PatSwitchProps = {
+ disabled: true,
+ onClick: jest.fn(),
+ };
+ render();
+ const element = screen.getByTestId('switch-element');
+ const checkbox = screen.getByRole('checkbox');
+ const label = screen.getByText('Disabled Switch');
+ const slider = screen.getByTestId('test-slider');
+ expect(element).toBeInTheDocument();
+ expect(checkbox).toBeInTheDocument();
+ expect(label).toBeInTheDocument();
+ expect(slider).toBeInTheDocument();
+ expect(slider).toHaveClass('switch-slider');
+ expect(element).toBeInTheDocument();
+ expect(checkbox).toBeInTheDocument();
+ expect(label).toBeInTheDocument();
+ expect(slider).toBeInTheDocument();
+ expect(element).toHaveClass('switch switch-default switch-sm');
+ expect(disabledSwitchProp.onClick).toHaveBeenCalledTimes(0);
+ fireEvent.click(element);
+ expect(disabledSwitchProp.onClick).toHaveBeenCalledTimes(0);
+ expect(slider).toHaveClass('disabled');
+ });
+});
diff --git a/src/components/Switch/Switch.tsx b/src/components/Switch/Switch.tsx
new file mode 100644
index 00000000..3801d0f3
--- /dev/null
+++ b/src/components/Switch/Switch.tsx
@@ -0,0 +1,85 @@
+import React, { FC, InputHTMLAttributes } from 'react';
+
+import { classNames } from '../../utils/classNames';
+
+export type SwitchSize = 'sm' | 'lg';
+export type SwitchColor = 'primary' | 'secondary' | 'default';
+
+export interface ISwitchProps {
+ /** set class name */
+ className?: string;
+ /** set switch size */
+ switchSize?: SwitchSize;
+ /** set switch color */
+ switchColor?: SwitchColor;
+ /** set disabled switch */
+ disabled?: boolean;
+ /** set default to checked */
+ isChecked?: boolean;
+ /** set switch label */
+ label?: string;
+}
+
+export type PatSwitchProps = ISwitchProps &
+ InputHTMLAttributes;
+
+/**
+ * Switches toggle the state of a single setting on or off.
+ *
+ * ```js
+ * import {Switch} from 'pat-ui'
+ * ```
+ *
+ */
+const Switch: FC = (props) => {
+ const {
+ switchSize,
+ className,
+ disabled = false,
+ switchColor,
+ label,
+ isChecked,
+ ...rest
+ } = props;
+ let styleClasses = classNames('switch', {
+ [`switch-${isChecked ? switchColor : 'default'}`]: true,
+ [`switch-${switchSize}`]: !!switchSize,
+ disabled: !!disabled,
+ });
+ if (className) {
+ styleClasses += ' ' + className;
+ }
+
+ let swh = (
+
+ );
+
+ return swh;
+};
+
+Switch.defaultProps = {
+ switchColor: 'default',
+ disabled: false,
+ switchSize: 'sm',
+};
+
+export default Switch;
diff --git a/src/components/Switch/__snapshots__/Switch.test.tsx.snap b/src/components/Switch/__snapshots__/Switch.test.tsx.snap
new file mode 100644
index 00000000..27db9f91
--- /dev/null
+++ b/src/components/Switch/__snapshots__/Switch.test.tsx.snap
@@ -0,0 +1,31 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Switch should match snapshot 1`] = `
+
+
+
+
+ Snapshot Switch
+
+
+
+`;
diff --git a/src/components/Switch/index.tsx b/src/components/Switch/index.tsx
new file mode 100644
index 00000000..ed80f23e
--- /dev/null
+++ b/src/components/Switch/index.tsx
@@ -0,0 +1 @@
+export { default } from './Switch';
diff --git a/src/components/Switch/styles/_Switch.scss b/src/components/Switch/styles/_Switch.scss
new file mode 100644
index 00000000..c68f34bf
--- /dev/null
+++ b/src/components/Switch/styles/_Switch.scss
@@ -0,0 +1,123 @@
+@import './variables';
+@import './mixin';
+.switch {
+ margin: $switch-margin;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ &-label {
+ @include switch-lable-style(
+ 16px,
+ 24px,
+ 0.15px,
+ $font-family-base,
+ 0.3em,
+ 0.3em
+ );
+ }
+
+ &-container {
+ position: relative;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ width: 26px;
+ height: 10px;
+ }
+
+ &-toggle {
+ opacity: 0;
+ width: 0;
+ height: 0;
+ }
+
+ &-slider {
+ position: absolute;
+ cursor: pointer;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ border-radius: 5px;
+ }
+
+ &-slider::before {
+ position: absolute;
+ content: '';
+ @include switch-slider(16px, 16px, -3px, -2px, 0.4s, 50%);
+ }
+ &-slider:hover::before {
+ box-shadow: 0 0 0 3px rgba(222, 226, 230, 0.18);
+ }
+
+ &-toggle:checked + &-slider::before {
+ transform: translateX(13px);
+ }
+}
+
+.switch {
+ &-lg {
+ .switch-container {
+ width: 34px;
+ height: 14px;
+ opacity: 50%;
+ }
+ .switch-slider::before {
+ height: 20px;
+ width: 20px;
+ opacity: 100% !important;
+ }
+ .switch-slider {
+ border-radius: 7px;
+ }
+
+ .switch-toggle:checked + .switch-slider::before {
+ transform: translateX(18px);
+ }
+ }
+}
+
+.switch-primary {
+ .switch-slider {
+ background-color: $switch-primary;
+ }
+
+ .switch-slider::before {
+ background-color: $primary;
+ }
+
+ .switch-slider:hover::before {
+ box-shadow: $switch-primary-hover;
+ }
+}
+
+.switch-secondary {
+ .switch-slider {
+ background-color: rgba(108, 117, 125, 0.8);
+ }
+
+ .switch-slider::before {
+ background-color: $secondary;
+ }
+ .switch-slider:hover::before {
+ box-shadow: 0 0 0 3px rgba(108, 117, 125, 0.2);
+ }
+}
+
+.switch-default {
+ .switch-slider {
+ background-color: rgba(173, 181, 189, 0.8);
+ }
+
+ .switch-slider::before {
+ background-color: $gray-300;
+ }
+ .switch-slider:hover::before {
+ box-shadow: 0 0 0 3px rgba(222, 226, 230, 0.2);
+ }
+}
+
+.disabled {
+ cursor: not-allowed !important;
+}
diff --git a/src/components/Switch/styles/_mixin.scss b/src/components/Switch/styles/_mixin.scss
new file mode 100644
index 00000000..ebf37205
--- /dev/null
+++ b/src/components/Switch/styles/_mixin.scss
@@ -0,0 +1,24 @@
+@mixin switch-lable-style(
+ $size,
+ $height,
+ $spacing,
+ $font,
+ $margin-l,
+ $margin-r
+) {
+ font-size: $size;
+ line-height: $height;
+ letter-spacing: $spacing;
+ font-family: $font;
+ margin-left: $margin-l;
+ margin-top: $margin-r;
+}
+
+@mixin switch-slider($heigth, $width, $top, $left, $transition, $br) {
+ height: $heigth;
+ width: $width;
+ top: $top;
+ left: $left;
+ transition: $transition;
+ border-radius: $br;
+}
diff --git a/src/components/Switch/styles/_variables.scss b/src/components/Switch/styles/_variables.scss
new file mode 100644
index 00000000..4ba25c44
--- /dev/null
+++ b/src/components/Switch/styles/_variables.scss
@@ -0,0 +1,4 @@
+$switch-primary: rgba(32, 201, 151, 0.8);
+$switch-secondary: rgba(108, 117, 125, 0.8);
+$switch-primary-hover: 0 0 0 3px rgba(32, 201, 151, 0.2);
+$switch-margin: 1em;
diff --git a/src/index.tsx b/src/index.tsx
index 70aeb63c..ba5d50b6 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -5,3 +5,4 @@ export { default as Message } from './components/Message';
export { default as Card } from './components/Card';
export { default as Dropdown } from './components/Dropdown';
export { default as Progress } from './components/Progress';
+export { default as Switch } from './components/Switch';
diff --git a/src/styles/index.scss b/src/styles/index.scss
index 33fa969f..cb1ee7fc 100644
--- a/src/styles/index.scss
+++ b/src/styles/index.scss
@@ -12,3 +12,7 @@
@import '../components/Input/Input';
@import '../components/Card/Card';
@import '../components/Progress/Progress';
+
+//Switch
+
+@import '../components/Switch/styles/Switch';