聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

发布一下 0 0
聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

Ant Design V5 已经发布也有一段时间了,作为 V5 设计研发小组成员,在这几个月中我们也第一时间升级了手上的业务应用到 antd v5,并针对实际的业务场景研究了 antd 动态主题的实践用法。截至目前近 3 个月的时间,我们总共完成了 6 个应用/组件/站点的 antd v5 升级改造,且均已支持亮暗色主题切换。并在一些对主题自定义有较强需求的场景下都有了不错的效果(如下):


亮色主题

暗色主题

Kitchen3 插件



@闻冰 / 业务应用

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

Kitchen Measure



@百音 @闻冰 / 业务应用

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

Kitchen 官网



@倏昱 / 业务应用

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

ProComponents



@期贤 / TechUI Pro系组件

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

ProEditor 编辑器



@兼续 / 业务组件

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

Ant Design Style 文档



@闻冰 / 文档应用

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

我个人感受的就是:用了 CSSinJS 之后的 antd 太香了! 正是有了这么多案例的应用验证,我才有信心写下这篇文章,和大家聊聊用 antd v5 可以在主题方面做出什么样的行活与花活。在可以预见的未来,所有动态主题的需求,无论是行活还是花活,我们都能做的轻轻松松~

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

PS:所谓的行活用法,就是无论设计师还是前端同学都可直接体验和使用;而花活用法,就是目前只有用写代码的方式才能实现的方案。(不过其中有些方案可能会在未来给到设计师使用)


行活用法 —— V4 的延展与产品化

由于 antd v5 核心采用了 CssinJS 的方案,因此所有的动态主题配置也都变成了代码里的运行时配置,且从单一的动态主色变成了圆角、字体、阴影等几乎所有样式变量。针对前端同学来说,在 Ant Design 官网的文档( )里也详细展示了基础的用法,我在这里就不赘述了。主要和大家聊聊 V5 里的产品化用法。

通过 Ant Design 的主题编辑器,设计系统的创建者可以非常简单地配出来 antd 的整体风格,并进行实时预览。

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

然后设计师将主题导入到 Kitchen 之后,设计师便可以直接消费主题 Token,同时也可以拖拽获得自定义主题后的 antd 组件。

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

交付设计稿后,基于 C2D2C 的链路,前端同学就能看到设计师使用了哪个 antd 组件,并一键获得 antd 的前端代码。 那如果大家对这部分内容感兴趣,欢迎在这里查看详情: Kitchen v3.2.0 Ant Design V5 动态主题资产来啦~ · 语雀


接下来就全部都是 antd 的花活用法了,由于以下的花活部分目前暂时都只能通过代码实现(部分能力后续可能也会产品化),所以介绍里会涉及到一些代码,但相对来说也还简单。

花活用法 ❶:自定义主题算法

antd 的 token 体系和市面上大部分的 token 体系不同,我们有一个非常重要的因素,它就是——算法。虽然一听算法好像挺高大上的,但它的思想是非常容易理解的:基于基础变量和派生规则来生成一组变量。其中派生规则就是算法。antd 在v4及以前一直有这方面的沉淀,在 v5 中自然把这个能力继承了过来。

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

由于算法的存在,我们就可以传入不同的主题算法,进而获得不同的主题风格效果。例如 TechUI Studio 中,我们通过集成自定义暗色算法,就可以轻松获得独特的暗色风格的主题。

import { theme } from 'antd';import type { MappingAlgorithm } from 'antd/es/config-provider/context';// 定义 studio 暗色模式算法export const studioDarkAlgorithm: MappingAlgorithm = (seedToken, mapToken) => {  // 使用 antd 默认的暗色算法生成基础token,这样其他不需要定制的部分则保持原样  const baseToken = theme.darkAlgorithm(seedToken, mapToken);  return {    ...baseToken,    colorBgLayout: '#20252b', // Layout 背景色    colorBgContainer: '#282c34', // 组件容器背景色     colorBgElevated: '#32363e', // 悬浮容器背景色  };};// 在应用中集成const Container =()=>{  return (    <ConfigProvider theme={{ algorithm: studioDarkAlgorithm }}>      ...    </ConfigProvider>  )}复制代码

