Drawer
从屏幕边缘滑入的面板。用于表单、详情或任务面板。
import { Drawer } from 'asterui'基础抽屉
从右侧滑入的简单抽屉。
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 位置
抽屉可以从任何方向滑入。
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 带页脚
页脚中带操作按钮的抽屉。
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 额外头部内容
在头部带额外操作的抽屉。
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 预设尺寸
默认(378px)和大(736px)预设尺寸。
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 加载状态
带骨架加载状态的抽屉。
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 嵌套抽屉
带推动行为的多个抽屉。
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 无遮罩
没有背景遮罩的抽屉。
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 Drawer
Section titled “Drawer”| 属性 | 描述 | 类型 | 默认值 |
|---|---|---|---|
children | 抽屉内容 | React.ReactNode | - |
open | 受控的打开状态 | boolean | false |
onClose | 关闭处理器 | (e?: React.MouseEvent | React.KeyboardEvent) => void | - |
afterOpenChange | 打开/关闭动画完成后的回调 | (open: boolean) => void | - |
title | 抽屉标题 | React.ReactNode | - |
placement | 抽屉位置 | 'left' | 'right' | 'top' | 'bottom' | 'right' |
size | 预设尺寸(378px 或 736px)或自定义数字 | 'default' | 'large' | number | 'default' |
width | 自定义宽度(覆盖左/右的 size) | string | number | - |
height | 自定义高度(覆盖上/下的 size) | string | number | - |
closable | 显示关闭按钮 | boolean | true |
mask | 显示遮罩层 | boolean | true |
maskClosable | 点击遮罩层关闭 | boolean | true |
keyboard | ESC 键关闭 | boolean | true |
footer | 页脚内容 | React.ReactNode | - |
extra | 头部额外内容(右侧) | React.ReactNode | - |
loading | 显示加载骨架 | boolean | false |
destroyOnClose | 关闭时销毁内容 | boolean | false |
forceRender | 预渲染内容(关闭时保留在 DOM 中) | boolean | false |
push | 嵌套抽屉推动行为 | boolean | { distance: number } | { distance: 180 } |
zIndex | 抽屉的 z-index | number | 1000 |
className | 抽屉面板的 CSS 类名 | string | - |