Offcanvas
Painel que desliza a partir da borda direita sobre um backdrop, usado para conteúdo secundário como filtros, detalhes ou formulários sem sair da página atual. É construído sobre o Radix Dialog, então prende o foco e fecha com Esc e com clique fora.
Exemplos
Padrão
A largura padrão é 400px (como no Figma), com animação de entrada e saída e botão de fechar.
Controlado
Use open e onOpenChange para abrir e fechar o offcanvas a partir do seu próprio estado.
Largura e largura mínima personalizadas
width, minWidth e maxWidth aceitam números (px) ou qualquer medida CSS ("50vw", "32rem"…). O painel nunca passa do espaço disponível.
Redimensionável
Com resizable, o usuário pode arrastar a borda esquerda do painel (ou dar foco nela e usar as setas do teclado) para mudar a largura, respeitando minWidth e maxWidth. A largura redimensionada é descartada quando o painel fecha, então ele reabre com width. Para persistir, controle width com onWidthChange.
Sem botão de fechar
Sem animação
Dentro de um container
No layout do Figma, o backdrop cobre só a área de conteúdo da página (não o header nem a sidebar). Passe o elemento via container para renderizar o offcanvas dentro dele. O elemento precisa ter position: relative.
classNames personalizadas
Cada elemento pode ser estilizado: className (painel), overlayClassName (backdrop), closeButtonClassName e resizeHandleClassName. O respiro de 8px em volta do painel vem da variável CSS --offcanvas-gutter. Para sobrescrever, use uma classe como [--offcanvas-gutter:1rem].
API
Offcanvas
| Propriedade | Tipo | Valores possíveis | Padrão | Descrição |
|---|---|---|---|---|
| open | boolean | true, false | - | Controla o estado de aberto (controlado). |
| onOpenChange | (open: boolean) => void | - | - | Chamada quando o estado de aberto muda. |
| defaultOpen | boolean | true, false | false | Estado inicial de aberto quando não controlado. |
| modal | boolean | true, false | true | Quando true, impede a interação com os elementos atrás do offcanvas. |
| ...props | Todas as props do Radix Dialog.Root | - | - | Todas as propriedades nativas do componente Root do Radix UI Dialog. |
OffcanvasContent
| Propriedade | Tipo | Valores possíveis | Padrão | Descrição |
|---|---|---|---|---|
| animated | boolean | true, false | true | Ativa as animações de entrada e saída (slide/fade). |
| showCloseButton | boolean | true, false | true | Renderiza o botão de fechar no canto superior direito. |
| width | number | string | número em px ou medida CSS | 400 | Largura do painel. Limitada ao espaço disponível. |
| minWidth | number | string | número em px ou medida CSS | - | Largura mínima do painel. Nunca passa da largura máxima. |
| maxWidth | number | string | número em px ou medida CSS | espaço disponível | Largura máxima do painel. Sempre limitada ao espaço disponível. |
| resizable | boolean | true, false | false | Permite que o usuário arraste a borda esquerda (ou use as setas do teclado) para redimensionar o painel. A largura redimensionada é descartada quando o painel fecha. |
| onWidthChange | (width: number) => void | - | - | Chamada com a nova largura em px durante o redimensionamento. |
| container | HTMLElement | null | - | document.body | Elemento onde o offcanvas é renderizado. Quando definido, o offcanvas cobre só esse elemento. |
| closeLabel | string | - | "Fechar" | Label acessível do botão de fechar. |
| resizeHandleLabel | string | - | "Redimensionar" | Label acessível da alça de redimensionamento (quando resizable). |
| className | string | - | - | Classes do painel. |
| overlayClassName | string | - | - | Classes do backdrop. |
| closeButtonClassName | string | - | - | Classes do botão de fechar (um Dismiss), mescladas com a posição padrão. |
| resizeHandleClassName | string | - | - | Classes da alça de redimensionamento (quando resizable). |
| ...props | Todas as props do Radix Dialog.Content | - | - | Todas as propriedades nativas do componente Content do Radix UI Dialog. |
OffcanvasHeader, OffcanvasBody, OffcanvasFooter
Slots de layout que seguem a estrutura do Figma: um header fixo (mín. 64px), um body com rolagem e um footer fixo (mín. 64px). Todos aceitam className e as props nativas de div.
OffcanvasTitle, OffcanvasDescription, OffcanvasTrigger, OffcanvasClose
Wrappers estilizados sobre as partes correspondentes do Radix Dialog. OffcanvasTrigger e OffcanvasClose aceitam asChild. OffcanvasOverlay e OffcanvasPortal também são exportados para composições personalizadas; o OffcanvasContent já renderiza os dois.