Ant Design Notification 自动关闭进度条指南:showProgress 与 pauseOnHover 的完整用法与实现原理
Notification(通知提醒框)是 Ant Design 中用于在屏幕四角展示系统主动推送、复杂内容或需要用户行动点的全局反馈组件。本指南聚焦于 Notification 5.18.0 起提供的自动关闭进度条能力:结合官方演示(demo)显示进度条 与其配套说明文档 show-with-progress.md,讲解如何借助 showProgress 在通知框上渲染一个随自动关闭倒计时填充的进度条,并用 pauseOnHover 控制悬停时是否暂停计时。读完本文,你将掌握进度条的三级配置入口(单条通知 / hooks 实例 / 全局 notification.config)、进度条的底层渲染与样式原理,以及如何对进度条进行定制。
功能概述:为什么需要“自动关闭进度条”
Notification 默认会在 duration(4.5 秒)后自动关闭,方便不打断用户主任务。但自动关闭是“无声”的——用户无法预判这条通知还剩下多少可见时间,尤其是当通知承载了重要的即时信息时,用户可能还没来得及阅读就消失了。
showProgress 正是在这一场景下引入的能力(5.18.0):在通知框底部渲染一条细进度条,直观展示剩余展示时间。与之配套的 pauseOnHover 则控制当鼠标悬停在通知框上时,是否暂停倒计时,从而给用户留出从容阅读与操作的时间。官方对该 demo 的描述仅一句话(show-with-progress.md):
zh-CN:显示自动关闭通知框的进度条。 en-US:Show progress bar for auto-closing notification.
其完整可运行示例位于 components/notification/demo/show-with-progress.tsx,并在 组件文档 中以“显示进度条”demo 的形式对外提供(标注版本 5.18.0)。
基础用法:在通知上开启进度条
推荐方式:useNotification Hook
官方 demo 使用 notification.useNotification() 创建 api 实体,并通过 api.open 传入配置。完整代码如下:
import React from 'react';
import { Button, notification, Space } from 'antd';
const App: React.FC = () => {
const [api, contextHolder] = notification.useNotification();
const openNotification = (pauseOnHover: boolean) => () => {
api.open({
title: 'Notification Title',
description:
'This is the content of the notification. This is the content of the notification. This is the content of the notification.',
showProgress: true,
pauseOnHover,
});
};
return (
<>
{contextHolder}
<Space>
<Button type="primary" onClick={openNotification(true)}>
Pause on hover
</Button>
<Button type="primary" onClick={openNotification(false)}>
Don't pause on hover
</Button>
</Space>
</>
);
};
export default App;
代码要点:
contextHolder必须渲染进组件树:useNotification返回的[api, contextHolder]中,contextHolder需要挂载在 JSX 中(如上例放在按钮之前),进度条等通知内容才真正渲染出来。这一方式也让通知能够读取所在位置的 Context(如ConfigProvider的theme/locale)。showProgress: true是开启进度条的唯一开关,开启后通知框底部会出现随倒计时递减/递增的进度条。pauseOnHover通过按钮动态传入:demo 用同一个openNotification工厂函数按布尔值生成点击回调,从而在同一页面上对比「悬停暂停」与「悬停不暂停」两种交互的差异——这是该 demo 的核心演示目的。
打开方式与单条通知参数
在 components/notification/interface.ts 中,单条通知的配置类型为 ArgsProps,其中与本次主题直接相关的字段如下:
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|---|---|---|---|---|
showProgress |
显示自动关闭通知框的进度条 | boolean |
- | 5.18.0 |
pauseOnHover |
悬停时是否暂停计时器 | boolean |
true |
5.18.0 |
duration |
自动关闭延时(秒),配置为 0 | false 则不会自动关闭 |
number | false |
4.5 |
- |
可见 pauseOnHover 单条级别默认即为 true,而 showProgress 需要显式开启。另外注意:进度条表达的是“自动关闭的倒计时”,因此它是配合 duration 生效的——如果某条通知设置了 duration: 0(不自动关闭),自然也就不存在自动关闭的进度可展示。
打开方式二:静态方法
除 hooks 外,Notification 还提供 notification.open / success / error / info / warning 等静态方法(类型见 interface.ts 中 NotificationInstance 与 StaticFn)。静态方法同样接受 ArgsProps,因此也可在其中传 showProgress 与 pauseOnHover。需要提示的是:antd 官方在文档中已明确“静态方法(不推荐)”用于简单场景,而 hooks 方式能正确处理 Context;需要读取主题或 locale 时请使用 useNotification。
统一配置入口:hooks 实例与全局 notification.config
showProgress / pauseOnHover 并不仅限于单条通知,还可以在两个更高层级统一声明,从而避免重复书写。
useNotification 级配置
notification.useNotification(config) 的 config 支持:
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|---|---|---|---|---|
showProgress |
显示自动关闭通知框的进度条 | boolean |
- | 5.18.0 |
pauseOnHover |
悬停时是否暂停计时器 | boolean |
true |
5.18.0 |
duration |
该实例下通知的默认自动关闭延时 | number |
4.5 |
- |
placement |
弹出位置 | string |
topRight |
- |
stack |
堆叠模式 | boolean | { threshold } |
{ threshold: 3 } |
5.10.0 |
maxCount |
最大显示数 | number |
- | 4.17.0 |
例如要让某个业务区域内的所有通知都带进度条并悬停暂停,可写成:
const [api, contextHolder] = notification.useNotification({
showProgress: true,
pauseOnHover: true,
});
之后通过 api.open(...) 弹出的通知默认即带进度条,除非单条通知内显式覆盖。
全局配置 notification.config
如果希望整个应用(包括静态方法弹出的通知)统一开启进度条,可以使用全局配置 notification.config(options):
notification.config({
placement: 'bottomRight',
bottom: 50,
duration: 3,
showProgress: true,
pauseOnHover: true,
});
该配置的完整字段见 index.zh-CN.md 的 “notification.config” 小节,其中与本主题相关的参数同样为 showProgress(默认 -)与 pauseOnHover(默认 true,均 5.18.0 引入)。从源码结构看,components/notification/index.tsx 维护了模块级 defaultGlobalConfig,静态方法每次调用时都会从其中取出 showProgress、pauseOnHover 等字段合并到通知上下文中,实现“全局一次生效”。
底层实现:倒计时如何驱动一条原生 <progress>
理解参数行为有助于在实际项目中做出正确决策。在 components/notification/useNotification.tsx 中可以看到 antd 对 rc-notification(useRcNotification)的封装:
- 倒计时、悬停暂停、进度条渲染本身由底层
@rc-component/notification完成,antd 通过useRcNotification({ ... duration, pauseOnHover, showProgress })将参数透传(见 useNotification.tsx); duration会先被归一化处理:isNumber(duration) && duration > 0 ? duration : false(useNotification.tsx),非正数一律视为不自动关闭;pauseOnHover在 hooks 实例层面有显式默认值true(useNotification.tsx),与 API 文档中“默认 true”保持一致。
进度条不是用 div 模拟的,而是渲染为原生 <progress> 元素。语义快照(如 demo-semantic 测试快照)中可以看到形如下方的 DOM:
<progress class="ant-notification-notice-progress ..." max="100" value="100"></progress>
antd 在样式层 components/notification/style/notification.ts 对 ${noticeCls}-progress(即 ant-notification-notice-progress)做了视觉定制:
- 绝对定位于通知框底部(
position: absolute; bottom: 0); - 高度由设计 Token
notificationProgressHeight控制,默认2px(见 components/notification/style/index.ts 的 token 生成逻辑); - 宽度为通知内容宽度减去两侧圆角(
calc(100% - borderRadiusLG * 2)),左右留出与borderRadiusLG一致的缩进; - 底色统一为半透明黑
rgba(0, 0, 0, 0.04); - 进度填充色取自 Token
progressBg,并同时兼容 WebKit(::-webkit-progress-bar/::-webkit-progress-value)与 Firefox(::-moz-progress-bar)两类伪元素实现。
这意味着进度条是一个“所见即真实时间”的轻量原生控件,底层倒计时推进 value,从而呈现平滑的关闭倒计时反馈。
样式定制:改高度、改颜色、逐语义结构覆盖
当默认的 2px 进度条不符合视觉要求时,可以分两层定制:
通过组件 Token 调整尺寸与色彩
notificationProgressHeight 控制进度条高度,可在 ConfigProvider 的主题里覆盖 Notification 组件 token:
<ConfigProvider
theme={{
components: {
Notification: {
notificationProgressHeight: 4, // 让进度条更醒目
},
},
}}
>
<App />
</ConfigProvider>
仓库另提供 progress-color.tsx 演示如何自定义进度条颜色(内部通过 showProgress: true 与较长 duration: 20 便于观察),结合上文源码可推断:进度条填充色读取的是进度类颜色 Token progressBg,可通过主题 Token 体系调整其取值,从而改变不同浏览器内核下进度条的颜色。
通过 Semantic DOM 精细化定位
在 6.0.0 引入的语义化结构中,Notification 明确把 progress 列为可定制节点(见 interface.ts 中 NotificationSemanticType 的 classNames/styles 均包含 progress 字段)。这意味着你可以对进度条做“原子级”样式覆盖,例如:
api.open({
title: '带样式覆盖的通知',
showProgress: true,
classNames: { progress: 'my-progress' },
styles: { progress: { height: 6, borderRadius: 3 } },
});
在渲染链路 PureList.tsx 中,showProgress、duration、classNames/styles 会被逐个整理并透传给底层通知项,语义化 class(如 semantic-mark-progress)与进度条原生 class 同时保留,便于测试与精准覆盖。需要说明的是,若仅需统一修改颜色/高度,优先走组件 Token 方案而非逐条覆盖 style。
实测验证:进度条 demo 的自动化保障
antd 为每个官方 demo 都生成了自动化快照测试,进度条 demo 也不例外:
- components/notification/tests/snapshots/demo.test.ts.snap 中保留了
renders components/notification/demo/show-with-progress.tsx correctly的快照,验证渲染出两个主按钮(Pause on hover/Don't pause on hover)及对应结构; - components/notification/tests/snapshots/demo-extend.test.ts.snap 中的
extend context用例则确保 demo 在带ConfigProvider上下文的环境中仍能正常渲染(antd 会自动为渲染结果补充css-var-test-id、acss-*等 hash class)。
此外语义化测试快照 demo-semantic.test.tsx.snap 稳定断言了 <progress class="...-progress semantic-mark-progress" max="100" value="100" /> 的存在。这些测试共同保障了“进度条功能 + demo 代码”在后续迭代中不会静默回归。
实用建议与注意事项
pauseOnHover默认即开启。多数场景下这是更友好的行为——用户鼠标一旦移入通知,倒计时暂停,避免“想点按钮通知却先消失”。只有当你需要通知严格按duration到时消失(例如短时效的提醒),才应显式传入false。- 进度条与自动关闭语义绑定。进度条展示的是自动关闭剩余时间;若通知配置为不自动关闭(
duration: false或0),应避免同时开启showProgress,否则会误导用户。 - 不要依赖进度条的精确像素/颜色还原。它基于浏览器原生
<progress>元素,跨内核表现由 WebKit/Moz 伪元素分别控制;在极旧的浏览器或非标准 UA 下可能出现样式差异,涉及严格视觉还原时请以 style/notification.ts 的 CSS 为准做针对性增强。 - 优先级关系:单条
api.open参数 >useNotification实例配置 > 全局notification.config。全局开启后,个别不需要进度条的通知可在单条上显式关闭(showProgress: false)。 - 需要 Context 时选择 hooks:进度条 demo 统一使用
useNotification,因为静态方法通过动态创建的 React 实体渲染,无法感知调用处的ConfigProvider主题上下文(详见组件文档 FAQ)。若项目中已使用 App 包裹组件,可直接通过App.useApp()获取带 context 的 notification 实例,省去手动挂载contextHolder的步骤。
从 v5.18.0 起,Ant Design 用两个布尔参数加一条原生进度条,低成本地补全了“自动关闭通知”最缺失的可感知反馈。无论是希望在页面级统一切换、还是逐条精细控制,结合本文梳理的三级配置入口与源码级渲染原理,都能在真实项目中稳定落地。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python07
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00