zarm
Version:
基于 React 的移动端UI库
290 lines (265 loc) • 13.3 kB
Markdown
# Popper 气泡层
## 基本用法
```jsx
import { useState } from 'react';
import { List, Button, Popper, Select } from 'zarm';
const Demo = () => {
const [visible, setVisible] = useState(false);
const [direction, setDirection] = useState('top');
const [trigger, setTrigger] = useState('click');
const [animationType, setAnimationType] = useState('zoom-fade');
return (
<List>
<List.Item className="basic-demo">
<Popper
content="我是气泡层的内容"
destroy={false}
visible={visible}
trigger={trigger}
direction={direction}
animationType={animationType}
className="custom-content"
>
<Button
theme="primary"
size="xs"
onClick={() => trigger === 'manual' && setVisible(!visible)}
>
点击{visible ? '隐藏' : '显示'}
</Button>
</Popper>
</List.Item>
<List.Item title="显示方向">
<Select
value={direction}
dataSource={[
{ value: 'top-left', label: 'top-left' },
{ value: 'top', label: 'top' },
{ value: 'top-right', label: 'top-right' },
{ value: 'right-top', label: 'right-top' },
{ value: 'right', label: 'right' },
{ value: 'right-bottom', label: 'right-bottom' },
{ value: 'bottom-left', label: 'bottom-left' },
{ value: 'bottom', label: 'bottom' },
{ value: 'bottom-right', label: 'bottom-right' },
{ value: 'left-top', label: 'left-top' },
{ value: 'left', label: 'left' },
{ value: 'left-bottom', label: 'left-bottom' },
]}
onConfirm={(selected) => setDirection(selected[0])}
/>
</List.Item>
<List.Item title="动画效果">
<Select
value={animationType}
dataSource={[
{ value: 'zoom-fade', label: '缩放渐显(zoom-fade)' },
{ value: 'menu-slide', label: '菜单拉伸(menu-slide)' },
{ value: 'fade', label: '淡出淡入效果(fade)' },
{ value: 'zoom', label: '缩放效果(zoom)' },
{ value: 'rotate', label: '旋转效果(rotate)' },
{ value: 'door', label: '开关门效果(door)' },
{ value: 'flip', label: '翻转效果(flip)' },
{ value: 'move-up', label: '移出移入效果(move-up)' },
{ value: 'move-down', label: '移出移入效果(move-down)' },
{ value: 'move-left', label: '移出移入效果(move-left)' },
{ value: 'move-right', label: '移出移入效果(move-right)' },
{ value: 'slide-up', label: '滑出滑入效果(slide-up)' },
{ value: 'slide-down', label: '滑出滑入效果(slide-down)' },
{ value: 'slide-left', label: '滑出滑入效果(slide-left)' },
{ value: 'slide-right', label: '滑出滑入效果(slide-right)' },
]}
onConfirm={(selected) => setAnimationType(selected[0])}
/>
</List.Item>
<List.Item title="触发方式">
<Select
value={trigger}
dataSource={[
{ value: 'click', label: '点击状态触发(click)' },
{ value: 'focus', label: '聚焦状态触发(focus)' },
{ value: 'hover', label: '鼠标经过触发(hover)' },
{ value: 'manual', label: '受控触发(manual)' },
{ value: 'contextMenu', label: '右键触发(contextMenu)' },
]}
onConfirm={(selected) => {
setTrigger(selected[0]);
setVisible(false);
}}
/>
</List.Item>
</List>
);
};
ReactDOM.render(<Demo />, mountNode);
```
## 自定义箭头
```jsx
import { useState } from 'react';
import { List, Button, Popper, Radio, Message } from 'zarm';
import { WarningCircle } from '@zarm-design/icons';
const Demo = () => {
const [arrowPointAtCenter, setArrowPointAtCenter] = useState(false);
return (
<List>
<List.Item
suffix={
<Radio.Group
compact
type="button"
value={arrowPointAtCenter}
onChange={setArrowPointAtCenter}
>
<Radio value={false}>跟随方向</Radio>
<Radio value={true}>元素中心</Radio>
</Radio.Group>
}
>
箭头位置
</List.Item>
<List.Item className="direction-demo">
<div>
<div style={{ marginLeft: 60 }}>
<Popper
arrowPointAtCenter={arrowPointAtCenter}
className="custom-arrow-content"
hasArrow
direction="top-left"
content="top-left text"
>
<Button size="xs">TL</Button>
</Popper>
<Popper
arrowPointAtCenter={arrowPointAtCenter}
className="custom-arrow-content"
hasArrow
direction="top"
content="top text"
>
<Button size="xs">Top</Button>
</Popper>
<Popper
arrowPointAtCenter={arrowPointAtCenter}
className="custom-arrow-content"
hasArrow
direction="top-right"
content="top-right text"
>
<Button size="xs">TR</Button>
</Popper>
</div>
<div style={{ width: 60, float: 'left', clear: 'both' }}>
<Popper
arrowPointAtCenter={arrowPointAtCenter}
className="custom-arrow-content"
hasArrow
direction="left-top"
content="left-top text"
>
<Button size="xs">LT</Button>
</Popper>
<Popper
arrowPointAtCenter={arrowPointAtCenter}
className="custom-arrow-content"
hasArrow
direction="left"
content="left text"
>
<Button size="xs">Left</Button>
</Popper>
<Popper
arrowPointAtCenter={arrowPointAtCenter}
className="custom-arrow-content"
hasArrow
direction="left-bottom"
content="left-bottom text"
>
<Button size="xs">LB</Button>
</Popper>
</div>
<div style={{ width: 60, marginLeft: 60 * 4 + 20 }}>
<Popper
arrowPointAtCenter={arrowPointAtCenter}
className="custom-arrow-content"
hasArrow
direction="right-top"
content="right-top text"
>
<Button size="xs">RT</Button>
</Popper>
<Popper
arrowPointAtCenter={arrowPointAtCenter}
className="custom-arrow-content"
hasArrow
direction="right"
content="right text"
>
<Button size="xs">Right</Button>
</Popper>
<Popper
arrowPointAtCenter={arrowPointAtCenter}
className="custom-arrow-content"
hasArrow
direction="right-bottom"
content="right-bottom text"
>
<Button size="xs">RB</Button>
</Popper>
</div>
<div style={{ marginLeft: 60, clear: 'both' }}>
<Popper
arrowPointAtCenter={arrowPointAtCenter}
className="custom-arrow-content"
hasArrow
direction="bottom-left"
content="bottom-left text"
>
<Button size="xs">BL</Button>
</Popper>
<Popper
arrowPointAtCenter={arrowPointAtCenter}
className="custom-arrow-content"
hasArrow
direction="bottom"
content="bottom text"
>
<Button size="xs">Bottom</Button>
</Popper>
<Popper
arrowPointAtCenter={arrowPointAtCenter}
className="custom-arrow-content"
hasArrow
direction="bottom-right"
content="bottom-right text"
>
<Button size="xs">BR</Button>
</Popper>
</div>
<Message theme="warning" icon={<WarningCircle />}>
左右两侧显示位置不足会自动调整为反向显示
</Message>
</div>
</List.Item>
</List>
);
};
ReactDOM.render(<Demo />, mountNode);
```
## API
| 属性 | 类型 | 默认值 | 说明 |
| :----------------- | :------------------------- | :------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| className | string | - | 气泡层类名追加 |
| content | ReactNode | - | 显示内容 |
| hasArrow | boolean | false | 是否显示箭头节点<font color="red">(注:需要自行定义箭头样式)</font> |
| destroy | boolean | true | 气泡层关闭后是否移除节点 |
| mountContainer | MountContainer | () => document.body | 指定 Popper 挂载的 HTML 节点 |
| animationType | string | 'zoom-fade' | 可选值 `zoom-fade`, `menu-slide`, `fade`, `door`, `flip`, `rotate`, `zoom`,`move-up`, `move-down`, `move-left`, `move-right`,`slide-up`, `slide-down`, `slide-left`, `slide-right` |
| animationDuration | number | 200 | 动画执行时间(单位:毫秒) |
| arrowPointAtCenter | boolean | false | 箭头是否指向目标元素中心 |
| mouseEnterDelay | number | 100 | 鼠标移入显示气泡层的延时时间(单位:毫秒) |
| mouseLeaveDelay | number | 100 | 鼠标移出隐藏气泡层的延时时间(单位:毫秒) |
| direction | string | 'top' | 显示方向,可选值 `top-left`、`top`、`top-right`、`right-top`、`right`、`right-bottom`、`bottom-left`、`bottom`、`bottom-right`、`left-top`、`left`、`left-bottom` |
| trigger | string | 移动端为'click' <br /> 桌面端为'hover' | 触发方式,可选值为:`click` 点击触发状态、`hover` 鼠标经过触发、`focus` 聚焦状态触发、`manual` 受控触发、`contextMenu` 右键触发 |
| visible | boolean | false | 是否显示,`trigger='manual'` 时有效 |
| onVisibleChange | (visible: boolean) => void | () => {} | 显示/隐藏 气泡层触发的事件 |
| |