Use Vaul on small screens

This commit is contained in:
Sebastien Castiel
2023-12-15 13:05:52 -05:00
parent 95bbcf352f
commit ceb6a7d707
3 changed files with 78 additions and 16 deletions

15
package-lock.json generated
View File

@@ -25,7 +25,7 @@
"clsx": "^2.0.0",
"lucide-react": "^0.290.0",
"nanoid": "^5.0.4",
"next": "^14.0.1",
"next": "14.0.1",
"next-plausible": "^3.12.0",
"next-themes": "^0.2.1",
"next13-progressbar": "^1.1.1",
@@ -36,6 +36,7 @@
"tailwind-merge": "^1.14.0",
"tailwindcss-animate": "^1.0.7",
"uuid": "^9.0.1",
"vaul": "^0.7.9",
"zod": "^3.22.4"
},
"devDependencies": {
@@ -6036,6 +6037,18 @@
"uuid": "dist/bin/uuid"
}
},
"node_modules/vaul": {
"version": "0.7.9",
"resolved": "https://registry.npmjs.org/vaul/-/vaul-0.7.9.tgz",
"integrity": "sha512-RrcnGOHOq/cEU3YpyyZrnjh0H79xMpF3IrHZs9ichvHlpKjLDc4Vwjn4VkuGzeUGrmQ3wamfm/cpdKWpvBIgQw==",
"dependencies": {
"@radix-ui/react-dialog": "^1.0.4"
},
"peerDependencies": {
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
}
},
"node_modules/watchpack": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",

View File

@@ -26,7 +26,7 @@
"clsx": "^2.0.0",
"lucide-react": "^0.290.0",
"nanoid": "^5.0.4",
"next": "^14.0.1",
"next": "14.0.1",
"next-plausible": "^3.12.0",
"next-themes": "^0.2.1",
"next13-progressbar": "^1.1.1",
@@ -37,6 +37,7 @@
"tailwind-merge": "^1.14.0",
"tailwindcss-animate": "^1.0.7",
"uuid": "^9.0.1",
"vaul": "^0.7.9",
"zod": "^3.22.4"
},
"devDependencies": {

View File

@@ -6,26 +6,28 @@ import {
DialogTitle,
} from '@/components/ui/dialog'
import { useRouter } from 'next/navigation'
import { ReactNode, useState } from 'react'
import { ReactNode, useEffect, useState } from 'react'
import { Drawer } from 'vaul'
export function ExpenseModal({
children,
title,
}: {
type Props = {
children: ReactNode
title: ReactNode
}) {
}
export function ExpenseModal(props: Props) {
const size = useTailwindBreakpoint()
if (size === 'xs') {
return <ExpenseVaul {...props} />
} else {
return <ExpenseDialog {...props} />
}
}
export function ExpenseDialog({ children, title }: Props) {
const router = useRouter()
const [open, setOpen] = useState(true)
return (
<Dialog
open={open}
onOpenChange={(open) => {
setOpen(open)
if (!open) router.back()
}}
>
<Dialog open onOpenChange={() => router.back()}>
<DialogContent className="w-full max-w-screen-sm">
<DialogHeader>
<DialogTitle>{title}</DialogTitle>
@@ -35,3 +37,49 @@ export function ExpenseModal({
</Dialog>
)
}
export function ExpenseVaul({ children, title }: Props) {
const router = useRouter()
return (
<Drawer.Root open onClose={() => router.back()}>
<Drawer.Portal>
<Drawer.Title>{title}</Drawer.Title>
<Drawer.Overlay
className="fixed inset-0 bg-background/80 backdrop-blur-sm"
onClick={() => router.back()}
/>
<Drawer.Content className="bg-background border flex flex-col rounded-t-[10px] h-fit mt-24 fixed bottom-0 left-0 right-0 p-4 z-50">
<div className="text-xl font-bold mb-4">{title}</div>
{children}
</Drawer.Content>
</Drawer.Portal>
</Drawer.Root>
)
}
export function useTailwindBreakpoint() {
const [size, setSize] = useState<'xs' | 'sm' | 'md' | 'lg'>('xs')
useEffect(() => {
const handleBreakpointChange = () => {
if (window.innerWidth >= 1200) {
setSize('lg')
} else if (window.innerWidth >= 768) {
setSize('md')
} else if (window.innerWidth >= 640) {
setSize('sm')
} else {
setSize('xs')
}
}
window.addEventListener('resize', handleBreakpointChange)
handleBreakpointChange()
return () => {
window.removeEventListener('resize', handleBreakpointChange)
}
}, [])
return size
}