feat: toggle group

This commit is contained in:
Sadegh Barati 2024-01-15 22:31:28 +03:30
parent c33acba4ff
commit f88f6e852b
22 changed files with 606 additions and 1 deletions

View File

@ -330,6 +330,11 @@ export const docsConfig: DocsConfig = {
href: '/docs/components/toggle',
items: [],
},
{
title: 'Toggle Group',
href: '/docs/components/toggle-group',
items: [],
},
{
title: 'Tooltip',
href: '/docs/components/tooltip',

View File

@ -716,6 +716,48 @@ export const Index = {
component: () => import('../src/lib/registry/default/example/ToggleSmallDemo.vue').then(m => m.default),
files: ['../src/lib/registry/default/example/ToggleSmallDemo.vue'],
},
ToggleGroupDemo: {
name: 'ToggleGroupDemo',
type: 'components:example',
registryDependencies: ['toggle-group'],
component: () => import('../src/lib/registry/default/example/ToggleGroupDemo.vue').then(m => m.default),
files: ['../src/lib/registry/default/example/ToggleGroupDemo.vue'],
},
ToggleGroupDisabledDemo: {
name: 'ToggleGroupDisabledDemo',
type: 'components:example',
registryDependencies: ['toggle-group'],
component: () => import('../src/lib/registry/default/example/ToggleGroupDisabledDemo.vue').then(m => m.default),
files: ['../src/lib/registry/default/example/ToggleGroupDisabledDemo.vue'],
},
ToggleGroupLargeDemo: {
name: 'ToggleGroupLargeDemo',
type: 'components:example',
registryDependencies: ['toggle-group'],
component: () => import('../src/lib/registry/default/example/ToggleGroupLargeDemo.vue').then(m => m.default),
files: ['../src/lib/registry/default/example/ToggleGroupLargeDemo.vue'],
},
ToggleGroupOutlineDemo: {
name: 'ToggleGroupOutlineDemo',
type: 'components:example',
registryDependencies: ['toggle-group'],
component: () => import('../src/lib/registry/default/example/ToggleGroupOutlineDemo.vue').then(m => m.default),
files: ['../src/lib/registry/default/example/ToggleGroupOutlineDemo.vue'],
},
ToggleGroupSingleDemo: {
name: 'ToggleGroupSingleDemo',
type: 'components:example',
registryDependencies: ['toggle-group'],
component: () => import('../src/lib/registry/default/example/ToggleGroupSingleDemo.vue').then(m => m.default),
files: ['../src/lib/registry/default/example/ToggleGroupSingleDemo.vue'],
},
ToggleGroupSmallDemo: {
name: 'ToggleGroupSmallDemo',
type: 'components:example',
registryDependencies: ['toggle-group'],
component: () => import('../src/lib/registry/default/example/ToggleGroupSmallDemo.vue').then(m => m.default),
files: ['../src/lib/registry/default/example/ToggleGroupSmallDemo.vue'],
},
TooltipDemo: {
name: 'TooltipDemo',
type: 'components:example',
@ -1558,6 +1600,48 @@ export const Index = {
component: () => import('../src/lib/registry/new-york/example/ToggleSmallDemo.vue').then(m => m.default),
files: ['../src/lib/registry/new-york/example/ToggleSmallDemo.vue'],
},
ToggleGroupDemo: {
name: 'ToggleGroupDemo',
type: 'components:example',
registryDependencies: ['toggle-group'],
component: () => import('../src/lib/registry/new-york/example/ToggleGroupDemo.vue').then(m => m.default),
files: ['../src/lib/registry/new-york/example/ToggleGroupDemo.vue'],
},
ToggleGroupDisabledDemo: {
name: 'ToggleGroupDisabledDemo',
type: 'components:example',
registryDependencies: ['toggle-group'],
component: () => import('../src/lib/registry/new-york/example/ToggleGroupDisabledDemo.vue').then(m => m.default),
files: ['../src/lib/registry/new-york/example/ToggleGroupDisabledDemo.vue'],
},
ToggleGroupLargeDemo: {
name: 'ToggleGroupLargeDemo',
type: 'components:example',
registryDependencies: ['toggle-group'],
component: () => import('../src/lib/registry/new-york/example/ToggleGroupLargeDemo.vue').then(m => m.default),
files: ['../src/lib/registry/new-york/example/ToggleGroupLargeDemo.vue'],
},
ToggleGroupOutlineDemo: {
name: 'ToggleGroupOutlineDemo',
type: 'components:example',
registryDependencies: ['toggle-group'],
component: () => import('../src/lib/registry/new-york/example/ToggleGroupOutlineDemo.vue').then(m => m.default),
files: ['../src/lib/registry/new-york/example/ToggleGroupOutlineDemo.vue'],
},
ToggleGroupSingleDemo: {
name: 'ToggleGroupSingleDemo',
type: 'components:example',
registryDependencies: ['toggle-group'],
component: () => import('../src/lib/registry/new-york/example/ToggleGroupSingleDemo.vue').then(m => m.default),
files: ['../src/lib/registry/new-york/example/ToggleGroupSingleDemo.vue'],
},
ToggleGroupSmallDemo: {
name: 'ToggleGroupSmallDemo',
type: 'components:example',
registryDependencies: ['toggle-group'],
component: () => import('../src/lib/registry/new-york/example/ToggleGroupSmallDemo.vue').then(m => m.default),
files: ['../src/lib/registry/new-york/example/ToggleGroupSmallDemo.vue'],
},
TooltipDemo: {
name: 'TooltipDemo',
type: 'components:example',

View File

@ -0,0 +1,93 @@
---
title: Toggle Group
description: A set of two-state buttons that can be toggled on or off.
source: apps/www/src/lib/registry/default/ui/toggle-group
primitive: https://www.radix-vue.com/components/toggle-group.html
---
<ComponentPreview name="ToggleGroupDemo" />
## Installation
<TabPreview name="CLI">
<template #CLI>
```bash
npx shadcn-vue@latest add toggle-group
```
</template>
<template #Manual>
<Steps>
### Install the following dependencies:
```bash
npm install radix-vue
```
### Copy and paste the following code into your project
<<< @/lib/registry/default/ui/toggle-group/ToggleGroup.vue
</Steps>
</template>
</TabPreview>
## Usage
```vue
<script setup lang="ts">
import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group'
</script>
<template>
<ToggleGroup type="single">
<ToggleGroupItem value="a">
A
</ToggleGroupItem>
<ToggleGroupItem value="b">
B
</ToggleGroupItem>
<ToggleGroupItem value="c">
C
</ToggleGroupItem>
</ToggleGroup>
</template>
```
## Examples
### Default
<ComponentPreview name="ToggleGroupDemo" />
### Outline
<ComponentPreview name="ToggleGroupOutlineDemo" />
### Single
<ComponentPreview name="ToggleGroupSingleDemo" />
### Small
<ComponentPreview name="ToggleGroupSmallDemo" />
### Large
<ComponentPreview name="ToggleGroupLargeDemo" />
### Disabled
<ComponentPreview name="ToggleGroupDisabledDemo" />

View File

@ -0,0 +1,19 @@
<script setup lang="ts">
import { Bold, Italic, Underline } from 'lucide-vue-next'
import { ToggleGroup, ToggleGroupItem } from '@/lib/registry/default/ui/toggle-group'
</script>
<template>
<ToggleGroup type="multiple">
<ToggleGroupItem value="bold" aria-label="Toggle bold">
<Bold class="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="italic" aria-label="Toggle italic">
<Italic class="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="underline" aria-label="Toggle underline">
<Underline class="h-4 w-4" />
</ToggleGroupItem>
</ToggleGroup>
</template>

View File

@ -0,0 +1,19 @@
<script setup lang="ts">
import { Bold, Italic, Underline } from 'lucide-vue-next'
import { ToggleGroup, ToggleGroupItem } from '@/lib/registry/default/ui/toggle-group'
</script>
<template>
<ToggleGroup type="multiple" disabled>
<ToggleGroupItem value="bold" aria-label="Toggle bold">
<Bold class="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="italic" aria-label="Toggle italic">
<Italic class="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="underline" aria-label="Toggle underline">
<Underline class="h-4 w-4" />
</ToggleGroupItem>
</ToggleGroup>
</template>

View File

@ -0,0 +1,19 @@
<script setup lang="ts">
import { Bold, Italic, Underline } from 'lucide-vue-next'
import { ToggleGroup, ToggleGroupItem } from '@/lib/registry/default/ui/toggle-group'
</script>
<template>
<ToggleGroup type="multiple" size="lg">
<ToggleGroupItem value="bold" aria-label="Toggle bold">
<Bold class="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="italic" aria-label="Toggle italic">
<Italic class="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="underline" aria-label="Toggle underline">
<Underline class="h-4 w-4" />
</ToggleGroupItem>
</ToggleGroup>
</template>

View File

@ -0,0 +1,19 @@
<script setup lang="ts">
import { Bold, Italic, Underline } from 'lucide-vue-next'
import { ToggleGroup, ToggleGroupItem } from '@/lib/registry/default/ui/toggle-group'
</script>
<template>
<ToggleGroup type="multiple" variant="outline">
<ToggleGroupItem value="bold" aria-label="Toggle bold">
<Bold class="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="italic" aria-label="Toggle italic">
<Italic class="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="underline" aria-label="Toggle underline">
<Underline class="h-4 w-4" />
</ToggleGroupItem>
</ToggleGroup>
</template>

View File

@ -0,0 +1,19 @@
<script setup lang="ts">
import { Bold, Italic, Underline } from 'lucide-vue-next'
import { ToggleGroup, ToggleGroupItem } from '@/lib/registry/default/ui/toggle-group'
</script>
<template>
<ToggleGroup type="single">
<ToggleGroupItem value="bold" aria-label="Toggle bold">
<Bold class="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="italic" aria-label="Toggle italic">
<Italic class="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="underline" aria-label="Toggle underline">
<Underline class="h-4 w-4" />
</ToggleGroupItem>
</ToggleGroup>
</template>

View File

@ -0,0 +1,19 @@
<script setup lang="ts">
import { Bold, Italic, Underline } from 'lucide-vue-next'
import { ToggleGroup, ToggleGroupItem } from '@/lib/registry/default/ui/toggle-group'
</script>
<template>
<ToggleGroup type="multiple" size="sm">
<ToggleGroupItem value="bold" aria-label="Toggle bold">
<Bold class="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="italic" aria-label="Toggle italic">
<Italic class="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="underline" aria-label="Toggle underline">
<Underline class="h-4 w-4" />
</ToggleGroupItem>
</ToggleGroup>
</template>

View File

@ -0,0 +1,38 @@
<script lang="ts">
import type { VariantProps } from 'class-variance-authority'
import type { ToggleGroupRootEmits, ToggleGroupRootProps } from 'radix-vue'
</script>
<script setup lang="ts">
import { type HTMLAttributes, computed, provide } from 'vue'
import { ToggleGroupRoot, useForwardPropsEmits } from 'radix-vue'
import type { toggleVariants } from '@/lib/registry/default/ui/toggle'
import { cn } from '@/lib/utils'
type ToggleGroupVariants = VariantProps<typeof toggleVariants>
const props = defineProps<ToggleGroupRootProps & {
class?: HTMLAttributes['class']
variant?: ToggleGroupVariants['variant']
size?: ToggleGroupVariants['size']
}>()
const emits = defineEmits<ToggleGroupRootEmits>()
provide('toggleGroup', {
variant: props.variant,
size: props.size,
})
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps.value, emits)
</script>
<template>
<ToggleGroupRoot v-bind="forwarded" :class="cn('flex items-center justify-center gap-1', props.class)">
<slot />
</ToggleGroupRoot>
</template>

View File

@ -0,0 +1,39 @@
<script lang="ts">
import type { VariantProps } from 'class-variance-authority'
import type { ToggleGroupItemProps } from 'radix-vue'
</script>
<script setup lang="ts">
import { type HTMLAttributes, computed, inject } from 'vue'
import { ToggleGroupItem, useForwardProps } from 'radix-vue'
import { toggleVariants } from '@/lib/registry/default/ui/toggle'
import { cn } from '@/lib/utils'
type ToggleGroupVariants = VariantProps<typeof toggleVariants>
const props = defineProps<ToggleGroupItemProps & {
class?: HTMLAttributes['class']
variant?: ToggleGroupVariants['variant']
size?: ToggleGroupVariants['size']
}>()
const context = inject<ToggleGroupVariants>('toggleGroup')
const delegatedProps = computed(() => {
const { class: _, variant, size, ...delegated } = props
return delegated
})
const forwardedProps = useForwardProps(delegatedProps.value)
</script>
<template>
<ToggleGroupItem
v-bind="forwardedProps" :class="cn(toggleVariants({
variant: context?.variant || variant,
size: context?.size || size,
}), props.class)"
>
<slot />
</ToggleGroupItem>
</template>

