抽屉

抽屉是从屏幕边缘滑出的面板。当您需要用户在不离开当前页面的情况下完成任务或查看一些详细信息时,它非常有用。

导入

import {
  Drawer,
  DrawerOverlay,
  DrawerContent,
  DrawerHeader,
  DrawerTitle,
  DrawerCloseButton,
  DrawerBody,
  DrawerFooter,
} from "@resolid/react-ui";
  • Drawer: 为其子级提供上下文的包装器。
  • DrawerOverlay: 抽屉后面的灰度叠加层。
  • DrawerContent: 抽屉内容的容器。
  • DrawerHeader: 抽屉的头部。
  • DrawerTitle: 抽屉的标题。
  • DrawerCloseButton: 关闭抽屉的按钮。
  • DrawerBody: 包含抽屉主要内容的包装器。
  • DrawerFooter: 抽屉的页脚。

基础

const [opened, setOpened] = useState(false);

return (
  <>
    <Button onClick={() => setOpened(true)}>打开抽屉</Button>
    <Drawer opened={opened} onClose={() => setOpened(false)}>
      <DrawerOverlay />
      <DrawerContent className={'w-11/12 md:w-3/5 lg:w-1/3'}>
        <DrawerHeader className={"p-4"}>
          <DrawerTitle>抽屉标题</DrawerTitle>
          <DrawerCloseButton />
        </DrawerHeader>
        <DrawerBody className={'p-1 px-4'}>抽屉内容</DrawerBody>
        <DrawerFooter className={'p-4 flex items-center justify-center gap-5'}>
          <Button onClick={() => setOpened(false)}>关闭</Button>
        </DrawerFooter>
      </DrawerContent>
    </Drawer>
  </>
);

打开位置

const [opened, setOpened] = useState(false);

return (
  <>
    <RadioGroup name="placement" value={placement} onChange={setPlacement}>
      <div className={'flex flex-row gap-5'}>
        <Radio value="top">顶部</Radio>
        <Radio value="bottom">底部</Radio>
        <Radio value="left">左边</Radio>
        <Radio value="right">右边</Radio>
      </div>
    </RadioGroup>
    <Button onClick={() => setOpened(true)}>打开抽屉</Button>
    <Drawer opened={opened} placement={placement} onClose={() => setOpened(false)}>
      <DrawerOverlay />
      <DrawerContent
        className={
          placement == 'left' || placement == 'right'
            ? 'w-11/12 md:w-3/5 lg:w-1/3'
            : 'h-11/12 md:h-3/5 lg:h-1/3'
        }
      >
        <DrawerHeader className={"p-4"}>
          <DrawerTitle>抽屉标题</DrawerTitle>
          <DrawerCloseButton />
        </DrawerHeader>
        <DrawerBody className={'p-1 px-4'}>抽屉内容</DrawerBody>
        <DrawerFooter className={'p-4 flex items-center justify-center gap-5'}>
          <Button onClick={() => setOpened(false)}>关闭</Button>
        </DrawerFooter>
      </DrawerContent>
    </Drawer>
  </>
);

内部滚动条

const [opened, setOpened] = useState(false);
const [scrollBehavior, setScrollBehavior] = useState("inside");

  return (
    <>
      <Button onClick={() => setOpened(true)}>打开抽屉</Button>
      <Drawer opened={opened} onClose={() => setOpened(false)}>
        <DrawerOverlay />
        <DrawerContent className={'w-11/12 md:w-3/5 lg:w-1/3'}>
          <DrawerHeader className={"p-4"}>
            <DrawerTitle>抽屉标题</DrawerTitle>
            <DrawerCloseButton />
          </DrawerHeader>
          <DrawerBody className={'p-1 px-4'}>
            内部大量内容
          </DrawerBody>
          <DrawerFooter className={'p-4 flex items-center justify-center gap-5'}>
            <Button onClick={() => setOpened(false)}>关闭</Button>
          </DrawerFooter>
        </DrawerContent>
      </Drawer>
    </>
  );

焦点管理

抽屉打开会自动将焦点设置在第一个可用的元素上(一般默认是关闭按钮),关闭时会自动返回焦点,你可以通过设置 initialFocusfinalFocus 属性来自定义焦点目标

  const [opened, setOpened] = useState(false);
  const initialRef = useRef(null);
  const finalRef = useRef(null);

  return (
    <>
      <Button onClick={() => setOpened(true)}>打开抽屉</Button>
      <Button color={'neutral'} ref={finalRef}>
        键盘关闭抽屉后获得焦点
      </Button>
      <Drawer initialFocus={initialRef} finalFocus={finalRef} opened={opened} onClose={() => setOpened(false)}>
        <DrawerOverlay />
        <DrawerContent className={'w-fit'}>
          <DrawerHeader className={"p-4"}>
            <DrawerTitle>抽屉标题</DrawerTitle>
            <DrawerCloseButton />
          </DrawerHeader>
          <DrawerBody className={'p-1 px-4 flex flex-col gap-3'}>
            <div className={'flex flex-row items-center'}>
              <label htmlFor={'username'} className={'w-28'}>
                用户名 <span className={'text-red-500'}>*</span>
              </label>
              <Input ref={initialRef} placeholder={'用户名'} id={'username'} />
            </div>
            <div className={'flex flex-row items-center'}>
              <label htmlFor={'email'} className={'w-28'}>
                电子邮箱 <span className={'text-red-500'}>*</span>
              </label>
              <Input placeholder={'电子邮箱'} id={'email'} />
            </div>
          </DrawerBody>
          <DrawerFooter className={'p-4 flex items-center justify-center gap-5'}>
            <Button onClick={() => setOpened(false)}>关闭</Button>
          </DrawerFooter>
        </DrawerContent>
      </Drawer>
    </>
  );

自定义背景样式

  const OverlayBlur = () => <DrawerOverlay className="backdrop-blur-sm" />;
  const OverlayHueRotate = () => <DrawerOverlay className="backdrop-hue-rotate-30" />;

  const [opened, setOpened] = useState(false);
  const [overlay, setOverlay] = useState(<OverlayBlur />);

  return (
    <>
      <Button onClick={() => { setOverlay(<OverlayBlur />); setOpened(true); }}>
        模糊样式
      </Button>
      <Button onClick={() => { setOverlay(<OverlayHueRotate />); setOpened(true); }}>
        调色样式
      </Button>
      <Drawer opened={opened} onClose={() => setOpened(false)}>
        {overlay}
        <DrawerContent className={'w-11/12 md:w-3/5 lg:w-1/3'}>
          <DrawerHeader className={"p-4"}>
            <DrawerTitle>抽屉标题</DrawerTitle>
            <DrawerCloseButton />
          </DrawerHeader>
          <DrawerBody className={'p-1 px-4'}>抽屉内容</DrawerBody>
          <DrawerFooter className={'p-4 flex items-center justify-center gap-5'}>
            <Button onClick={() => setOpened(false)}>关闭</Button>
          </DrawerFooter>
        </DrawerContent>
      </Drawer>
    </>
  );

属性

属性opened类型boolean默认值-必须true
属性onClose类型() => void默认值-必须true
属性centered类型boolean默认值-必须false
属性initialFocus类型number | RefObject<HTMLElement>默认值-必须false
属性finalFocus类型RefObject<HTMLElement>默认值-必须false
属性onCloseComplete类型() => void默认值-必须false
属性closeOnEsc类型boolean默认值true必须false
属性closeOnBlur类型boolean默认值true必须false
属性duration类型number默认值'250'必须false
属性placement类型"left" | "right" | "bottom" | "top"默认值'right'必须false