Skip to content

Commit

Permalink
Merge pull request #974 from tszhong0411/pack-33-add-toggle-group
Browse files Browse the repository at this point in the history
Add Toggle Group
  • Loading branch information
tszhong0411 authored Jan 14, 2025
2 parents 66ea167 + 0686557 commit 4a761f8
Show file tree
Hide file tree
Showing 13 changed files with 261 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/famous-emus-work.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tszhong0411/ui': patch
---

Add Toggle Group
46 changes: 46 additions & 0 deletions apps/docs/src/app/ui/components/toggle-group.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
title: Toggle Group
description: A set of two-state buttons that can be toggled on or off.
---

<ComponentPreview name='toggle-group/toggle-group' />

## Usage

```tsx
import { ToggleGroup, ToggleGroupItem } from '@tszhong0411/ui'
```

```tsx
<ToggleGroup type='single'>
<ToggleGroupItem value='a'>A</ToggleGroupItem>
<ToggleGroupItem value='b'>B</ToggleGroupItem>
<ToggleGroupItem value='c'>C</ToggleGroupItem>
</ToggleGroup>
```

## Examples

### Default

<ComponentPreview name='toggle-group/toggle-group' />

### Outline

<ComponentPreview name='toggle-group/outline' />

### Single

<ComponentPreview name='toggle-group/single' />

### Small

<ComponentPreview name='toggle-group/small' />

### Large

<ComponentPreview name='toggle-group/large' />

### Disabled

<ComponentPreview name='toggle-group/disabled' />
20 changes: 20 additions & 0 deletions apps/docs/src/components/demos/toggle-group/disabled.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { ToggleGroup, ToggleGroupItem } from '@tszhong0411/ui'
import { BoldIcon, ItalicIcon, UnderlineIcon } from 'lucide-react'

const ToggleGroupDisabledDemo = () => {
return (
<ToggleGroup type='multiple' disabled>
<ToggleGroupItem value='bold' aria-label='Toggle bold'>
<BoldIcon className='size-4' />
</ToggleGroupItem>
<ToggleGroupItem value='italic' aria-label='Toggle italic'>
<ItalicIcon className='size-4' />
</ToggleGroupItem>
<ToggleGroupItem value='underline' aria-label='Toggle underline'>
<UnderlineIcon className='size-4' />
</ToggleGroupItem>
</ToggleGroup>
)
}

export default ToggleGroupDisabledDemo
20 changes: 20 additions & 0 deletions apps/docs/src/components/demos/toggle-group/large.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { ToggleGroup, ToggleGroupItem } from '@tszhong0411/ui'
import { BoldIcon, ItalicIcon, UnderlineIcon } from 'lucide-react'

const ToggleGroupLargeDemo = () => {
return (
<ToggleGroup size='lg' type='multiple'>
<ToggleGroupItem value='bold' aria-label='Toggle bold'>
<BoldIcon className='size-4' />
</ToggleGroupItem>
<ToggleGroupItem value='italic' aria-label='Toggle italic'>
<ItalicIcon className='size-4' />
</ToggleGroupItem>
<ToggleGroupItem value='underline' aria-label='Toggle underline'>
<UnderlineIcon className='size-4' />
</ToggleGroupItem>
</ToggleGroup>
)
}

export default ToggleGroupLargeDemo
20 changes: 20 additions & 0 deletions apps/docs/src/components/demos/toggle-group/outline.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { ToggleGroup, ToggleGroupItem } from '@tszhong0411/ui'
import { BoldIcon, ItalicIcon, UnderlineIcon } from 'lucide-react'

const ToggleGroupOutlineDemo = () => {
return (
<ToggleGroup variant='outline' type='multiple'>
<ToggleGroupItem value='bold' aria-label='Toggle bold'>
<BoldIcon className='size-4' />
</ToggleGroupItem>
<ToggleGroupItem value='italic' aria-label='Toggle italic'>
<ItalicIcon className='size-4' />
</ToggleGroupItem>
<ToggleGroupItem value='underline' aria-label='Toggle underline'>
<UnderlineIcon className='size-4' />
</ToggleGroupItem>
</ToggleGroup>
)
}

export default ToggleGroupOutlineDemo
20 changes: 20 additions & 0 deletions apps/docs/src/components/demos/toggle-group/single.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { ToggleGroup, ToggleGroupItem } from '@tszhong0411/ui'
import { BoldIcon, ItalicIcon, UnderlineIcon } from 'lucide-react'