View File

@ -0,0 +1,2 @@
export { default as ToggleGroup } from './ToggleGroup.vue'
export { default as ToggleGroupItem } from './ToggleGroupItem.vue'

View File

@ -0,0 +1,23 @@
<script setup lang="ts">
import {
FontBoldIcon,
FontItalicIcon,
UnderlineIcon,
} from '@radix-icons/vue'
import { ToggleGroup, ToggleGroupItem } from '@/lib/registry/new-york/ui/toggle-group'
</script>
<template>
<ToggleGroup type="multiple">
<ToggleGroupItem value="bold" aria-label="Toggle bold">
<FontBoldIcon class="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="italic" aria-label="Toggle italic">
<FontItalicIcon class="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="underline" aria-label="Toggle underline">
<UnderlineIcon class="h-4 w-4" />
</ToggleGroupItem>
</ToggleGroup>
</template>

View File

@ -0,0 +1,23 @@
<script setup lang="ts">
import {
FontBoldIcon,
FontItalicIcon,
UnderlineIcon,
} from '@radix-icons/vue'
import { ToggleGroup, ToggleGroupItem } from '@/lib/registry/new-york/ui/toggle-group'
</script>
<template>
<ToggleGroup type="multiple" disabled>
<ToggleGroupItem value="bold" aria-label="Toggle bold">
<FontBoldIcon class="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="italic" aria-label="Toggle italic">
<FontItalicIcon class="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="underline" aria-label="Toggle underline">
<UnderlineIcon class="h-4 w-4" />
</ToggleGroupItem>
</ToggleGroup>
</template>

