Nested Vaul Drawer
Nested Vaul Drawer is a React and Tailwind CSS overlay component from UI Layouts, licensed MIT. Copy it and paste it into your project.
UI Layouts
MIT
overlays
What it is
Nested Vaul Drawer is a React and Tailwind CSS overlay component from UI Layouts, licensed MIT. Copy it and paste it into your project.
How to use it
Open it in the catalogue, press copy, and paste it into your project. The prompt you copy carries the code and the rules that tell your agent to reproduce it without changing anything.
Five free copies a month. No card.
No packages beyond the project baseline
Licence
This component comes from UI Layouts and is redistributed under the MIT licence, which permits commercial use. The copyright notice travels with the code.
Nested Vaul Drawer
'use client';
import { Drawer } from 'vaul';
export default function MyDrawer() {
return (
<div className='flex justify-center'>
<Drawer.Root shouldScaleBackground>
<Drawer.Trigger asChild>
<button className='inline-flex h-12 w-fit mx-auto animate-background-shine items-center justify-center rounded-md border-2 dark:border-[#656fe2] border-[#c0c6fc] dark:bg-[linear-gradient(110deg,#1e2a78,45%,#3749be,55%,#1e2a78)] bg-[linear-gradient(110deg,#3d5af1,45%,#5471ff,55%,#3d5af1)] bg-size-[200%_100%] dark:hover:border-white px-6 font-medium text-white dark:text-white transition-colors focus:outline-hidden focus:ring-2 dark:focus:ring-neutral-400 focus:ring-offset-2 focus:ring-offset-neutral-50'>
Open Drawer
</button>
</Drawer.Trigger>
<Drawer.Portal>
<Drawer.Overlay className='fixed inset-0 bg-black/40' />
<Drawer.Content className='bg-neutral-100 flex flex-col rounded-t-[10px] h-full mt-24 max-h-[96%] fixed bottom-0 left-0 right-0'>
<div className='p-4 bg-white rounded-t-[10px] flex-1'>
<div className='mx-auto w-12 h-1.5 shrink-0 rounded-full bg-neutral-300 mb-8' />
<div className='max-w-md mx-auto'>
<Drawer.Title className='font-medium mb-4'>Drawer for React.</Drawer.Title>
<p className='text-neutral-600 mb-2'>
This component can be used as a Dialog replacement on mobile and tablet devices.
</p>
<p className='text-neutral-600 mb-2'>
It comes unstyled and has gesture-driven animations.
</p>
<p className='text-neutral-600 mb-6'>
It uses{' '}
<a
href='https://www.radix-ui.com/docs/primitives/components/dialog'
className='underline'
target='_blank'
rel='noreferrer noopener'
>
Radix’s Dialog primitive
</a>{' '}
under the hood and is inspired by{' '}
<a
href='https://twitter.com/devongovett/status/1674470185783402496'
className='underline'
target='_blank'
rel='noreferrer noopener'
>
this tweet.
</a>
</p>
<Drawer.NestedRoot>
<Drawer.Trigger className='rounded-md mb-6 w-full bg-neutral-900 px-3.5 py-2.5 text-sm font-semibold text-white shadow-xs hover:bg-neutral-800 focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-neutral-600'>
Open Second Drawer
</Drawer.Trigger>
<Drawer.Portal>
<Drawer.Overlay className='fixed inset-0 bg-black/40' />
<Drawer.Content className='bg-neutral-100 flex flex-col rounded-t-[10px] h-full mt-24 max-h-[94%] fixed bottom-0 left-0 right-0'>
<div className='p-4 bg-white rounded-t-[10px] flex-1'>
<div className='mx-auto w-12 h-1.5 shrink-0 rounded-full bg-neutral-300 mb-8' />
<div className='max-w-md mx-auto'>
<Drawer.Title className='font-medium mb-4'>
This drawer is nested.
</Drawer.Title>
<p className='text-neutral-600 mb-2'>
Place a{' '}
<span className='font-mono text-[15px] font-semibold'>
`Drawer.NestedRoot`
</span>{' '}
inside another drawer and it will be nested automatically for you.
</p>
<p className='text-neutral-600 mb-2'>
You can view more examples{' '}
<a
href='https://github.com/emilkowalski/vaul#examples'
className='underline'
target='_blank'
rel='noreferrer noopener'
>
here
</a>
.
<Drawer.NestedRoot>
<Drawer.Trigger className='rounded-md mb-6 w-full bg-neutral-900 px-3.5 py-2.5 text-sm font-semibold text-white shadow-xs hover:bg-neutral-800 focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-neutral-600'>
Open third Drawer
</Drawer.Trigger>
<Drawer.Portal>
<Drawer.Overlay className='fixed inset-0 bg-black/40' />
<Drawer.Content className='bg-neutral-100 flex flex-col rounded-t-[10px] h-full mt-24 max-h-[94%] fixed bottom-0 left-0 right-0'>
<div className='p-4 bg-white rounded-t-[10px] flex-1'>
<div className='mx-auto w-12 h-1.5 shrink-0 rounded-full bg-neutral-300 mb-8' />
<div className='max-w-md mx-auto'>
<Drawer.Title className='font-medium mb-4'>
This drawer is nested.
</Drawer.Title>
<p className='text-neutral-600 mb-2'>
Place a{' '}
<span className='font-mono text-[15px] font-semibold'>
`Drawer.NestedRoot`
</span>{' '}
inside another drawer and it will be nested automatically
for you.
</p>
<p className='text-neutral-600 mb-2'>
You can view more examples{' '}
<a
href='https://github.com/emilkowalski/vaul#examples'
className='underline'
target='_blank'
rel='noreferrer noopener'
>
here
</a>
.
</p>
</div>
</div>
<div className='p-4 bg-neutral-100 border-t border-neutral-200 mt-auto'>
<div className='flex gap-6 justify-end max-w-md mx-auto'>
<a
className='text-xs text-neutral-600 flex items-center gap-0.25'
href='https://github.com/emilkowalski/vaul'
target='_blank'
rel='noreferrer noopener'
>
GitHub
<svg
fill='none'
height='16'
stroke='currentColor'
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth='2'
viewBox='0 0 24 24'
width='16'
aria-hidden='true'
className='w-3 h-3 ml-1'
>
<path d='M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6'></path>
<path d='M15 3h6v6'></path>
<path d='M10 14L21 3'></path>
</svg>
</a>
<a
className='text-xs text-neutral-600 flex items-center gap-0.25'
href='https://twitter.com/emilkowalski_'
target='_blank'
rel='noreferrer noopener'
>
Twitter
<svg
fill='none'
height='16'
stroke='currentColor'
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth='2'
viewBox='0 0 24 24'
width='16'
aria-hidden='true'
className='w-3 h-3 ml-1'
>
<path d='M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6'></path>
<path d='M15 3h6v6'></path>
<path d='M10 14L21 3'></path>
</svg>
</a>
</div>
</div>
</Drawer.Content>
</Drawer.Portal>
</Drawer.NestedRoot>
</p>
</div>
</div>
<div className='p-4 bg-neutral-100 border-t border-neutral-200 mt-auto'>
<div className='flex gap-6 justify-end max-w-md mx-auto'>
<a
className='text-xs text-neutral-600 flex items-center gap-0.25'
href='https://github.com/emilkowalski/vaul'
target='_blank'
rel='noreferrer noopener'
>
GitHub
<svg
fill='none'
height='16'
stroke='currentColor'
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth='2'
viewBox='0 0 24 24'
width='16'
aria-hidden='true'
className='w-3 h-3 ml-1'
>
<path d='M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6'></path>
<path d='M15 3h6v6'></path>
<path d='M10 14L21 3'></path>
</svg>
</a>
<a
className='text-xs text-neutral-600 flex items-center gap-0.25'
href='https://twitter.com/emilkowalski_'
target='_blank'
rel='noreferrer noopener'
>
Twitter
<svg
fill='none'
height='16'
stroke='currentColor'
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth='2'
viewBox='0 0 24 24'
width='16'
aria-hidden='true'
className='w-3 h-3 ml-1'
>
<path d='M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6'></path>
<path d='M15 3h6v6'></path>
<path d='M10 14L21 3'></path>
</svg>
</a>
</div>
</div>
</Drawer.Content>
</Drawer.Portal>
</Drawer.NestedRoot>
</div>
</div>
<div className='p-4 bg-neutral-100 border-t border-neutral-200 mt-auto'>
<div className='flex gap-6 justify-end max-w-md mx-auto'>
<a
className='text-xs text-neutral-600 flex items-center gap-0.25'
href='https://github.com/emilkowalski/vaul'
target='_blank'
rel='noreferrer noopener'
>
GitHub
<svg
fill='none'
height='16'
stroke='currentColor'
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth='2'
viewBox='0 0 24 24'
width='16'
aria-hidden='true'
className='w-3 h-3 ml-1'
>
<path d='M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6'></path>
<path d='M15 3h6v6'></path>
<path d='M10 14L21 3'></path>
</svg>
</a>
<a
className='text-xs text-neutral-600 flex items-center gap-0.25'
href='https://twitter.com/emilkowalski_'
target='_blank'
rel='noreferrer noopener'
>
Twitter
<svg
fill='none'
height='16'
stroke='currentColor'
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth='2'
viewBox='0 0 24 24'
width='16'
aria-hidden='true'
className='w-3 h-3 ml-1'
>
<path d='M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6'></path>
<path d='M15 3h6v6'></path>
<path d='M10 14L21 3'></path>
</svg>
</a>
</div>
</div>
</Drawer.Content>
</Drawer.Portal>
</Drawer.Root>
</div>
);
}