Skip to content

Commit

Permalink
feat: Switch
Browse files Browse the repository at this point in the history
  • Loading branch information
JasKang committed Mar 26, 2024
1 parent b099d2e commit 75ecdc1
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 8 deletions.
5 changes: 1 addition & 4 deletions packages/docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,6 @@ export default defineConfigWithTheme<ThemeConfig>({
{ key: 'Button', link: '/components/button' },
{ key: 'Anchor', link: '/components/anchor' },
{ key: 'ScrollArea', link: '/components/scroll-area' },
{ key: 'Popover', link: '/components/popover' },
{ key: 'Tooltip', link: '/components/tooltip' },
],
},
{
Expand All @@ -129,8 +127,7 @@ export default defineConfigWithTheme<ThemeConfig>({
{ key: 'Radio', link: '/components/radio' },
{ key: 'Input', link: '/components/input' },
{ key: 'Select', link: '/components/select' },
{ key: 'Popover', link: '/components/popover' },
{ key: 'Tooltip', link: '/components/tooltip' },
{ key: 'Switch', link: '/components/switch' },
],
},
{
Expand Down
41 changes: 41 additions & 0 deletions packages/docs/components/switch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<script setup>
import { ref } from 'vue'
import { Switch } from 'tailv'

const val = ref(true)

</script>

# CheckboxGroup

## Default

<div class="flex flex-wrap gap-2">
<div class="">
<Switch v-model:checked="val" /> value: {{ val }}
</div>
</div>

## Disabled

<div class="flex flex-wrap gap-2">
<Checkbox value="A" disabled checked>
checked
</Checkbox>
<Checkbox value="B" disabled>unchecked</Checkbox>
</div>

## Props

| Prop | Type | Default | Description |
| ----------- | ------- | ------- | ----------------------------- |
| **checked** | boolean | false | whether the checkbox checked |
| name | string | - | input name |
| value | any | - | value for group |
| disabled | boolean | false | whether the checkbox disabled |

## Slots

| Name | Description |
| ------- | ----------- |
| default | children |
74 changes: 70 additions & 4 deletions packages/vue/src/Switch/Switch.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,77 @@
<script setup lang="ts">
import { useModelValue } from '@/use/useModelValue'
import { ref, computed } from 'vue'
defineOptions({ name: 'TSwitch' })
const emit = defineEmits<{ click: [any] }>()
const slots = defineSlots<{ default?(_: {}): any }>()
const props = defineProps({})
const emit = defineEmits<{ 'update:checked': [boolean]; change: [boolean] }>()
const slots = defineSlots<{ default?(_: {}): any; open?(_: {}): any; close?(_: {}): any }>()
const props = defineProps({
checked: { type: Boolean, default: undefined },
name: String,
disabled: Boolean,
})
const [innerChecked, setInnerChecked] = useModelValue<boolean>(props, {
valuePropName: 'checked',
onChange: val => {
emit('change', val)
},
})
const clickHandler = () => {
setInnerChecked(!innerChecked.value)
}
</script>
<template>
<div></div>
<button
type="button"
class="flex-shrink-0 relative inline-flex h-6 w-11 cursor-pointer appearance-none rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out select-none focus:ring-2 focus:ring-indigo-600 focus:ring-offset-2 focus:outline-none"
:class="[innerChecked ? 'bg-primary-500' : 'bg-gray-200']"
:disabled="disabled"
:name="name"
@click="clickHandler"
>
<slot name="open"></slot>
<slot name="close"></slot>
<!-- Enabled: "translate-x-5", Not Enabled: "translate-x-0" -->
<span
class="pointer-events-none relative inline-block h-5 w-5 translate-x-0 transform rounded-full bg-white ring-0 shadow transition duration-200 ease-in-out"
:class="[innerChecked ? 'translate-x-5' : 'translate-x-0']"
>
<span
:class="[
innerChecked ? 'opacity-0 duration-100 ease-out' : 'opacity-100 duration-200 ease-in',
'absolute inset-0 flex h-full w-full items-center justify-center transition-opacity',
]"
aria-hidden="true"
>
<slot name="open">
<svg class="h-3 w-3 text-gray-400" fill="none" viewBox="0 0 12 12">
<path
d="M4 8l2-2m0 0l2-2M6 6L4 4m2 2l2 2"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</slot>
</span>
<span
:class="[
innerChecked ? 'opacity-100 duration-200 ease-in' : 'opacity-0 duration-100 ease-out',
'absolute inset-0 flex h-full w-full items-center justify-center transition-opacity',
]"
aria-hidden="true"
>
<slot name="close">
<svg class="h-3 w-3 text-indigo-600" fill="currentColor" viewBox="0 0 12 12">
<path
d="M3.707 5.293a1 1 0 00-1.414 1.414l1.414-1.414zM5 8l-.707.707a1 1 0 001.414 0L5 8zm4.707-3.293a1 1 0 00-1.414-1.414l1.414 1.414zm-7.414 2l2 2 1.414-1.414-2-2-1.414 1.414zm3.414 2l4-4-1.414-1.414-4 4 1.414 1.414z"
/>
</svg>
</slot>
</span>
</span>
</button>
</template>
1 change: 1 addition & 0 deletions packages/vue/src/Switch/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as Switch } from './Switch.vue'
1 change: 1 addition & 0 deletions packages/vue/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export { Anchor, type AnchorItem } from './Anchor'
export { ScrollArea } from './ScrollArea'
export { default as Input } from './Input/index.vue'
export { Select, type SelectOption } from './Select'
export { Switch } from './Switch'
export { default as Popover } from './Popover/index.vue'
export { default as Tooltip } from './Tooltip/index.vue'
export { default as SpaceCompact } from './Space/SpaceCompact.vue'
Expand Down

0 comments on commit 75ecdc1

Please sign in to comment.