Sheet
Extends the Dialog component to display content that complements the main content of the screen.
Installation
Install the following dependencies:
npm install @radix-ui/react-dialog class-variance-authorityCopy and paste the following code into your project.
'use client';
import * as SheetPrimitive from '@radix-ui/react-dialog';
import { cva, type VariantProps } from 'class-variance-authority';
import clsx from 'clsx';
import { X } from 'lucide-react';
import { ComponentPropsWithoutRef, ElementRef, forwardRef, HTMLAttributes } from 'react';
import styles from './styles.module.scss';
const Sheet = SheetPrimitive.Root;
const SheetTrigger = SheetPrimitive.Trigger;
const SheetClose = SheetPrimitive.Close;
const SheetPortal = SheetPrimitive.Portal;
const SheetOverlay = forwardRef<
ElementRef<typeof SheetPrimitive.Overlay>,
ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Overlay className={clsx(styles.sheet__overlay, className)} {...props} ref={ref} />
));
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName;
const sheetVariants = cva(styles.base, {
variants: {
side: {
top: styles.variant__top,
bottom: styles.variant__bottom,
left: styles.variant__left,
right: styles.variant__right,
},
},
defaultVariants: {
side: 'right',
},
});
interface SheetContentProps
extends ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
VariantProps<typeof sheetVariants> {}
const SheetContent = forwardRef<ElementRef<typeof SheetPrimitive.Content>, SheetContentProps>(
({ side = 'right', className, children, ...props }, ref) => (
<SheetPortal>
<SheetOverlay />
<SheetPrimitive.Content ref={ref} className={clsx(sheetVariants({ side }), className)} {...props}>
{children}
<SheetPrimitive.Close className={styles.sheet__content__close}>
<X className={styles.sheet__content__close__icon} />
<span className={styles.sr_only}>Close</span>
</SheetPrimitive.Close>
</SheetPrimitive.Content>
</SheetPortal>
)
);
SheetContent.displayName = SheetPrimitive.Content.displayName;
const SheetHeader = ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => (
<div className={clsx(styles.sheet__header, className)} {...props} />
);
SheetHeader.displayName = 'SheetHeader';
const SheetFooter = ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => (
<div className={clsx(styles.sheet__footer, className)} {...props} />
);
SheetFooter.displayName = 'SheetFooter';
const SheetTitle = forwardRef<
ElementRef<typeof SheetPrimitive.Title>,
ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Title ref={ref} className={clsx(styles.sheet__title, className)} {...props} />
));
SheetTitle.displayName = SheetPrimitive.Title.displayName;
const SheetDescription = forwardRef<
ElementRef<typeof SheetPrimitive.Description>,
ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Description ref={ref} className={clsx(styles.sheet__description, className)} {...props} />
));
SheetDescription.displayName = SheetPrimitive.Description.displayName;
export {
Sheet,
SheetClose,
SheetContent,
SheetDescription,
SheetFooter,
SheetHeader,
SheetOverlay,
SheetPortal,
SheetTitle,
SheetTrigger,
};Update the import paths to match your project setup.
Usage
import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, SheetTrigger } from '@/components/ui/sheet';<Sheet>
<SheetTrigger>Open</SheetTrigger>
<SheetContent>
<SheetHeader>
<SheetTitle>Are you absolutely sure?</SheetTitle>
<SheetDescription>
This action cannot be undone. This will permanently delete your account and remove your data from our
servers.
</SheetDescription>
</SheetHeader>
</SheetContent>
</Sheet>Examples
Side
Use the side property to <SheetContent /> to indicate the edge of the screen where the component will appear. The values can be top, right, bottom or left.
Size
You can adjust the size of the sheet using CSS classes:
<Sheet>
<SheetTrigger>Open</SheetTrigger>
<SheetContent>
<SheetHeader>
<SheetTitle>Are you absolutely sure?</SheetTitle>
<SheetDescription>
This action cannot be undone. This will permanently delete your account and remove your data from our
servers.
</SheetDescription>
</SheetHeader>
</SheetContent>
</Sheet>