For AI agents: the complete documentation index is available at https://ifhover.github.io/leaf-ui/v/0.6.0/llms.txt, the full documentation bundle is available at https://ifhover.github.io/leaf-ui/v/0.6.0/llms-full.txt, and this page is available as Markdown at https://ifhover.github.io/leaf-ui/v/0.6.0/components/drawer.md.
  • 简体中文
  • Drawer 抽屉

    从页面边缘展开内容,查看详情或完成操作。

    基础用法

    basic.tsx
    import { Button, Drawer, Flex, Form, FormField, Input, Select, Space } from '@ifhover/leaf-ui';
    
    import { useState } from 'react';
    
    export function DrawerBasic() {
      const [placement, setPlacement] = useState<'left' | 'right' | 'top' | 'bottom'>('right');
      const [open, setOpen] = useState(false);
      return (
        <Space direction="vertical" align="stretch">
          <Flex gap="md" align="center" wrap justify="center">
            {(['left', 'right', 'top', 'bottom'] as const).map((side) => (
              <Button
                key={side}
                variant="outline"
                onClick={() => {
                  setPlacement(side);
                  setOpen(true);
                }}
              >
                {side}
              </Button>
            ))}
          </Flex>
          <Drawer
            open={open}
            placement={placement}
            title="项目设置"
            onClose={() => setOpen(false)}
            footer={
              <>
                <Button variant="outline" onClick={() => setOpen(false)}>
                  取消
                </Button>
                <Button type="submit" form="drawer-project">
                  保存
                </Button>
              </>
            }
          >
            <Form
              id="drawer-project"
              onSubmit={(event) => {
                event.preventDefault();
                setOpen(false);
              }}
            >
              <FormField label="项目名称" required>
                <Input name="name" defaultValue="Leaf Garden" />
              </FormField>
              <FormField label="项目类型">
                <Select
                  name="type"
                  defaultValue="design"
                  options={[
                    { value: 'design', label: '设计项目' },
                    { value: 'development', label: '开发项目' },
                  ]}
                />
              </FormField>
            </Form>
          </Drawer>
        </Space>
      );
    }
    

    调整宽度与嵌套推移

    capabilities.tsx
    import { Button, Drawer, Input, Space } from '@ifhover/leaf-ui';
    
    import { useState } from 'react';
    
    export function Capabilities() {
      const [open, setOpen] = useState(false),
        [child, setChild] = useState(false);
      return (
        <>
          <Button onClick={() => setOpen(true)}>
            {'可调整宽度的工作区'}
          </Button>
          <Drawer
            title={'工作区'}
            open={open}
            onClose={() => setOpen(false)}
            resizable
            minSize={260}
            maxSize={640}
          >
            <Space direction="vertical">
              <Input aria-label="Project" />
              <Button onClick={() => setChild(true)}>{'查看详情'}</Button>
            </Space>
            <Drawer
              open={child}
              onClose={() => setChild(false)}
              title={'详情'}
              width={300}
              push={120}
            >
              Details
            </Drawer>
          </Drawer>
        </>
      );
    }
    

    通知偏好

    标题、内容与底部操作分区,适合较长的设置流程。

    sections.tsx
    import { Alert, Button, Drawer, RadioGroup, Space } from '@ifhover/leaf-ui';
    
    import { Bell } from 'lucide-react';
    
    import { useState } from 'react';
    
    export function DrawerSections() {
      
      const [open, setOpen] = useState(false);
      const [frequency, setFrequency] = useState('weekly');
      return (
        <>
          <Button variant="outline" startIcon={<Bell />} onClick={() => setOpen(true)}>
            {'通知偏好'}
          </Button>
          <Drawer
            open={open}
            width={440}
            title={'通知偏好'}
            description={'选择适合你的更新频率。'}
            icon={<Bell />}
            onClose={() => setOpen(false)}
            footer={
              <>
                <Button variant="outline" onClick={() => setOpen(false)}>
                  {'取消'}
                </Button>
                <Button onClick={() => setOpen(false)}>{'保存'}</Button>
              </>
            }
          >
            <Space direction="vertical" align="stretch" size={20}>
              <RadioGroup
                variant="list"
                label={'活动摘要'}
                value={frequency}
                onChange={(event) => setFrequency(event.target.value)}
                options={[
                  {
                    value: 'daily',
                    label: '每日',
                    description: '每天汇总团队动态',
                  },
                  {
                    value: 'weekly',
                    label: '每周',
                    description: '每周一接收一份摘要',
                  },
                  {
                    value: 'off',
                    label: '关闭摘要',
                    description: '仅接收重要提醒',
                  },
                ]}
              />
              <Alert
                type="info"
                title={'重要提醒始终发送'}
                description={'安全事件和需要你处理的事项不会被关闭。'}
              />
            </Space>
          </Drawer>
        </>
      );
    }
    

    Drawer API

    属性类型默认值说明
    initialFocusRefObject<HTMLElement | null> | (() => HTMLElement | null)—指定打开后的初始焦点。
    returnFocusboolean | RefObject<HTMLElement | null> | (() => HTMLElement | null)—关闭后返回原焦点;也可指定目标或设为 false。
    openboolean必填必需。是否展开
    titleReactNode—标题
    descriptionReactNode—补充说明。
    iconReactNode—标题左侧的装饰图标。
    dividedbooleantrue用浅分隔线划分标题、内容和底部操作区。
    footerReactNode—底部内容
    extraReactNode—标题旁的操作内容
    placement'left' | 'right' | 'top' | 'bottom''right'展开方向
    widthnumber | string380左右抽屉宽度
    heightnumber | string300上下抽屉高度
    closablebooleantrue关闭按钮 / 点击遮罩 / Escape 关闭
    maskClosablebooleantrue关闭按钮 / 点击遮罩 / Escape 关闭
    keyboardbooleantrue关闭按钮 / 点击遮罩 / Escape 关闭
    onClose() => void—请求关闭,由应用更新 open
    afterClose() => void—关闭过渡结束后触发
    forceRenderbooleanfalse打开前也挂载内容,关闭时保持隐藏。
    destroyOnClosebooleanfalse关闭过渡完成后卸载内容;默认保留。
    preserveboolean—显式控制关闭后是否保留内容,优先于 destroyOnClose。
    containerElement | DocumentFragment | (() => Element | DocumentFragment)—自定义挂载或滚动容器。
    pushboolean | numberfalse打开嵌套抽屉时推动父弹层,可指定距离。
    resizablebooleanfalse允许拖动和使用方向键调整大小。
    minSizenumber240最小尺寸,单位为像素。
    maxSizenumber900最大尺寸,单位为像素。
    onResize(size: number) => void—大小改变时调用。

    类型

    定义组件属性或组装列表时可导入相关类型。

    import type { DrawerProps } from '@ifhover/leaf-ui';

    使用说明

    通过 footer 放置取消、提交等操作;表单提交按钮可使用 form 属性关联抽屉内的表单。标题为空时请使用 aria-label 提供名称。支持嵌套弹窗和抽屉,关闭后焦点会回到打开位置。

    外观与丰富内容

    description 与 icon 用于说明当前任务。默认标题和底部操作有浅分隔线,底部使用淡灰辅助面;divided={false} 使用留白分区。