View File

@ -0,0 +1,23 @@
<script setup lang="ts">
import {
FontBoldIcon,
FontItalicIcon,
UnderlineIcon,
} from '@radix-icons/vue'
import { ToggleGroup, ToggleGroupItem } from '@/lib/registry/new-york/ui/toggle-group'
</script>
<template>
<ToggleGroup type="multiple" size="lg">
<ToggleGroupItem value="bold" aria-label="Toggle bold">
<FontBoldIcon class="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="italic" aria-label="Toggle italic">
<FontItalicIcon class="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="underline" aria-label="Toggle underline">
<UnderlineIcon class="h-4 w-4" />
</ToggleGroupItem>
</ToggleGroup>
</template>

View File

@ -0,0 +1,23 @@
<script setup lang="ts">
import {
FontBoldIcon,
FontItalicIcon,
UnderlineIcon,
} from '@radix-icons/vue'
import { ToggleGroup, ToggleGroupItem } from '@/lib/registry/new-york/ui/toggle-group'
</script>
<template>
<ToggleGroup type="multiple" variant="outline">
<ToggleGroupItem value="bold" aria-label="Toggle bold">
<FontBoldIcon class="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="italic" aria-label="Toggle italic">
<FontItalicIcon class="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="underline" aria-label="Toggle underline">
<UnderlineIcon class="h-4 w-4" />
</ToggleGroupItem>
</ToggleGroup>
</template>

