Popover
基础反馈基于 Bootstrap 5 的弹窗组件,Popover 渲染标准的弹窗结构(.popover > .popover-arrow + .popover-header + .popover-body),PopoverTrigger 负责触发、延迟、动画与定位,支持四个方向与对齐变体、HTML 内容、CSS 变量定制、click/hover/focus/manual 触发、受控模式、禁用元素与视口翻转
Component Demo
Basic usage and examples of the Popover component
基础用法
默认 trigger 为 `['click']`,placement 为 `'right'`;标题或正文任一非空即可显示,与 Bootstrap 的「title/content 均为空时不显示」行为一致
四个方向
placement 支持 `top`/`right`/`bottom`/`left` 四个方向,RTL 布局下方向自动镜像
对齐变体
每个方向都支持 `-start`/`-end` 对齐变体,与 Bootstrap 的 placement 选项一致
HTML 内容
title 与 content 都是 ReactNode,天然支持富文本内容,无需 Bootstrap 的 `html` 选项
自定义样式
customClass 对应 Bootstrap 的 `customClass` 选项,配合 `--bs-popover-bg` 等 CSS 变量即可定制外观;箭头三角默认跟随 `--bs-popover-header-bg`,修改该变量即可同步换色
禁用元素
禁用元素不触发鼠标事件,需将触发元素包裹在带 `tabIndex=0` 的 `span` 中;给禁用按钮设置 `pointer-events: none` 可让鼠标事件穿透到外层 span(与 Bootstrap 文档一致)
触发方式
`click`/`focus`/`hover` 可单独使用或组合,`manual` 则完全由 `show` 属性控制;弹窗显示时按 Esc 可关闭
延迟与动画
delay 传入数字同时作用于显示与隐藏,或传 `{ show, hide }` 分别设置;动画基于 Bootstrap 的 `fade` 类,并自动响应系统的减少动态效果设置
定位配置
定位基于 `src/utils/position.ts` 计算:offset 调整与触发元素的间距,padding 约束与视口边缘的距离,flip 控制靠近视口边缘时是否翻转方向
受控模式
传入 `show` 后组件变为受控,配合 `trigger="manual"` 完全由外部状态控制显示
单独使用
顶部弹窗
底部弹窗
左侧弹窗
Popover 单独渲染弹窗结构,与 Bootstrap 生成的结构一致(`.popover` 包含 `.popover-arrow`、 `.popover-header` 与 `.popover-body`,标题为空时不渲染 header),也可作为 `overlay` 传给 PopoverTrigger
API Documentation
Complete API reference for the Popover component
Props
Popover
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
animation | boolean | true | 是否渲染 `fade` 类,配合 PopoverTrigger 播放淡入淡出过渡动画 |
arrowProps | HTMLAttributes | - | 透传给箭头元素(`.popover-arrow`)的属性 |
as | ElementType | 'div' | 根元素标签 |
bodyProps | HTMLAttributes | - | 透传给正文元素(`.popover-body`)的属性 |
children | ReactNode | - | 弹窗正文内容,渲染在 `.popover-body` 内 |
className | string | - | 自定义类名,对应 Bootstrap 的 `customClass` 选项 |
flip | boolean | true | `true` 渲染 `bs-popover-auto` 类;`false` 渲染 `bs-popover-{placement}` 静态类。箭头方向始终随 `data-popper-placement`(当前实际位置)变化 |
headerProps | HTMLAttributes | - | 透传给标题元素(`.popover-header`)的属性 |
id | string | - | 弹窗元素 id,供触发元素的 `aria-describedby` 引用 |
placement | Placement | 'right' | 展示位置,仅影响类名与箭头方向,实际定位由 PopoverTrigger 完成 |
show | boolean | true | 是否显示,渲染 `show` 类(配合 `fade` 播放透明度过渡) |
title | ReactNode | - | 弹窗标题,渲染在 `.popover-header` 内;空值不渲染标题元素。存在标题时,箭头三角默认与标题背景色(`--bs-popover-header-bg`)一致 |
PopoverTrigger
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
animation | boolean | true | 是否启用淡入淡出动画,系统开启减少动态效果(prefers-reduced-motion)时自动禁用 |
children | ReactElement | - | 单个触发元素,组件会克隆该元素并注入触发事件与 `aria-describedby` |
content | ReactNode | - | 弹窗正文内容(简写形式),`title` 或 `content` 任一非空即可显示(与 Bootstrap 一致) |
customClass | string | - | 弹窗上的自定义类名,可用于通过 CSS 变量定制外观 |
defaultShow | boolean | false | 非受控模式下的初始显示状态 |
delay | number | PopoverDelay | 0 | 显示/隐藏延迟(毫秒),传入数字同时作用于两者,或传 `{ show, hide }` 分别设置 |
disabled | boolean | false | 是否禁用触发,等价于 Bootstrap 的 `disable()` 方法 |
flip | boolean | true | 靠近视口边缘时是否自动翻转方向 |
id | string | - | 弹窗元素 id,缺省时自动生成 |
offset | [number, number] | '[0, 8]' | 定位偏移 `[水平偏移, 间距]` 元组,对应 Bootstrap 的 `offset` 选项 |
onToggle | (nextShow: boolean) => void | - | 显示状态变化回调,配合 `show` 实现受控模式 |
overlay | ReactElement | - | 自定义覆盖元素(如 `<Popover id="...">`),与 `title`/`content` 二选一,需支持注入 ref、`show`、`placement`、`id` |
padding | number | 2 | 弹窗与视口边缘的最小距离(像素) |
placement | Placement | 'right' | 期望的显示位置,支持 `top`/`right`/`bottom`/`left` 及 `-start`/`-end` 对齐变体 |
show | boolean | - | 受控的显示状态,需配合 `onToggle` 更新 |
title | ReactNode | - | 弹窗标题(简写形式),渲染在 `.popover-header` 内 |
trigger | PopoverTriggerType | PopoverTriggerType[] | ['click'] | 触发方式:`click`/`hover`/`focus`/`manual`,可传入数组组合 |
Type Definitions
PopoverDelay
显示/隐藏延迟配置
export interface PopoverDelay {
hide?: number;
show?: number;
}PopoverProps
弹窗组件属性接口
export interface PopoverProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
animation?: boolean;
arrowProps?: HTMLAttributes<HTMLElement>;
as?: ElementType;
bodyProps?: HTMLAttributes<HTMLElement>;
children?: ReactNode;
className?: string;
flip?: boolean;
headerProps?: HTMLAttributes<HTMLElement>;
id?: string;
placement?: Placement;
show?: boolean;
title?: ReactNode;
}PopoverTriggerProps
弹窗触发器组件属性接口
export interface PopoverTriggerProps {
animation?: boolean;
children: ReactElement;
content?: ReactNode;
customClass?: string;
defaultShow?: boolean;
delay?: number | PopoverDelay;
disabled?: boolean;
flip?: boolean;
id?: string;
offset?: readonly [number, number];
onToggle?: (nextShow: boolean) => void;
overlay?: ReactElement;
padding?: number;
placement?: Placement;
show?: boolean;
title?: ReactNode;
trigger?: PopoverTriggerType | PopoverTriggerType[];
}PopoverTriggerType
触发方式类型
export type PopoverTriggerType = 'click' | 'focus' | 'hover' | 'manual';