Drawer

Overlay

Gaveta com arraste que entra por uma borda da tela, o equivalente ao Sheet pensado para toque.

Carregando

Instalação

Recebe correções por update de versão. O caminho recomendado.

npm i @trdr/ui

import { Drawer } from "@trdr/ui/drawer"

Uso

import { Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader } from "@trdr/ui/drawer"

export function Exemplo() {
  return <Drawer />
}

Props

DrawerTriggerPropsestende React.ButtonHTMLAttributes<HTMLButtonElement>
PropTipoDescrição
asChild?booleanRepassa as props para o filho direto em vez de renderizar seu proprio `button` (padrao Radix Slot).
DrawerClosePropsestende React.ButtonHTMLAttributes<HTMLButtonElement>
PropTipoDescrição
asChild?booleanRepassa as props para o filho direto em vez de renderizar seu proprio `button` (padrao Radix Slot).
DrawerOverlayPropsestende React.HTMLAttributes<HTMLDivElement>
PropTipoDescrição
asChild?booleanRepassa as props para o filho direto em vez de renderizar seu proprio `div` (padrao Radix Slot).
DrawerContentPropsestende React.HTMLAttributes<HTMLDivElement>
PropTipoDescrição
asChild?booleanRepassa as props para o filho direto em vez de renderizar seu proprio `div` (padrao Radix Slot).
DrawerHeaderPropsestende React.HTMLAttributes<HTMLDivElement>
DrawerFooterPropsestende React.HTMLAttributes<HTMLDivElement>
DrawerTitlePropsestende React.HTMLAttributes<HTMLHeadingElement>
PropTipoDescrição
asChild?booleanRepassa as props para o filho direto em vez de renderizar seu proprio `h2` (padrao Radix Slot).
DrawerDescriptionPropsestende React.HTMLAttributes<HTMLParagraphElement>
PropTipoDescrição
asChild?booleanRepassa as props para o filho direto em vez de renderizar seu proprio `p` (padrao Radix Slot).

Quando usar

Use o drawer no lugar do sheet quando a interacao principal e por toque: selecionar um ativo numa lista longa no mobile, abrir opcoes de uma ordem numa tela estreita, qualquer painel secundario onde o usuario provavelmente vai querer arrastar para fechar em vez de procurar um botao "x". Por baixo, o drawer usa a biblioteca vaul, que adiciona o gesto de arraste (com o "puxador" no topo do painel) sobre a mesma base de dialog acessivel do Radix.

Quando nao usar drawer (use Sheet)

Se a superficie e primariamente operada por ponteiro (desktop, mouse, teclado), use Sheet: o gesto de arraste nao acrescenta nada quando nao ha toque, e o sheet nao carrega o custo de biblioteca extra do vaul. Regra pratica: sheet e o painel do mouse, drawer e o painel do dedo. Os dois sao intercambiaveis na API (mesma anatomia de Header/Footer/Title/Description), entao trocar de um para o outro depois nao deveria exigir redesenhar o conteudo de dentro, so o componente que envolve.

Anatomia

  • Drawer: a raiz, controla o estado aberto/fechado. Aceita direction ("bottom" por padrao, tambem "top", "left", "right") e liga shouldScaleBackground por padrao, o efeito de encolher o conteudo de tras (a assinatura visual do drawer mobile).
  • DrawerTrigger (data-slot="drawer-trigger"): abre o painel. Use asChild para o filho virar o trigger.
  • DrawerContent (data-slot="drawer-content"): o painel, dentro de um Portal, com o mesmo scrim do Dialog/Sheet. Inclui o puxador (data-slot="drawer-handle") para o gesto de arraste. A posicao e resolvida pela prop direction do Drawer, nao por uma prop side redundante aqui: o vaul ja marca o proprio conteudo com a direcao internamente.
  • DrawerHeader / DrawerFooter: agrupam titulo/descricao e acoes.
  • DrawerTitle / DrawerDescription: mesma tipografia do Dialog/Sheet.
  • DrawerClose: fecha o painel. Compoe com asChild e o Button do sistema, do mesmo jeito que DialogClose/SheetClose.

Acessibilidade

O vaul renderiza por cima de @radix-ui/react-dialog, entao o painel herda role="dialog", foco preso e fechamento por Escape, igual ao Sheet. O puxador e decorativo (o painel inteiro tambem responde a arraste por padrao), o fechamento por teclado e leitor de tela nunca depende de conseguir arrastar. A animacao de entrada, saida e o scrim ja vem do proprio vaul (via atributos data-vaul-* e uma folha de estilo interna), por isso o DrawerContent nao acrescenta classes de tw-animate-css por cima: duplicaria a transicao que a biblioteca ja aplica.

Slots e tokens

Todo elemento renderizado carrega um data-slot para estilizar partes internas sem depender de classe da biblioteca. Os tokens listados são extraídos do código fonte.

[data-slot="drawer-close"][data-slot="drawer-content"][data-slot="drawer-description"][data-slot="drawer-footer"][data-slot="drawer-handle"][data-slot="drawer-header"][data-slot="drawer-overlay"][data-slot="drawer-title"][data-slot="drawer-trigger"]
9 tokens usados
bg-bg-primarybg-border-strongbg-cardoutline-nonetext-b3text-card-foregroundtext-foregroundtext-h5text-muted-foreground