# Drawer

抽屉组件，从屏幕边缘滑出的浮层面板，支持四个方向、遮罩配置和操作按钮。

## 适用场景

- 展示与当前任务相关的补充信息（只读内容）
- 包含表单操作，需要用户填写后确认或取消
- 需要在不离开当前页面的情况下展开辅助功能

## Props

### Drawer Props

| 名称 | 类型 | 默认值 | 必填 | 说明 |
|------|------|--------|------|------|
| mask | `boolean` | `true` | 否 | 是否有遮罩，无遮罩时可操作抽屉外部区域 |
| maskTransparent | `boolean` | `false` | 否 | 遮罩是否透明（透明遮罩仍为模态，仍会阻隔外部操作） |
| placement | `"top" \| "right" \| "bottom" \| "left"` | `"right"` | 否 | 抽屉弹出方向 |
| width | `number \| "sm" \| "md" \| "lg"` | `"md"` | 否 | 抽屉宽度，在 placement 为 left/right 时有效 |
| height | `number \| "sm" \| "md"` | `"sm"` | 否 | 抽屉高度，在 placement 为 top/bottom 时有效 |
| className | `string` | `-` | 否 | 自定义 class |
| visible | `boolean` | `-` | 否 | 是否显示 |
| destroyOnHide | `boolean` | `-` | 否 | 隐藏时是否销毁内容 |
| disablePortal | `boolean` | `-` | 否 | 禁用 popup portal，维持 children 在父节点 DOM 层级 |
| portalContainer | `HTMLElement \| (() => HTMLElement)` | `-` | 否 | 指定 portal 挂载容器，默认为 document.body |
| size | `"sm" \| "md"` | `-` | 否 | 尺寸，默认读取 ConfigContext `baseSize` |
| headline | `ReactNode` | `-` | 否 | 标题 |
| confirmLabel | `string` | `-` | 否 | 自定义确认按钮文本 |
| cancelLabel | `string` | `-` | 否 | 自定义取消按钮文本 |
| actions | `ReactNode` | `-` | 否 | 自定义操作区 |
| maskCancel | `boolean` | `true` | 否 | 点击蒙层是否触发取消/关闭 |
| actionsAlign | `"right" \| "left" \| "center"` | `-` | 否 | 操作按钮位置，默认读取 ConfigContext `dialogActionsAlign` |
| onConfirm | `DialogAction` | `-` | 否 | 点击确认的回调 |
| onCancel | `DialogAction` | `-` | 否 | 点击取消/关闭的回调 |
| withCloseX | `boolean` | `true` | 否 | 是否显示右上角关闭叉 |
| withCancel | `boolean` | `true` | 否 | 是否有取消按钮（及关闭叉） |

## 典型用法

### 基础只读抽屉

```tsx
import { useState } from 'react'
import { Button } from '@befe/brick-comp-button'
import { Drawer } from '@befe/brick-comp-drawer'

function Demo() {
    const [visible, setVisible] = useState(false)

    return (
        <>
            <Button type={'important'} onClick={() => setVisible(true)}>打开</Button>
            <Drawer
                visible={visible}
                headline={'标题'}
                onCancel={() => setVisible(false)}
            >
                <div>只读内容</div>
            </Drawer>
        </>
    )
}
```

### 带操作按钮的表单抽屉

```tsx
<Drawer
    visible={visible}
    headline={'编辑信息'}
    onConfirm={() => setVisible(false)}
    onCancel={() => setVisible(false)}
    maskCancel={false}
>
    <p>表单内容</p>
</Drawer>
```

### 透明遮罩

```tsx
<Drawer
    visible={visible}
    headline={'标题'}
    onCancel={close}
    maskTransparent={true}
>
    <p>内容</p>
</Drawer>
```

### 无遮罩（可操作外部区域）

```tsx
<Drawer
    visible={visible}
    headline={'标题'}
    onCancel={close}
    mask={false}
>
    <p>内容</p>
</Drawer>
```

### 不同弹出方向

```tsx
<Drawer placement={'left'} visible={visible} onCancel={close}>左侧</Drawer>
<Drawer placement={'top'} visible={visible} onCancel={close}>顶部</Drawer>
<Drawer placement={'bottom'} visible={visible} onCancel={close}>底部</Drawer>
```

## 注意事项

- 标准尺寸（2021 更新）：`sm` = 320px，`md` = 800px，`lg` = 960px
- `width` 设置范围 [320px, 960px]，超出将以边界值处理；`height` 范围 [232px, 680px]
- 含操作按钮（有子操作）的场景，建议 `maskCancel=false` 以防用户误触关闭；同时保留 `withCloseX=true` 保证可关闭
- 设置 `mask=false` 后，`maskTransparent` 和 `maskCancel` 均无意义
- 破坏性变更（2021）：`withClose` 默认值由 `false` 改为 `true`；遮罩默认由全透明改为黑色半透明
