Drawer
Painel que sobe a partir do rodapé da tela, otimizado para interações mobile
Drawer é um painel que desliza a partir da base da viewport. É construído sobre vaul e oferece gestos nativos de arrastar: o usuário pode puxar a borda superior para fechar, como em apps nativos. Use-o em vez de Sheet quando o conteúdo é principalmente consumido em dispositivos móveis.
'use client';
import {
Button,
Drawer,
DrawerClose,
DrawerContent,
DrawerDescription,
DrawerFooter,
DrawerHeader,
DrawerTitle,
DrawerTrigger,
} from '@uranus-workspace/design-system';
export default function DrawerDefault() {
return (
<Drawer>
<DrawerTrigger asChild>
<Button variant="outline">Ver detalhes do pedido</Button>
</DrawerTrigger>
<DrawerContent>
<div className="mx-auto w-full max-w-md">
<DrawerHeader>
<DrawerTitle>Pedido #4829</DrawerTitle>
<DrawerDescription>
Criado em 14 de abril, com entrega prevista para sexta-feira.
</DrawerDescription>
</DrawerHeader>
<div className="px-4 pb-4 text-sm">
<ul className="divide-y">
<li className="flex justify-between py-2">
<span>Plano Profissional</span>
<span className="font-medium">R$ 149,00</span>
</li>
<li className="flex justify-between py-2">
<span>Assentos adicionais (3)</span>
<span className="font-medium">R$ 87,00</span>
</li>
<li className="flex justify-between py-2 font-semibold">
<span>Total</span>
<span>R$ 236,00</span>
</li>
</ul>
</div>
<DrawerFooter>
<Button>Confirmar pedido</Button>
<DrawerClose asChild>
<Button variant="outline">Fechar</Button>
</DrawerClose>
</DrawerFooter>
</div>
</DrawerContent>
</Drawer>
);
}
Anatomia
- Drawer — raiz que controla o estado. A prop
shouldScaleBackground(ativada por padrão) reduz levemente o fundo enquanto o drawer está aberto. - DrawerTrigger — elemento que abre o drawer.
- DrawerContent — o painel. Já inclui a "handle" cinza no topo.
- DrawerHeader → DrawerTitle + DrawerDescription — título e contexto.
- DrawerFooter — área para ações primárias, sempre empilhadas verticalmente.
- DrawerClose — botão de fechar explícito.
Uso
import {
Button,
Drawer,
DrawerClose,
DrawerContent,
DrawerDescription,
DrawerFooter,
DrawerHeader,
DrawerTitle,
DrawerTrigger,
} from '@uranus-workspace/design-system';
<Drawer>
<DrawerTrigger asChild>
<Button variant="outline">Abrir</Button>
</DrawerTrigger>
<DrawerContent>
<DrawerHeader>
<DrawerTitle>Detalhes do pedido</DrawerTitle>
<DrawerDescription>Criado em 14 de abril.</DrawerDescription>
</DrawerHeader>
<DrawerFooter>
<Button>Confirmar</Button>
<DrawerClose asChild>
<Button variant="outline">Fechar</Button>
</DrawerClose>
</DrawerFooter>
</DrawerContent>
</Drawer>Faça
- Use em fluxos mobile onde o gesto de arrastar é esperado.
- Empilhe ações no
DrawerFooter— a ação primária fica em cima, a de cancelar embaixo, alinhadas à largura total. - Limite a altura do conteúdo para que a "handle" fique sempre visível e alcançável com o polegar.
Não faça
- Não use
Drawercomo navegação principal em desktop — ele bloqueia toda a largura da tela. UseSheetnesses casos. - Não encha o drawer de formulário longo sem scroll — lembre-se de que o usuário pode arrastar para fechar por acidente.
- Não remova a "handle" visual: ela é a afordance que comunica o gesto.
Acessibilidade
vaulexpõerole="dialog"e gerencia trap de foco,Esce retorno de foco ao trigger.DrawerTitleeDrawerDescriptionsão associados ao container viaaria-labelledby/aria-describedbyautomaticamente.- Em dispositivos com teclado, o gesto de arrastar é substituído pelo botão
DrawerClose— por isso ele é obrigatório em qualquer drawer não trivial. - Respeita
prefers-reduced-motion.