View File

@ -0,0 +1,23 @@
<script setup lang="ts">
import {
FontBoldIcon,
FontItalicIcon,
UnderlineIcon,
} from '@radix-icons/vue'
import { ToggleGroup, ToggleGroupItem } from '@/lib/registry/new-york/ui/toggle-group'
</script>
<template>
<ToggleGroup type="single">
<ToggleGroupItem value="bold" aria-label="Toggle bold">
<FontBoldIcon class="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="italic" aria-label="Toggle italic">
<FontItalicIcon class="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="underline" aria-label="Toggle underline">
<UnderlineIcon class="h-4 w-4" />
</ToggleGroupItem>
</ToggleGroup>
</template>

View File

@ -0,0 +1,23 @@
<script setup lang="ts">
import {
FontBoldIcon,
FontItalicIcon,
UnderlineIcon,
} from '@radix-icons/vue'
import { ToggleGroup, ToggleGroupItem } from '@/lib/registry/new-york/ui/toggle-group'
</script>
<template>
<ToggleGroup type="multiple" size="sm">
<ToggleGroupItem value="bold" aria-label="Toggle bold">
<FontBoldIcon class="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="italic" aria-label="Toggle italic">
<FontItalicIcon class="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="underline" aria-label="Toggle underline">
<UnderlineIcon class="h-4 w-4" />
</ToggleGroupItem>
</ToggleGroup>
</template>

