抽屉
查看源代码用于渲染从屏幕侧面滑入的内容。
导入
import {
Drawer,
DrawerTrigger,
DrawerPortal,
DrawerBackdrop,
DrawerContent,
DrawerTitle,
DrawerDescription,
DrawerClose,
} from "@resolid/react-ui";
Drawer
: 包含抽屉的所有部分。DrawerTrigger
: 包装将打开抽屉的控件。DrawerPortal
: 当抽屉打开时,将其子项传送到body
中。DrawerBackdrop
: 抽屉打开时覆盖视图惰性部分的层。DrawerContent
: 包含抽屉打开时要呈现的内容。DrawerTitle
: 打开抽屉时要宣布的可访问标题。DrawerDescription
: 打开抽屉时要宣布的可选描述。DrawerClose
: 关闭抽屉的控件。
演示
抽屉默认只有必需的样式,你可以通过 DrawerContent
、DrawerTitle
和 DrawerDescription
的 className
自定义。
import {
Button,
CloseButton,
Drawer,
DrawerBackdrop,
DrawerClose,
DrawerContent,
DrawerDescription,
DrawerPortal,
DrawerTitle,
DrawerTrigger,
} from "@resolid/react-ui";
export default function App() {
return (
<div className={"flex flex-row gap-3"}>
<Drawer>
<DrawerTrigger render={(props) => <Button {...props} />}>打开抽屉</DrawerTrigger>
<DrawerPortal>
<DrawerBackdrop />
<DrawerContent className="w-11/12 md:w-3/5 lg:w-1/3">
<DrawerClose
className={"absolute end-2 top-2 p-1"}
render={(props) => <CloseButton {...props} />}
/>
<DrawerTitle className={"p-4"}>抽屉标题</DrawerTitle>
<DrawerDescription className={"grow p-4 pt-1"}>
这是一个抽屉示例,你可以在这里放置相关的提示信息、确认内容或者操作说明。内容可以根据需求进行修改,以适应不同的业务场景。
</DrawerDescription>
<div className={"flex justify-end gap-4 p-4 pt-1"}>
<DrawerClose
render={(props) => <Button color={"neutral"} variant={"soft"} {...props} />}
>
取消
</DrawerClose>
<Button color={"neutral"}>确定</Button>
</div>
</DrawerContent>
</DrawerPortal>
</Drawer>
</div>
);
}
举例
位置
使用 placement
属性更改抽屉组件的位置,抽屉支持 start
、end
、top
和 bottom
四个位置。
import {
Button,
CloseButton,
Drawer,
DrawerBackdrop,
DrawerClose,
DrawerContent,
DrawerDescription,
DrawerPortal,
DrawerTitle,
DrawerTrigger,
} from "@resolid/react-ui";
export default function App() {
const placements = [
{ value: "top", name: "顶部" },
{ value: "bottom", name: "底部" },
{ value: "start", name: "左边" },
{ value: "end", name: "右边" },
];
return (
<div className={"flex flex-row gap-3"}>
{placements.map((placement) => {
return (
<Drawer key={placement.value} placement={placement.value}>
<DrawerTrigger render={(props) => <Button {...props} />}>
打开{placement.name}抽屉
</DrawerTrigger>
<DrawerPortal>
<DrawerBackdrop />
<DrawerContent
className={
placement.value === "start" || placement.value === "end"
? "w-11/12 md:w-3/5 lg:w-1/3"
: "h-11/12 md:h-3/5 lg:h-1/3"
}
>
<DrawerClose
className={"absolute end-2 top-2 p-1"}
render={(props) => <CloseButton {...props} />}
/>
<DrawerTitle className={"p-4"}>抽屉标题</DrawerTitle>
<DrawerDescription className={"grow p-4 pt-1"}>
这是一个抽屉示例,你可以在这里放置相关的提示信息、确认内容或者操作说明。内容可以根据需求进行修改,以适应不同的业务场景。
</DrawerDescription>
<div className={"flex justify-end gap-4 p-4 pt-1"}>
<DrawerClose
render={(props) => <Button color={"neutral"} variant={"soft"} {...props} />}
>
取消
</DrawerClose>
<Button color={"neutral"}>确定</Button>
</div>
</DrawerContent>
</DrawerPortal>
</Drawer>
);
})}
</div>
);
}
滚动条
抽屉内部支持滚动条
import {
Button,
CloseButton,
Drawer,
DrawerTrigger,
DrawerPortal,
DrawerBackdrop,
DrawerContent,
DrawerTitle,
DrawerDescription,
DrawerClose,
} from "@resolid/react-ui";
export default function App() {
return (
<div className={"flex flex-row items-center gap-5"}>
<Drawer>
<DrawerTrigger render={(props) => <Button {...props} />}>打开抽屉</DrawerTrigger>
<DrawerPortal>
<DrawerBackdrop />
<DrawerContent className="w-11/12 md:w-3/5 lg:w-1/3">
<DrawerClose
className={"absolute end-2 top-2 p-1"}
render={(props) => <CloseButton {...props} />}
/>
<DrawerTitle className={"p-4"}>抽屉标题</DrawerTitle>
<div className={"scrollbar scrollbar-thin flex-1 overflow-y-auto overscroll-contain"}>
<DrawerDescription className={"p-4 pt-1"}>
这是一个抽屉示例,你可以在这里放置相关的提示信息、确认内容或者操作说明。内容可以根据需求进行修改,以适应不同的业务场景。
</DrawerDescription>
<article className={"p-4 py-1"}>
{Array.from({ length: 16 }, (x, i) => i + 1).map((i) => (
<p key={i} className={"mb-4"}>
这是一个演示文本,用于填充内容,以便展示排版效果。你可以根据需要替换为实际内容。
</p>
))}
</article>
</div>
</DrawerContent>
</DrawerPortal>
</Drawer>
</div>
);
}
焦点管理
抽屉打开会自动将焦点设置在第一个可用的元素上(一般默认是关闭按钮),关闭时会自动返回焦点,你可以通过设置 initialFocus
和 finalFocus
属性来自定义焦点目标。
import {
Button,
Drawer,
DrawerTrigger,
DrawerPortal,
DrawerBackdrop,
DrawerContent,
DrawerTitle,
DrawerClose,
Input,
} from "@resolid/react-ui";
import { useRef } from "react";
export default function App() {
const initialRef = useRef(null);
const finalRef = useRef(null);
return (
<div className={"flex flex-row gap-3"}>
<Drawer initialFocus={initialRef} finalFocus={finalRef}>
<DrawerTrigger render={(props) => <Button {...props} />}>打开抽屉</DrawerTrigger>
<Button color={"neutral"} ref={finalRef}>
键盘关闭抽屉后获得焦点
</Button>
<DrawerPortal>
<DrawerBackdrop />
<DrawerContent className="w-11/12 md:w-3/5 lg:w-1/3">
<DrawerTitle className={"p-4"}>抽屉标题</DrawerTitle>
<div className={"flex grow flex-col gap-4 p-4 pt-1"}>
<div className={"flex flex-col gap-1"}>
<label htmlFor={"username"}>姓名</label>
<Input id={"username"} />
</div>
<div className={"flex flex-col gap-1"}>
<label htmlFor={"email"}>邮件</label>
<Input ref={initialRef} id={"email"} />
</div>
</div>
<div className={"flex justify-end gap-4 p-4 pt-1"}>
<DrawerClose
render={(props) => <Button color={"neutral"} variant={"soft"} {...props} />}
>
取消
</DrawerClose>
<Button color={"neutral"}>保存</Button>
</div>
</DrawerContent>
</DrawerPortal>
</Drawer>
</div>
);
}
属性
属性 | 类型 | 默认值 | 必须 | |
---|---|---|---|---|
属性open | 简介 受控打开状态 | 类型boolean | 默认值- | 必须false |
属性defaultOpen | 简介 初始渲染时的默认打开状态 | 类型boolean | 默认值false | 必须false |
属性onOpenChange | 简介 打开状态改变时调用 | 类型(open: boolean) => void | 默认值- | 必须false |
属性initialFocus | 简介 开启后焦点目标 | 类型number | RefObject<HTMLElement> | 默认值- | 必须false |
属性finalFocus | 简介 关闭后焦点目标 | 类型RefObject<HTMLElement> | 默认值- | 必须false |
属性closeOnEscape | 简介 按下 Esc 键时关闭 | 类型boolean | 默认值true | 必须false |
属性closeOnOutsideClick | 简介 单击外部时关闭 | 类型boolean | 默认值true | 必须false |
属性duration | 简介 动画持续时间 | 类型number | 默认值250 | 必须false |
属性placement | 简介 放置位置 | 类型"start" | "end" | "bottom" | "top" | 默认值'right' | 必须false |