diff --git a/src/components/Switch/Switch.stories.mdx b/src/components/Switch/Switch.stories.mdx new file mode 100644 index 0000000..b745aa2 --- /dev/null +++ b/src/components/Switch/Switch.stories.mdx @@ -0,0 +1,133 @@ +import { Canvas, Meta, Story, ArgsTable } from '@storybook/addon-docs'; + +import Switch from './Switch.vue'; + + + +export const Default = (args) => { + return { + components: { Switch }, + setup() { + return { + args, + }; + }, + template: '', + }; +}; + +# All the sizes + +
+ + + + {Default.bind({})} + + + {Default.bind({})} + + + {Default.bind({})} + + + +# Reference + +
+ + + +# Notes + +
+

+ This component is a wrapper around the input element. +

+

+ The value prop is passed to the input element. +

+

+ The disabled prop is passed to the input element. +

+

+ The size prop is passed to the input element. +

+ +# Installation + +
+ +

Install the component with:

+ +```js +import { Switch } from '@/components/Switch'; +``` + +# Examples + +
+ +
Basic using
+ +```html + +``` + +
Advance using
+ +```html + +``` diff --git a/src/components/Switch/Switch.vue b/src/components/Switch/Switch.vue new file mode 100644 index 0000000..890ecf3 --- /dev/null +++ b/src/components/Switch/Switch.vue @@ -0,0 +1,39 @@ + + diff --git a/src/components/Switch/switch.css b/src/components/Switch/switch.css new file mode 100644 index 0000000..cb3be02 --- /dev/null +++ b/src/components/Switch/switch.css @@ -0,0 +1,56 @@ +@tailwind components; + +fieldset { + @apply font-sans border-none m-0 p-0; +} +.switch { + @apply relative inline-block w-16 h-9; +} +.switch--small { + @apply w-12 h-6; +} +.switch--large { + @apply w-20 h-11; +} +.switch input { + @apply opacity-0 w-0 h-0 -z-10; +} +.slider { + @apply absolute top-0 left-0 right-0 bottom-0 bg-gray-300 transition duration-200 ease-in-out; +} +.switch--small > .slider::before { + @apply w-4 h-4; +} +.switch--large > .slider::before { + @apply w-9 h-9; +} +.slider:before { + content: ''; + @apply absolute h-7 w-7 left-1 bottom-1 bg-white transition duration-200 ease-in-out; +} +input:checked + .slider { + @apply bg-teal-400; +} +input:focus + .slider { + box-shadow: 0 0 1px; + @apply shadow-teal-400; +} +input:checked + .slider:before { + -webkit-transform: translateX(26px); + -ms-transform: translateX(26px); + transform: translateX(26px); +} +.switch--large > input:checked + .slider:before { + -webkit-transform: translateX(34px); + -ms-transform: translateX(34px); + transform: translateX(34px); +} +.slider.round { + @apply rounded-full; +} +.slider.round:before { + @apply rounded-full; +} +.switch--disabled { + @apply opacity-50 cursor-not-allowed; +} diff --git a/src/components/Switch/switch.spec.ts b/src/components/Switch/switch.spec.ts new file mode 100644 index 0000000..fb409f1 --- /dev/null +++ b/src/components/Switch/switch.spec.ts @@ -0,0 +1,23 @@ +import { describe, it, expect } from 'vitest'; + +import { mount } from '@vue/test-utils'; +import Switch from './Switch.vue'; + +describe('Switch', () => { + it('renders properly', () => { + const wrapper = mount(Switch, { + props: { + id: 'switch-id', + disabled: false, + size: 'small', + }, + }); + expect(wrapper.exists()).toBe(true); + expect(wrapper.find('label').exists()).toBe(true); + expect(wrapper.find('label').element.getAttribute('for')).toBe('switch-id'); + expect(wrapper.find('input').exists()).toBe(true); + expect(wrapper.find('input').element.getAttribute('id')).toBe('switch-id'); + expect(wrapper.find('input').element.getAttribute('type')).toBe('checkbox'); + expect(wrapper.find('input').element.getAttribute('disabled')).toBe(null); + }); +});