Skip to content
Nerdfishui
Esc
navigateopen⌘Jpreview
On this page

Drawer

A drawer component for React.

'use client'

import { Button } from '@nerdfish/react/button'
import {
	Drawer,
	DrawerClose,
	DrawerContent,
	DrawerDescription,
	DrawerFooter,
	DrawerHeader,
	DrawerTitle,
	DrawerTrigger,
} from '@nerdfish/react/drawer'
import { Minus, Plus } from 'lucide-react'
import * as React 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,
	},
]

export default function DrawerExample() {
	const [goal, setGoal] = React.useState(350)

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

	return (
		<Drawer>
			<DrawerTrigger asChild>
				<Button variant="outline">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"
								icon
								size="md"
								className="shrink-0"
								onClick={() => onClick(-10)}
								disabled={goal <= 200}
							>
								<Minus />
								<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"
								icon
								size="md"
								className="shrink-0"
								onClick={() => onClick(10)}
								disabled={goal >= 400}
							>
								<Plus />
								<span className="sr-only">Increase</span>
							</Button>
						</div>
						<div className="mt-3 h-30">
							<ResponsiveContainer width="100%" height="100%">
								<BarChart data={data}>
									<Bar
										dataKey="goal"
										style={
											{
												fill: 'var(--color-success)',
												opacity: 0.9,
											} as React.CSSProperties
										}
									/>
								</BarChart>
							</ResponsiveContainer>
						</div>
					</div>
					<DrawerFooter>
						<Button>Submit</Button>
						<DrawerClose asChild>
							<Button variant="outline">Cancel</Button>
						</DrawerClose>
					</DrawerFooter>
				</div>
			</DrawerContent>
		</Drawer>
	)
}

Direction

'use client'

import { Button } from '@nerdfish/react/button'
import {
	Drawer,
	DrawerClose,
	DrawerContent,
	DrawerDescription,
	DrawerFooter,
	DrawerHeader,
	DrawerTitle,
	DrawerTrigger,
} from '@nerdfish/react/drawer'
import { Minus, Plus } from 'lucide-react'
import * as React 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,
	},
]

function DrawerContentContent() {
	const [goal, setGoal] = React.useState(350)

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

	return (
		<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"
						icon
						size="md"
						className="shrink-0"
						onClick={() => onClick(-10)}
						disabled={goal <= 200}
					>
						<Minus />
						<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"
						icon
						size="md"
						className="shrink-0"
						onClick={() => onClick(10)}
						disabled={goal >= 400}
					>
						<Plus />
						<span className="sr-only">Increase</span>
					</Button>
				</div>
				<div className="mt-3 h-30">
					<ResponsiveContainer width="100%" height="100%">
						<BarChart data={data}>
							<Bar
								dataKey="goal"
								style={
									{
										fill: 'var(--color-success)',
										opacity: 0.9,
									} as React.CSSProperties
								}
							/>
						</BarChart>
					</ResponsiveContainer>
				</div>
			</div>
			<DrawerFooter>
				<Button>Submit</Button>
				<DrawerClose asChild>
					<Button variant="outline">Cancel</Button>
				</DrawerClose>
			</DrawerFooter>
		</div>
	)
}

export default function DrawerDirectionExample() {
	return (
		<div className="gap-casual px-friends flex">
			<Drawer direction="bottom">
				<DrawerTrigger asChild>
					<Button variant="outline">Bottom Drawer</Button>
				</DrawerTrigger>
				<DrawerContent>
					<DrawerContentContent />
				</DrawerContent>
			</Drawer>
			<Drawer direction="top">
				<DrawerTrigger asChild>
					<Button variant="outline">Top Drawer</Button>
				</DrawerTrigger>
				<DrawerContent>
					<DrawerContentContent />
				</DrawerContent>
			</Drawer>
			<Drawer direction="left">
				<DrawerTrigger asChild>
					<Button variant="outline">Left Drawer</Button>
				</DrawerTrigger>
				<DrawerContent>
					<DrawerContentContent />
				</DrawerContent>
			</Drawer>
			<Drawer direction="right">
				<DrawerTrigger asChild>
					<Button variant="outline">Right Drawer</Button>
				</DrawerTrigger>
				<DrawerContent>
					<DrawerContentContent />
				</DrawerContent>
			</Drawer>
		</div>
	)
}