最终的效果如下图所示。可以看到我们通过集成主题算法,通过非常少的 token 自定义,就可以实现风格感受很不一样的主题,同时界面的视觉梯度仍然可以保持稳定,不会出现常见的暗色模式翻车的问题。

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

而且通过传入不同的主题算法,我们甚至可以控制组件在不同应用场景下的展示形态。例如在Kitchen中为了让 智能表格编辑器符合 kitchen 的视觉风格,我们通过传入 kitchen 风的 antd 自定义主题算法,就可以让 ProEditor 在 kitchen 中变成另外一个风格。

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

所以单纯一个 v5 的自定义算法,就可以玩出很多花活,而我们后续也会结合 Kitchen Color Studio 色彩生成工具,在 Ant Design 的主题编辑器中集成可供设计师使用的自定义算法功能,让不懂代码的设计师也能轻松生成业务定制的色彩算法。

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

花活用法 ❷:局部主题自定义

自定义主题算法是一个全局风格的调整,接来下再来介绍局部主题的使用。在 v4 及以前,想要 antd 的组件有多套主题同屏的实现难度是非常高的,而在 V5 中,得益于 CSSinJS 的动态主题,多套主题模式同屏展示就变得非常简单。 这在我们的 ProEditor 编辑器、TechUI Studio 平台、Ant Design 的主题预览器都有使用到这些效果。

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

以 Studio 平台的场景为例,这种局部主题设定的核心代码如下:

import { ConfigProvider ,theme } from 'antd';export default () => {  return (  <div>        {/* 暗色模式只需套一个 CP 并设定算法,里面的 Toolbar 就是暗色的了 */ }        <ConfigProvider theme={{ algorithm: theme.darkAlgorithm }}>    	<Toolbar />    </ConfigProvider>        {/* 其余部分默认是亮色 */ }    <ProTableEditor      style={{ height: 'calc(100vh - 40px)' }}    />  </div>  );};复制代码

这样局部主题的定制可以极大程度地提升样式定制的灵活度。像暗色主题的一个泛化是『深色主题』,比较典型的就是类似海兔这样的深色背景头图场景。基于上面写的用法示例,理论上只需做一个「深色主题」算法,就可以实现在不魔改 antd 样式的情况下做到风格兼容。

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

花活用法 ❸:组件级风格自定义

当大家对主题能力切换有了基础的感知之后,我们再来看看组件级别的主题风格定制能力。在 antd v4 及以前,自定义一个 popup 的提示组件是非常难的。 下面则演示了一个需要自定义为主题色的 popup 提示说明(代码示例:codesandbox.io/s/popover-i…)为了达成较好的视觉效果,样式覆写可能会比组件的声明都要多,但仍然难以达到完美状态。 所以 antd v4 才会经常被诟病说很难做自定义。

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

那在 V5 中,使用 ConfigProvider 可以非常简单地完成样式的自定义,且非常符合直觉。

