Explicação Geral 🔍
Este arquivo cria um conjunto de componentes de Drawer (painel deslizante) usando a biblioteca Vaul. O Drawer é uma interface onde um painel pode deslizar da parte inferior ou lateral da tela, permitindo a exibição de informações adicionais sem interromper a navegação principal. Ele também proporciona uma experiência acessível para o usuário.
Importação do Vaul e Utilitários 📦
import * as React from "react"
import { Drawer as DrawerPrimitive } from "vaul"
import { cn } from "@/lib/utils"
- React: Biblioteca principal para a criação de componentes em JavaScript.
- DrawerPrimitive: A implementação básica do componente Drawer da biblioteca Vaul.
- cn: Função utilitária para adicionar classes condicionalmente (normalmente usada para manipular classes CSS).
Componente Principal Drawer 🎛️
const Drawer = ({
shouldScaleBackground = true,
...props
}) => (
<DrawerPrimitive.Root shouldScaleBackground={shouldScaleBackground} {...props} />
)
Drawer.displayName = "Drawer"
- O Drawer é o contêiner principal do componente, que gerencia o estado e a exibição do painel deslizante.
- shouldScaleBackground é uma prop que define se o fundo será escalado ao abrir o drawer. O valor padrão é true.
- displayName define um nome de exibição para o componente, útil para depuração.
Outros Componentes do Drawer 🧳
DrawerTrigger 🚪
const DrawerTrigger = DrawerPrimitive.Trigger
- DrawerTrigger é o componente que ativa o painel deslizante. Pode ser um botão ou outro elemento interativo.
DrawerPortal 🏰
const DrawerPortal = DrawerPrimitive.Portal
- DrawerPortal renderiza o conteúdo do Drawer fora da hierarquia do DOM onde ele foi criado, proporcionando uma melhor performance e acessibilidade.
DrawerClose ❌
const DrawerClose = DrawerPrimitive.Close
- DrawerClose é o componente utilizado para fechar o painel.
DrawerOverlay 🌑
const DrawerOverlay = React.forwardRef(({ className, ...props }, ref) => (
<DrawerPrimitive.Overlay
ref={ref}
className={cn("fixed inset-0 z-50 bg-black/80", className)}
{...props} />
))
DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName
- DrawerOverlay é a camada semitransparente que aparece atrás do Drawer quando ele está aberto.
- forwardRef é usado para encaminhar a referência do componente, permitindo que ele seja manipulado externamente.
DrawerContent 📄
const DrawerContent = React.forwardRef(({ className, children, ...props }, ref) => (
<DrawerPortal>
<DrawerOverlay />
<DrawerPrimitive.Content
ref={ref}
className={cn(
"fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background",
className
)}
{...props}>
<div className="mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted" />
{children}
</DrawerPrimitive.Content>
</DrawerPortal>
))
DrawerContent.displayName = "DrawerContent"
- DrawerContent é o painel principal que contém o conteúdo do Drawer.
- O código inclui uma barra decorativa e permite a adição de conteúdo via children.
DrawerHeader 📑
const DrawerHeader = ({
className,
...props
}) => (
<div
className={cn("grid gap-1.5 p-4 text-center sm:text-left", className)}
{...props} />
)
DrawerHeader.displayName = "DrawerHeader"
- DrawerHeader é a área de cabeçalho do Drawer, geralmente usada para títulos ou informações de contexto.
DrawerFooter 👣
const DrawerFooter = ({
className,
...props
}) => (
<div className={cn("mt-auto flex flex-col gap-2 p-4", className)} {...props} />
)
DrawerFooter.displayName = "DrawerFooter"
- DrawerFooter é a área de rodapé do Drawer, frequentemente usada para botões de ação ou outros controles.
DrawerTitle 📝
const DrawerTitle = React.forwardRef(({ className, ...props }, ref) => (
<DrawerPrimitive.Title
ref={ref}
className={cn("text-lg font-semibold leading-none tracking-tight", className)}
{...props} />
))
DrawerTitle.displayName = DrawerPrimitive.Title.displayName
- DrawerTitle é o componente usado para exibir o título dentro do Drawer.
DrawerDescription 🗣️
const DrawerDescription = React.forwardRef(({ className, ...props }, ref) => (
<DrawerPrimitive.Description
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props} />
))
DrawerDescription.displayName = DrawerPrimitive.Description.displayName
- DrawerDescription fornece uma descrição adicional dentro do Drawer, geralmente usada para explicar o conteúdo ou ação disponível.
Código Completo 🔧
"use client"
import * as React from "react"
import { Drawer as DrawerPrimitive } from "vaul"
import { cn } from "@/lib/utils"
const Drawer = ({
shouldScaleBackground = true,
...props
}) => (
<DrawerPrimitive.Root shouldScaleBackground={shouldScaleBackground} {...props} />
)
Drawer.displayName = "Drawer"
const DrawerTrigger = DrawerPrimitive.Trigger
const DrawerPortal = DrawerPrimitive.Portal
const DrawerClose = DrawerPrimitive.Close
const DrawerOverlay = React.forwardRef(({ className, ...props }, ref) => (
<DrawerPrimitive.Overlay
ref={ref}
className={cn("fixed inset-0 z-50 bg-black/80", className)}
{...props} />
))
DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName
const DrawerContent = React.forwardRef(({ className, children, ...props }, ref) => (
<DrawerPortal>
<DrawerOverlay />
<DrawerPrimitive.Content
ref={ref}
className={cn(
"fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background",
className
)}
{...props}>
<div className="mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted" />
{children}
</DrawerPrimitive.Content>
</DrawerPortal>
))
DrawerContent.displayName = "DrawerContent"
const DrawerHeader = ({
className,
...props
}) => (
<div
className={cn("grid gap-1.5 p-4 text-center sm:text-left", className)}
{...props} />
)
DrawerHeader.displayName = "DrawerHeader"
const DrawerFooter = ({
className,
...props
}) => (
<div className={cn("mt-auto flex flex-col gap-2 p-4", className)} {...props} />
)
DrawerFooter.displayName = "DrawerFooter"
const DrawerTitle = React.forwardRef(({ className, ...props }, ref) => (
<DrawerPrimitive.Title
ref={ref}
className={cn("text-lg font-semibold leading-none tracking-tight", className)}
{...props} />
))
DrawerTitle.displayName = DrawerPrimitive.Title.displayName
const DrawerDescription = React.forwardRef(({ className, ...props }, ref) => (
<DrawerPrimitive.Description
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props} />
))
DrawerDescription.displayName = DrawerPrimitive.Description.displayName
export {
Drawer,
DrawerPortal,
DrawerOverlay,
DrawerTrigger,
DrawerClose,
DrawerContent,
DrawerHeader,
DrawerFooter,
DrawerTitle,
DrawerDescription,
}