Skip to content

Commit

Permalink
Merge pull request #943 from tszhong0411/pack-19-add-drawer
Browse files Browse the repository at this point in the history
Add drawer
  • Loading branch information
tszhong0411 authored Jan 9, 2025
2 parents 1d1844f + 161ad7e commit 998f011
Show file tree
Hide file tree
Showing 11 changed files with 570 additions and 39 deletions.
5 changes: 5 additions & 0 deletions .changeset/three-apples-appear.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tszhong0411/ui': patch
---

Add drawer component
1 change: 1 addition & 0 deletions .cspell/libraries.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,6 @@ tsup
turbopack
unifiedjs
usehooks
vaul
vfile
zustand
1 change: 1 addition & 0 deletions apps/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"react": "19.0.0",
"react-dom": "19.0.0",
"react-hook-form": "^7.54.2",
"recharts": "^2.15.0",
"sharp": "^0.33.5",
"shiki": "^1.24.4",
"zod": "^3.24.1"
Expand Down
3 changes: 2 additions & 1 deletion apps/docs/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ const Layout = (props: LayoutProps) => {
className={cn(GeistSans.variable, GeistMono.variable, 'scroll-smooth')}
suppressHydrationWarning
>
<body>
{/* eslint-disable-next-line @eslint-react/dom/no-unknown-property -- custom attribute */}
<body vaul-drawer-wrapper=''>
<Providers>
{children}
<Toaster />
Expand Down
39 changes: 39 additions & 0 deletions apps/docs/src/app/ui/components/drawer.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
title: Drawer
description: A drawer component for React.
---

<ComponentPreview name='drawer/drawer' />

## Usage

```tsx
import {
Drawer,
DrawerClose,
DrawerContent,
DrawerDescription,
DrawerFooter,
DrawerHeader,
DrawerTitle,
DrawerTrigger
} from '@tszhong0411/ui'
```

```tsx
<Drawer>
<DrawerTrigger>Open</DrawerTrigger>
<DrawerContent>
<DrawerHeader>
<DrawerTitle>Are you absolutely sure?</DrawerTitle>
<DrawerDescription>This action cannot be undone.</DrawerDescription>
</DrawerHeader>
<DrawerFooter>
<Button>Submit</Button>
<DrawerClose>
<Button variant='outline'>Cancel</Button>
</DrawerClose>
</DrawerFooter>
</DrawerContent>
</Drawer>
```
143 changes: 143 additions & 0 deletions apps/docs/src/components/demos/drawer/drawer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
'use client'

import {
Button,
Drawer,
DrawerClose,
DrawerContent,
DrawerDescription,
DrawerFooter,
DrawerHeader,
DrawerTitle,
DrawerTrigger
} from '@tszhong0411/ui'
import { MinusIcon, PlusIcon } from 'lucide-react'
import { useState } from 'react'
import { Bar, BarChart, ResponsiveContainer } from 'recharts'

const data = [
{
goal: 400
},
{
goal: 300
},
{
goal: 200
},
{
goal: 300
},
{
goal: 200
},
{
goal: 278
},
{
goal: 189
},
{
goal: 239
},
{
goal: 300
},
{
goal: 200
},
{
goal: 278
},
{
goal: 189
},
{
goal: 349
}
]

const DrawerDemo = () => {
const [goal, setGoal] = useState(350)

const onClick = (adjustment: number) => {
setGoal(Math.max(200, Math.min(400, goal + adjustment)))
}

return (
<Drawer>
<DrawerTrigger asChild>
<Button variant='outline' type='button'>
Open Drawer
</Button>
</DrawerTrigger>
<DrawerContent>
<div className='mx-auto w-full max-w-sm'>
<DrawerHeader>
<DrawerTitle>Move Goal</DrawerTitle>
<DrawerDescription>Set your daily activity goal.</DrawerDescription>
</DrawerHeader>
<div className='p-4 pb-0'>
<div className='flex items-center justify-center space-x-2'>
<Button
variant='outline'
size='icon'
className='size-8 shrink-0 rounded-full'
onClick={() => {
onClick(-10)
}}
disabled={goal <= 200}
type='button'
>
<MinusIcon />
<span className='sr-only'>Decrease</span>
</Button>
<div className='flex-1 text-center'>
<div className='text-7xl font-bold tracking-tighter'>{goal}</div>
<div className='text-muted-foreground text-[0.70rem] uppercase'>Calories/day</div>
</div>
<Button
variant='outline'
size='icon'
className='size-8 shrink-0 rounded-full'
onClick={() => {
onClick(10)
}}
disabled={goal >= 400}
type='button'
>
<PlusIcon />
<span className='sr-only'>Increase</span>
</Button>
</div>
<div className='mt-3 h-[120px]'>
<ResponsiveContainer width='100%' height='100%'>
<BarChart data={data}>
<Bar
dataKey='goal'
style={
{
fill: 'hsl(var(--foreground))',
opacity: 0.9
} as React.CSSProperties
}
/>
</BarChart>
</ResponsiveContainer>
</div>
</div>
<DrawerFooter>
<Button type='button'>Submit</Button>
<DrawerClose asChild>
<Button variant='outline' type='button'>
Cancel
</Button>
</DrawerClose>
</DrawerFooter>
</div>
</DrawerContent>
</Drawer>
)
}

export default DrawerDemo
4 changes: 4 additions & 0 deletions apps/docs/src/config/links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ export const SIDEBAR_LINKS: SidebarLinks = [
href: '/ui/components/dialog',
text: 'Dialog'
},
{
href: '/ui/components/drawer',
text: 'Drawer'
},
{
href: '/ui/components/dropdown-menu',
text: 'Dropdown Menu'
Expand Down
3 changes: 2 additions & 1 deletion packages/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@
"react-hook-form": "^7.54.2",
"react-resizable-panels": "^2.1.7",
"react-textarea-autosize": "^8.5.6",
"sonner": "1.7.1"
"sonner": "1.7.1",
"vaul": "^1.1.2"
},
"peerDependencies": {
"@tanstack/react-table": "^8",
Expand Down
93 changes: 93 additions & 0 deletions packages/ui/src/drawer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
'use client'

import { cn } from '@tszhong0411/utils'
import { Drawer as DrawerPrimitive } from 'vaul'

type DrawerProps = React.ComponentProps<typeof DrawerPrimitive.Root>

export const Drawer = (props: DrawerProps) => {
const { shouldScaleBackground = true, ...rest } = props

return <DrawerPrimitive.Root shouldScaleBackground={shouldScaleBackground} {...rest} />
}

export const DrawerTrigger = DrawerPrimitive.Trigger
export const DrawerPortal = DrawerPrimitive.Portal
export const DrawerClose = DrawerPrimitive.Close

type DrawerOverlayProps = React.ComponentProps<typeof DrawerPrimitive.Overlay>

export const DrawerOverlay = (props: DrawerOverlayProps) => {
const { className, ...rest } = props

return (
<DrawerPrimitive.Overlay
className={cn('fixed inset-0 z-50 bg-black/80', className)}
{...rest}
/>
)
}

type DrawerContentProps = React.ComponentProps<typeof DrawerPrimitive.Content>

export const DrawerContent = (props: DrawerContentProps) => {
const { className, children, ...rest } = props

return (
<DrawerPortal>
<DrawerOverlay />
<DrawerPrimitive.Content
className={cn(
'bg-background fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border',
className
)}
{...rest}
>
<div className='bg-muted mx-auto mt-4 h-2 w-[100px] rounded-full' />
{children}
</DrawerPrimitive.Content>
</DrawerPortal>
)
}

type DrawerHeaderProps = React.ComponentProps<'div'>

export const DrawerHeader = (props: DrawerHeaderProps) => {
const { className, ...rest } = props

return <div className={cn('grid gap-1.5 p-4 text-center sm:text-left', className)} {...rest} />
}

type DrawerFooterProps = React.ComponentProps<'div'>

export const DrawerFooter = (props: DrawerFooterProps) => {
const { className, ...rest } = props

return <div className={cn('mt-auto flex flex-col gap-2 p-4', className)} {...rest} />
}

type DrawerTitleProps = React.ComponentProps<typeof DrawerPrimitive.Title>

export const DrawerTitle = (props: DrawerTitleProps) => {
const { className, ...rest } = props

return (
<DrawerPrimitive.Title
className={cn('text-lg font-semibold leading-none tracking-tight', className)}
{...rest}
/>
)
}

type DrawerDescriptionProps = React.ComponentProps<typeof DrawerPrimitive.Description>

export const DrawerDescription = (props: DrawerDescriptionProps) => {
const { className, ...rest } = props

return (
<DrawerPrimitive.Description
className={cn('text-muted-foreground text-sm', className)}
{...rest}
/>
)
}
1 change: 1 addition & 0 deletions packages/ui/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export * from './command'
export * from './context-menu'
export * from './data-table'
export * from './dialog'
export * from './drawer'
export * from './dropdown-menu'
export * from './files'
export * from './form'
Expand Down
Loading

0 comments on commit 998f011

Please sign in to comment.