# Modal

模态弹层基础组件，提供带遮罩的模态行为，可用于拓展 Dialog、模态提示图等更高层组件。

## 适用场景

- 需要遮罩层的模态弹窗基础能力
- 自定义模态内容（非标准 Dialog 场景）
- 局部区域内的模态弹层（指定 portalContainer）

## Props

| 名称 | 类型 | 默认值 | 必填 | 说明 |
|------|------|--------|------|------|
| className | `string` | `""` | 否 | 自定义 class |
| visible | `boolean` | `false` | 否 | 是否显示 |
| onClickMask | `MouseEventHandler<Element>` | `-` | 否 | 点击遮罩的回调 |
| destroyOnHide | `boolean` | `-` | 否 | 是否在隐藏时销毁内容 |
| disablePortal | `boolean` | `-` | 否 | 禁用 popup portal，维持 children in parent DOM 层级 |
| portalContainer | `HTMLElement \| (() => HTMLElement)` | `-` | 否 | 指定 popup portal 挂载的容器，不提供时默认为 document.body |

## 典型用法

### 基础用法

```tsx
const [visible, setVisible] = useState(false)

<Button onClick={() => setVisible(true)} type="important">open</Button>
<Modal visible={visible} onClickMask={() => setVisible(false)}>
    <div className="modal-content-inner">
        <p>模态内容</p>
        <Button onClick={() => setVisible(false)}>点我关闭</Button>
        <span>或点击遮罩关闭</span>
    </div>
</Modal>
```

### 局部模态（指定挂载容器）

> 对于局部模态窗场景，使用 `portalContainer` 指定 modal 挂载的容器，此时 `.brick-modal-wrap, .brick-modal-mask` 会使用 `position: absolute`

```tsx
const [visible, setVisible] = useState(false)
const refContainer = useRef<HTMLDivElement>(null)

<Button onClick={() => setVisible(true)}>open</Button>
<div className={'portal-container'} ref={refContainer}>
    A Portal Container
</div>
<Modal
    portalContainer={refContainer.current}
    visible={visible}
    onClickMask={() => setVisible(false)}
>
    <div className="modal-content-inner">局部模态内容</div>
</Modal>
```

## 注意事项

- Modal 是基础组件，一般业务场景推荐使用更高层的 Dialog 组件
- 使用 `portalContainer` 实现局部模态时，容器需设置 `position` 为非 `static`（如 `position: relative`）
- Modal 显示时会给 body 添加 `overflow: hidden` 以阻止背景滚动
