Drawer
Um painel que desliza da borda da tela. Use para formulários, detalhes ou painéis de tarefas.
Importação
Seção intitulada “Importação”import { Drawer } from 'asterui'Exemplos
Seção intitulada “Exemplos”Drawer Básico
Drawer simples do lado direito.
import { Drawer, Button } from 'asterui'
import { useState } from 'react'
function App() {
const [open, setOpen] = useState(false)
return (
<Button color="primary" onClick={() => setOpen(true)}>
Open Drawer
</Button>
<Drawer
open={open}
onClose={() => setOpen(false)}
title="Basic Drawer"
>
<p>Drawer content goes here.</p>
</Drawer>
)
}
export default App Posicionamento
Drawer pode deslizar de qualquer direção.
import { Drawer, Button, Space } from 'asterui'
import { useState } from 'react'
function App() {
const [placement, setPlacement] = useState<'left' | 'right' | 'top' | 'bottom'>('right')
const [open, setOpen] = useState(false)
const showDrawer = (p: typeof placement) => {
setPlacement(p)
setOpen(true)
}
return (
<Space direction="horizontal" size="sm" wrap>
<Button onClick={() => showDrawer('left')}>Left</Button>
<Button onClick={() => showDrawer('right')}>Right</Button>
<Button onClick={() => showDrawer('top')}>Top</Button>
<Button onClick={() => showDrawer('bottom')}>Bottom</Button>
</Space>
<Drawer
open={open}
onClose={() => setOpen(false)}
placement={placement}
title={`${placement.charAt(0).toUpperCase() + placement.slice(1)} Drawer`}
>
<p>This drawer slides in from the {placement}.</p>
</Drawer>
)
}
export default App Com Rodapé
Drawer com botões de ação no rodapé.
import { Drawer, Button, Space } from 'asterui'
import { useState } from 'react'
function App() {
const [open, setOpen] = useState(false)
return (
<Button color="primary" onClick={() => setOpen(true)}>
Open Drawer
</Button>
<Drawer
open={open}
onClose={() => setOpen(false)}
title="Edit Profile"
footer={
<Space direction="horizontal" size="sm">
<Button onClick={() => setOpen(false)}>Cancel</Button>
<Button color="primary" onClick={() => setOpen(false)}>
Save
</Button>
</Space>
}
>
<p>Form content would go here...</p>
</Drawer>
)
}
export default App Conteúdo Extra no Cabeçalho
Drawer com ações extras no cabeçalho.
import { Drawer, Button, Space } from 'asterui'
import { useState } from 'react'
function App() {
const [open, setOpen] = useState(false)
return (
<Button color="primary" onClick={() => setOpen(true)}>
Open Drawer
</Button>
<Drawer
open={open}
onClose={() => setOpen(false)}
title="User Details"
extra={
<Space size="xs">
<Button size="sm" variant="ghost">Edit</Button>
<Button size="sm" variant="ghost">Delete</Button>
</Space>
}
>
<p>User information displayed here.</p>
</Drawer>
)
}
export default App Tamanhos Predefinidos
Tamanhos padrão (378px) e grande (736px) predefinidos.
import { Drawer, Button, Space } from 'asterui'
import { useState } from 'react'
function App() {
const [size, setSize] = useState<'default' | 'large'>('default')
const [open, setOpen] = useState(false)
const showDrawer = (s: typeof size) => {
setSize(s)
setOpen(true)
}
return (
<Space direction="horizontal" size="sm">
<Button onClick={() => showDrawer('default')}>Default (378px)</Button>
<Button onClick={() => showDrawer('large')}>Large (736px)</Button>
</Space>
<Drawer
open={open}
onClose={() => setOpen(false)}
title={`${size.charAt(0).toUpperCase() + size.slice(1)} Drawer`}
size={size}
>
<p>This drawer uses the {size} preset size.</p>
</Drawer>
)
}
export default App Estado de Carregamento
Drawer com estado de carregamento skeleton.
import { Drawer, Button } from 'asterui'
import { useState, useEffect } from 'react'
function App() {
const [open, setOpen] = useState(false)
const [loading, setLoading] = useState(true)
useEffect(() => {
if (open) {
setLoading(true)
const timer = setTimeout(() => setLoading(false), 1500)
return () => clearTimeout(timer)
}
}, [open])
return (
<Button color="primary" onClick={() => setOpen(true)}>
Load Data
</Button>
<Drawer
open={open}
onClose={() => setOpen(false)}
title="User Profile"
loading={loading}
>
<div className="space-y-4">
<p><strong>Name:</strong> John Doe</p>
<p><strong>Email:</strong> john@example.com</p>
<p><strong>Role:</strong> Administrator</p>
</div>
</Drawer>
)
}
export default App Drawers Aninhados
Múltiplos drawers com comportamento de empurrar.
import { Drawer, Button } from 'asterui'
import { useState } from 'react'
function App() {
const [open1, setOpen1] = useState(false)
const [open2, setOpen2] = useState(false)
return (
<Button color="primary" onClick={() => setOpen1(true)}>
Open First Drawer
</Button>
<Drawer
open={open1}
onClose={() => setOpen1(false)}
title="First Drawer"
push={{ distance: 180 }}
>
<p>This is the first drawer.</p>
<Button color="secondary" onClick={() => setOpen2(true)}>
Open Second Drawer
</Button>
<Drawer
open={open2}
onClose={() => setOpen2(false)}
title="Second Drawer"
width={400}
>
<p>This is a nested drawer.</p>
<p>Notice how the first drawer pushed back.</p>
</Drawer>
</Drawer>
)
}
export default App Sem Máscara
Drawer sem sobreposição de fundo.
import { Drawer, Button } from 'asterui'
import { useState } from 'react'
function App() {
const [open, setOpen] = useState(false)
return (
<Button color="primary" onClick={() => setOpen(true)}>
Open Drawer
</Button>
<Drawer
open={open}
onClose={() => setOpen(false)}
title="No Mask Drawer"
mask={false}
>
<p>This drawer has no backdrop overlay.</p>
<p>You can still interact with the page behind it.</p>
</Drawer>
)
}
export default App | Propriedade | Descrição | Tipo | Padrão |
|---|---|---|---|
children | Conteúdo do drawer | React.ReactNode | - |
open | Estado aberto controlado | boolean | false |
onClose | Manipulador de fechamento | (e?: React.MouseEvent | React.KeyboardEvent) => void | - |
afterOpenChange | Callback após animação de abrir/fechar completar | (open: boolean) => void | - |
title | Título do drawer | React.ReactNode | - |
placement | Posição do drawer | 'left' | 'right' | 'top' | 'bottom' | 'right' |
size | Tamanho predefinido (378px ou 736px) ou número personalizado | 'default' | 'large' | number | 'default' |
width | Largura personalizada (substitui size para esquerda/direita) | string | number | - |
height | Altura personalizada (substitui size para topo/baixo) | string | number | - |
closable | Mostrar botão de fechar | boolean | true |
mask | Mostrar máscara de sobreposição | boolean | true |
maskClosable | Fechar ao clicar na máscara | boolean | true |
keyboard | Fechar com tecla ESC | boolean | true |
footer | Conteúdo do rodapé | React.ReactNode | - |
extra | Conteúdo extra no cabeçalho (lado direito) | React.ReactNode | - |
loading | Mostrar skeleton de carregamento | boolean | false |
destroyOnClose | Destruir conteúdo ao fechar | boolean | false |
forceRender | Pré-renderizar conteúdo (manter no DOM quando fechado) | boolean | false |
push | Comportamento de empurrar drawer aninhado | boolean | { distance: number } | { distance: 180 } |
zIndex | z-index do drawer | number | 1000 |
className | Classe CSS para painel do drawer | string | - |