View File

@ -0,0 +1,38 @@
<script lang="ts">
import type { VariantProps } from 'class-variance-authority'
import type { ToggleGroupRootEmits, ToggleGroupRootProps } from 'radix-vue'
</script>
<script setup lang="ts">
import { type HTMLAttributes, computed, provide } from 'vue'
import { ToggleGroupRoot, useForwardPropsEmits } from 'radix-vue'
import type { toggleVariants } from '@/lib/registry/new-york/ui/toggle'
import { cn } from '@/lib/utils'
type ToggleGroupVariants = VariantProps<typeof toggleVariants>
const props = defineProps<ToggleGroupRootProps & {
class?: HTMLAttributes['class']
variant?: ToggleGroupVariants['variant']
size?: ToggleGroupVariants['size']
}>()
const emits = defineEmits<ToggleGroupRootEmits>()
provide('toggleGroup', {
variant: props.variant,
size: props.size,
})
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps.value, emits)
</script>
<template>
<ToggleGroupRoot v-bind="forwarded" :class="cn('flex items-center justify-center gap-1', props.class)">
<slot />
</ToggleGroupRoot>
</template>

View File

@ -0,0 +1,39 @@
<script lang="ts">
import type { VariantProps } from 'class-variance-authority'
import type { ToggleGroupItemProps } from 'radix-vue'
</script>
<script setup lang="ts">
import { type HTMLAttributes, computed, inject } from 'vue'
import { ToggleGroupItem, useForwardProps } from 'radix-vue'
import { toggleVariants } from '@/lib/registry/new-york/ui/toggle'
import { cn } from '@/lib/utils'
type ToggleGroupVariants = VariantProps<typeof toggleVariants>
const props = defineProps<ToggleGroupItemProps & {
class?: HTMLAttributes['class']
variant?: ToggleGroupVariants['variant']
size?: ToggleGroupVariants['size']
}>()
const context = inject<ToggleGroupVariants>('toggleGroup')
const delegatedProps = computed(() => {
const { class: _, variant, size, ...delegated } = props
return delegated
})
const forwardedProps = useForwardProps(delegatedProps.value)
</script>
<template>
<ToggleGroupItem
v-bind="forwardedProps" :class="cn(toggleVariants({
variant: context?.variant || variant,
size: context?.size || size,
}), props.class)"
>
<slot />
</ToggleGroupItem>
</template>

View File

@ -0,0 +1,2 @@
export { default as ToggleGroup } from './ToggleGroup.vue'
export { default as ToggleGroupItem } from './ToggleGroupItem.vue'

View File

@ -610,6 +610,19 @@
],
"type": "components:ui"
},
{
"name": "toggle-group",
"dependencies": [],
"registryDependencies": [
"utils"
],
"files": [
"ui/toggle-group/ToggleGroup.vue",
"ui/toggle-group/ToggleGroupItem.vue",
"ui/toggle-group/index.ts"
],
"type": "components:ui"
},
{
"name": "tooltip",
"dependencies": [],
@ -625,4 +638,4 @@
],
"type": "components:ui"
}
]
]