import { theme, Popover, Checkbox, Button, ConfigProvider } from 'antd';export default function App() {  const { token } = theme.useToken();  return (    <ConfigProvider      theme={{        // component 字段可以聚合调整每个组件的 token        components: {          // 将 Popover 的文本颜色设为白色          Popover: { colorText: token.colorTextLightSolid },          // 将 Checkbox 的文本颜色设为白色,主色设为更强一级的颜色          Checkbox: {            colorPrimary: token['blue-7'],            colorText: token.colorTextLightSolid          },          // 将 Button 的颜色设为更强一级的颜色          Button: { colorPrimary: token['blue-7'] }        }      }}    >       ... 业务组件代码    </ConfigProvider>  );}复制代码

产出的效果如下(示例代码:codesandbox.io/s/v5-popove…):

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

基于 CSSinJS 这样的动态能力,我们可以实现在组件样式组合上非常高的灵活度,进而轻松实现一些原本在 V4 中很难达成的自定义样式。

花活用法 ❹:组件的搭配组合

在 antd v4 中,之前被诟病的另一点就是组件的组合性不理想,比如一个典型场景是暗色模式下的弹窗与表格组合使用。可以看到由于暗色模式下 Modal 的底色与页面基础的 Layout 底色不同,最终呈现的感觉就是 table “陷”进去了一层,看起来就会很奇怪。

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

但这种场景在 antd 层面往往无能为力,因为组件本身并不限制业务应用如何使用组件。最后的结果就是应用中的体验细节有瑕疵。如果修正这些瑕疵,在 V4 中可能需要做很多 hack 才能实现,ROI 划不来。 而在 V5 中则可以非常轻松地达到预期的效果。 当然,也是通过 ConfigProvider 的嵌套特性达成。

import React from 'react';import { Modal, ConfigProvider, theme } from 'antd';import Table from './Table';const App: React.FC = () => {  const { token } = theme.useToken();  return (    <div      style={{ background: token.colorBgLayout, padding: 24, height: '100vh' }}    >      <Modal open={true} width={800} title={'在Modal中的表格'}>        <ConfigProvider          theme={{            token: { colorBgContainer: token.colorBgElevated }          }}        >          <Table />        </ConfigProvider>      </Modal>      <Table />    </div>  );};export default App;复制代码

只需在 Modal 中的 table 外层嵌套一个 ConfigProvider 作为夹心层,然后将 token 的 colorBgContainer 参数设为 colorBgElevated,我们就得到了响应 Modal 背景色的表格样式。

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

同时,利用一些颜色计算库,我们甚至可以非常轻松地调整出比 Modal 的背景色更加突出的效果。这样的操作,在 v4 中几乎是不敢想的。

聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

而它的代码,只需简单地微调即可。

import React from 'react';import { Modal, ConfigProvider, theme } from 'antd';import Table from './Table';import { lighten } from 'polished';const App: React.FC = () => {  const { token } = theme.useToken();  return (    <div      style={{ background: token.colorBgLayout, padding: 24, height: '100vh' }}    >      <Modal open={true} width={800} title={'在Modal中的表格'}>        <ConfigProvider          theme={{            // 把 colorBgElevated 的颜色提亮 4% 作为容器基础色            token: { colorBgContainer: lighten(0.04, token.colorBgElevated) }          }}        >          <Table />        </ConfigProvider>      </Modal>      <Table />    </div>  );};export default App;复制代码

花活总结: v5 的起点将会是其他组件库的天花板

在这么几个月的探索使用中,我愈发感觉 V5 的 CSSinJS 动态能力,搭配我们独一无二的 Token 体系,放眼全球都是极其领先的存在。尝过这些能力的甜头之后,我甚至很笃定地认为未来就是 CSSinJS 的天下。

借用云谦老师的话:「选择很重要,有些方案的起点可能就是另一些方案的天花板」。而上文所提到的行活与花活,也只是 V5 的起点,灵活性课题在 CY23 还会进一步延展下去:语义化组件 DOM 类、组件级 Token、Stylish、主题编辑器 2.0 、antd 应用级 CSSinJS 方案等等…当然,整条产研消费链路中组件库只是其中一环,上下游的协同也非常重要,但在这里就不多展开了。

既然这篇文章的标题起的是(上),那么势必还会有个(下),那在下一篇中将会和大家聊聊在实际应用中,我们应该如何用“工程化”的方式接入 antd v5 的这些特性,并将上面提到的诸多花活统统收到囊中。

关于 V5 Token 体系的详细介绍,后续会作为独立的系列更新,并在完善后同步到官网,敬请期待~

版权声明:内容来源于互联网和用户投稿 如有侵权请联系删除

本文地址:http://0561fc.cn/202399.html