const ToggleGroupSingleDemo = () => {
return (
<ToggleGroup type='single'>
<ToggleGroupItem value='bold' aria-label='Toggle bold'>
<BoldIcon className='size-4' />
</ToggleGroupItem>
<ToggleGroupItem value='italic' aria-label='Toggle italic'>
<ItalicIcon className='size-4' />
</ToggleGroupItem>
<ToggleGroupItem value='underline' aria-label='Toggle underline'>
<UnderlineIcon className='size-4' />
</ToggleGroupItem>
</ToggleGroup>
)
}

export default ToggleGroupSingleDemo
20 changes: 20 additions & 0 deletions apps/docs/src/components/demos/toggle-group/small.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { ToggleGroup, ToggleGroupItem } from '@tszhong0411/ui'
import { BoldIcon, ItalicIcon, UnderlineIcon } from 'lucide-react'

const ToggleGroupSmallDemo = () => {
return (
<ToggleGroup size='sm' type='multiple'>
<ToggleGroupItem value='bold' aria-label='Toggle bold'>
<BoldIcon className='size-4' />
</ToggleGroupItem>
<ToggleGroupItem value='italic' aria-label='Toggle italic'>
<ItalicIcon className='size-4' />
</ToggleGroupItem>
<ToggleGroupItem value='underline' aria-label='Toggle underline'>
<UnderlineIcon className='size-4' />
</ToggleGroupItem>
</ToggleGroup>
)
}

export default ToggleGroupSmallDemo
20 changes: 20 additions & 0 deletions apps/docs/src/components/demos/toggle-group/toggle-group.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { ToggleGroup, ToggleGroupItem } from '@tszhong0411/ui'
import { BoldIcon, ItalicIcon, UnderlineIcon } from 'lucide-react'

const ToggleGroupDemo = () => {
return (
<ToggleGroup type='multiple'>
<ToggleGroupItem value='bold' aria-label='Toggle bold'>
<BoldIcon className='size-4' />
</ToggleGroupItem>
<ToggleGroupItem value='italic' aria-label='Toggle italic'>
<ItalicIcon className='size-4' />
</ToggleGroupItem>
<ToggleGroupItem value='underline' aria-label='Toggle underline'>
<UnderlineIcon className='size-4' />
</ToggleGroupItem>
</ToggleGroup>
)
}

export default ToggleGroupDemo
4 changes: 4 additions & 0 deletions apps/docs/src/config/links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,10 @@ const COMPONENT_LINKS = [
href: '/ui/components/toaster',
text: 'Toaster'
},
{
href: '/ui/components/toggle-group',
text: 'Toggle Group'
},
{
href: '/ui/components/toggle',
text: 'Toggle'
Expand Down
1 change: 1 addition & 0 deletions packages/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"@radix-ui/react-switch": "^1.1.2",
"@radix-ui/react-tabs": "^1.1.2",
"@radix-ui/react-toggle": "^1.1.1",
"@radix-ui/react-toggle-group": "^1.1.1",
"@radix-ui/react-tooltip": "^1.1.6",
"@radix-ui/react-visually-hidden": "^1.1.1",
"class-variance-authority": "^0.7.1",
Expand Down
1 change: 1 addition & 0 deletions packages/ui/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,6 @@ export * from './tabs'
export * from './textarea'
export * from './toaster'
export * from './toggle'
export * from './toggle-group'
export * from './tooltip'
export * from './visually-hidden'
53 changes: 53 additions & 0 deletions packages/ui/src/toggle-group.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
'use client'

import * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group'
import { cn } from '@tszhong0411/utils'
import { type VariantProps } from 'class-variance-authority'
import { createContext, useContext } from 'react'

import { toggleVariants } from './toggle'

const ToggleGroupContext = createContext<VariantProps<typeof toggleVariants>>({
size: 'default',
variant: 'default'
})

type ToggleGroupProps = React.ComponentProps<typeof ToggleGroupPrimitive.Root> &
VariantProps<typeof toggleVariants>

export const ToggleGroup = (props: ToggleGroupProps) => {
const { className, variant, size, children, ...rest } = props

return (
<ToggleGroupPrimitive.Root
className={cn('flex items-center justify-center gap-1', className)}
{...rest}
>
<ToggleGroupContext value={{ variant, size }}>{children}</ToggleGroupContext>
</ToggleGroupPrimitive.Root>
)
}

type ToggleGroupItemProps = React.ComponentProps<typeof ToggleGroupPrimitive.Item> &
VariantProps<typeof toggleVariants>

export const ToggleGroupItem = (props: ToggleGroupItemProps) => {
const { className, children, variant, size, ...rest } = props

const context = useContext(ToggleGroupContext)

return (
<ToggleGroupPrimitive.Item
className={cn(
toggleVariants({
variant: context.variant ?? variant,
size: context.size ?? size
}),
className
)}
{...rest}
>
{children}
</ToggleGroupPrimitive.Item>
)
}
31 changes: 31 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 4a761f8

Please sign in to comment.