Material UI 十二月更新全解读:实验室新成员 Alert、头像堆叠与纵向按钮组,以及一月路线图前瞻
本文基于仓库中的月度官方更新公告 december-2019-update.md(发布于 2020-01-07)编写,系统梳理 Material UI 当月发布的重点新特性——Alert 组件、头像堆叠(AvatarGroup)、按钮组纵向排布与国际化语言包扩容,并结合当前仓库 packages/mui-material 下的源码逐项印证,同时带读者回顾下一个月(2020 年 1 月)的组件路线图。读完你将了解这些组件/能力的 API 形态、源码实现要点,以及如何在本仓库中定位它们的演进痕迹。
一次月度更新的全景视图
这份发布于 2020 年 1 月 7 日的月度总结(blog front matter 中 date: 2020-01-07T00:00:00.000Z,作者 oliviertassinari,tags 为 Company)开篇即列出了当月最重要的四组改进:
- 🚨 在 lab(实验室)包中引入全新 [Alert] 组件,并支持与 Snackbar 组合使用(pull request #18702);
- 👤 为头像新增堆叠(stacking)能力;
- ↕️ 为按钮组新增纵向(vertical)排布能力;
- 🌎 支持的本地化(locale)数量从 13 个几乎翻倍到 22 个。
公告同时给出当月工程规模数据:共接受了来自 73 位贡献者的 168 个提交,改动 1,059 个文件,其中 新增 13,468 行、删除 8,584 行。这说明单月发布背后是活跃的社区协作,而非少量内部提交。
需要特别说明:上述特性在 2019 年 12 月发布时对应的版本是 v4 时代的 @material-ui/* 包结构。历经数个主版本演进后,如今这些能力已沉淀在当前仓库的 mui-material 包中,下面的源码对照将以 packages/mui-material 现有实现为准。
全新 Alert 组件:从实验室走向核心的提醒条
当月头条特性是实验室新组件 Alert。在 2019 年 12 月它位于 @material-ui/lab(由社区贡献者 @dimitropoulos 通过 pull request #18702 提交),支持与 Snackbar 组合实现“自定义 Snackbar”的消息反馈场景。如今该组件已毕业进入核心库,源码位于 packages/mui-material/src/Alert/Alert.js。
原公告截图:Alert 的 standard(标准)变体,用于标准/填充/描边三种视觉风格的对照说明。
源码结构印证
从 Alert.js 的实现看,它本质上是对 Paper 的再封装(AlertRoot = styled(Paper)),并内置一套语义化配色体系:
- severity/color 驱动的配色:
useUtilityClasses中通过color${capitalize(color || severity)}生成MuiAlert-colorSuccess、colorError、colorInfo、colorWarning等样式类(见 Alert.js); - 三种变体:
standard、outlined、filled对应源码中三组variants样式映射——standard/outlined 使用调色板light亮度做背景与描边,filled 使用main/dark亮度(见 Alert.js); - 内置语义图标:源码顶部引入
SuccessOutlinedIcon、ReportProblemOutlinedIcon、ErrorOutlineIcon、InfoOutlinedIcon、CloseIcon四类图标,分别对应用户可见的 success/warning/error/info 图标与可关闭场景的关闭按钮(见 Alert.js)。
说明:当前版本对 Alert 的根容器使用
useSlot与 slotProps/slots 机制,支持以root、icon、message、action等 slot 进行细粒度定制,这是相对 2019 年实验室版本的演进。
典型用法
原公告展示的两种渲染形态(standard 与 filled)在今天对应如下写法:
import Alert from '@mui/material/Alert';
// standard 变体(默认),配合四种 severity
<Alert severity="error">This is an error alert — check it out!</Alert>
<Alert severity="warning">This is a warning alert — check it out!</Alert>
<Alert severity="info">This is an info alert — check it out!</Alert>
<Alert severity="success">This is a success alert — check it out!</Alert>
// filled 变体
<Alert variant="filled" severity="success">
This is a filled success alert.
</Alert>
// outlined 变体
<Alert variant="outlined" severity="info">
This is an outlined info alert.
</Alert>
与 Snackbar 的组合
原公告特别指出 Alert“同样支持与 Snackbar 组合使用(customized snackbars)”,这是把表单/操作结果反馈做成轻提示的推荐姿势:
import { Alert, Snackbar } from '@mui/material';
<Snackbar open={open} autoHideDuration={6000} onClose={handleClose}>
<Alert onClose={handleClose} severity="success" sx={{ width: '100%' }}>
This is a success message inside a Snackbar!
</Alert>
</Snackbar>
这样既能复用 Alert 的语义配色与图标,又能获得 Snackbar 的自动隐藏与定位能力。
头像堆叠:AvatarGroup 的引入
第二项新能力是头像的 stacking(堆叠) 支持:将多个头像以相互交叠的方式排成一组,超出部分以 "+N" 形式汇总。
原公告截图:多张头像以负间距交叠排布的效果。
当前实现位于 packages/mui-material/src/AvatarGroup/AvatarGroup.js,从源码可以看到其核心机制:
- 负间距实现交叠:
SPACINGS = { small: -16, medium: -8 },通过 CSS 变量--AvatarGroup-spacing控制marginLeft,flexDirection: 'row-reverse'使交叠方向自右向左(见 AvatarGroup.js); - 每张头像带描边分割:根样式为每个
MuiAvatar-root添加2px的background.default色边框,使交叠处轮廓清晰(见 AvatarGroup.js); - max 与 total 逻辑:
max默认值为 5,表示最多展示几张真实头像,超出数量聚合为+N;total可显式声明总数(默认取 children 长度),便于在懒加载等场景下正确计算盈余数量(见 AvatarGroup.js)。
import Avatar from '@mui/material/Avatar';
import AvatarGroup from '@mui/material/AvatarGroup';
<AvatarGroup max={4} spacing="small">
<Avatar alt="Remy Sharp" src="/static/images/avatar/1.jpg" />
<Avatar alt="Travis Howard" src="/static/images/avatar/2.jpg" />
<Avatar alt="Cindy Baker" src="/static/images/avatar/3.jpg" />
<Avatar alt="Agnes Walker" src="/static/images/avatar/4.jpg" />
<Avatar alt="Trevor Henderson" src="/static/images/avatar/5.jpg" />
</AvatarGroup>
当传入超过 max 的头像时,多余的会折叠成“+N”占位头像;spacing 支持 'small' | 'medium' | number,也可以传入任意数值自定义交叠深度。
按钮组支持纵向排布
第三项改进是 ButtonGroup 的 纵向(vertical) 支持,用于工具条、步骤按钮等需要上下堆叠按钮的场景。
原公告截图:vertical(纵向)模式下的按钮组,按钮自上而下排列。
源码层面,ButtonGroup.js 通过 orientation prop 切换布局:
- 根节点为
inline-flex容器,纵向时设置flexDirection: 'column'; - 通过
firstButton、middleButton、lastButton三组圆角规则消除相邻按钮间多余圆角——纵向模式下首/尾按钮只保留顶部/底部圆角,横向模式则相反(见 ButtonGroup.js)。
import Button from '@mui/material/Button';
import ButtonGroup from '@mui/material/ButtonGroup';
<ButtonGroup orientation="vertical" aria-label="vertical outlined button group">
<Button onClick={() => console.log('One')}>One</Button>
<Button onClick={() => console.log('Two')}>Two</Button>
<Button onClick={() => console.log('Three')}>Three</Button>
</ButtonGroup>
默认的 orientation 为 'horizontal';同时该组件还支持 variant、color、size、disableElevation、fullWidth 等属性,fullWidth 会把容器拉伸为 100% 宽度(见 ButtonGroup.js)。
国际化:支持语言接近翻倍(13 → 22)
第四项是本地化支持的大幅扩容:支持的 locale 从 13 个增长到 22 个,公告同时号召社区“帮我们下个月再翻一倍”。这体现了 MUI 官方对 i18n 的持续投入——组件内置文案(如分页的 aria 标签、日期选择器文本等)均支持按语言切换。
从当前仓库的 packages/mui-material/src/locale/ 目录可以看到,语言包机制已发展为覆盖数十种语言的完整体系(含 zhCN.ts、zhTW.ts、zhHK.ts、jaJP.ts、koKR.ts、deDE.ts、frFR.ts、ptBR.ts、arEG.ts、heIL.ts、ruRU.ts 等),远多于公告当月统计的 22 个,可作为后续社区贡献持续积累的直接证据。
用法示例(以简体中文为例):
import { createTheme, ThemeProvider } from '@mui/material/styles';
import { zhCN } from '@mui/material/locale';
const theme = createTheme({}, zhCN);
function App() {
return <ThemeProvider theme={theme}>{/* 组件树 */}</ThemeProvider>;
}
更完整的语言包接入说明可参见仓库内的 本地化指南。需要提醒的是,语言包只覆盖 Material UI 内置文案;DatePicker 等 MUI X 组件有自己独立的 locale 体系,不属于本指南范围。
2020 年 1 月路线图:Pagination、日期选择器与 Data Grid
公告下半部分用“尽力而为、不作承诺(We'll do our best, no guarantee!)”的口吻预告了下一个月的三项重点工程:
- 💄 新的 Pagination(分页)组件:当时处于 preview 阶段(pull request #19049,由 @mbrookes 主导)。该组件如今已在核心库中稳定落地,源码位于 packages/mui-material/src/Pagination/Pagination.js。它对外渲染为语义化的
<nav>+<ul>结构,核心分页运算抽离为usePaginationhook,并配合PaginationItem完成页码、省略号(ellipsis)、上一页/下一页/首尾页等条目的渲染(见 Pagination.js)。典型用法:
import Pagination from '@mui/material/Pagination';
<Pagination count={10} color="primary" /> // 基础用法
<Pagination count={10} variant="outlined" shape="rounded" /> // 变体与形状
<Pagination count={10} showFirstButton showLastButton /> // 显示首尾按钮
<Pagination count={10} boundaryCount={2} siblingCount={1} /> // 控制页码窗口
从源码可见,boundaryCount(首尾固定展示页码数)、siblingCount(当前页两侧页码数)、showFirstButton/showLastButton、hidePrevButton/hideNextButton 等参数共同决定页码折叠策略(见 Pagination.js)。
-
📅 Date/Time Picker 组件的大版本升级:当时计划补齐桌面端与 range(范围)选择能力(由 @dmtrKovalenko 主导,关联 issue #1293)。这批选择器组件在后续演进中并入 MUI X 产品线,不在本仓库的
packages/源码范围内。 -
🧮 全新的 Data Grid(数据表格)组件:当时同样是可预览状态(pull request #18872,由 @oliviertassinari 主导)。与 Date Picker 相同,Data Grid 后续归属于 MUI X 系列产品,独立于本仓库迭代(仓库中可看到面向 MUI X 的 产品页 与其系列版本博客)。
此外,公告向社区发出明确的“投票”号召:如果有特别想要的能力,请在 GitHub issues 上点赞(👍),点赞数量会直接影响官方对需求的优先级排序。这也是 Material UI 月度迭代风格的一部分——路线图由社区反馈驱动,月度更新公告则把“做了什么、下月做什么”透明地同步给使用者。
延伸阅读
- 原文档案:docs/pages/blog/december-2019-update.md
- Alert 核心实现:packages/mui-material/src/Alert/Alert.js
- AvatarGroup 核心实现:packages/mui-material/src/AvatarGroup/AvatarGroup.js
- ButtonGroup 核心实现(纵向布局):packages/mui-material/src/ButtonGroup/ButtonGroup.js
- Pagination 核心实现:packages/mui-material/src/Pagination/Pagination.js
- 语言包目录:packages/mui-material/src/locale/
- 本地化指南:docs/data/material/guides/localization/localization.md
如果你在自己的项目中使用 Material UI,不妨对照本文的源码路径,从组件入口一路读到样式变体与 hook 逻辑——这通常是理解 MUI 组件“配置项如何转化为实际 DOM 与 CSS”最快的方式。
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


