在Orka干了1个月了,今天基本上写好了Orka App Page的大部分页面这篇文章用来记录一下我做orkaui的背景和动机。
大背景:公司规模的提升与设计规范的确立
- 公司以前的前端是由很多人兼职维护的,且刚开始start up的时候没有全职的前端开发人员,所以开发人员的代码风格及其不一致,包括但不限于:页边距、button的样式、布局模式——对于只有两三个页面的项目,这本身是没有问题的,但是随着app和听力测试功能的引入,以及公司马上发布二代产品,我们的前端需要一定的规范和更精简的代码。
- 前端开发和设计人员没有完全打通。在我看来,前端对于figma设计稿的落实程度是有着很大的差别的。再加上每个人只负责维护个别页面,导致页面很不规范。比如,页边距、动画时长、动画的实现方式。
- 代码的可复用性低。虽然不是每个组件都很复杂,但是相似或者同样的代码会在组件中大量的出现——因为我们目前的组件大部分是基于MUI的,但是有时候又借用了Antd的内容。所以,我们几乎每一个组件都会再由不同的开发人员wrap一层,但是这些代码又散布于各个地方,导致一个人封装了一个小组件,其他人没办法及时得知组件有哪些功能,会选择自己再去定制一个。
- 更多的项目。我们马上会推出新的网站,也会用到相似的设计。
开始:设计部门的Library
为了解决这个问题,首先是设计部的同事在figma上建立了自己的组件库——除了UI,还有他们自己画的icons。我们也相应的建立了一个项目内的“组件库”。然而,项目内的组件库并没有很好地完成代码精简的功能,短时间内可以缓解代码不规范的问题,但是长期下来,还是会让项目变得很臃肿。
我的工作内容——同步需求、写文档和组件库
基于这个背景,我的工作有了以下目的:
- 和设计的同事确定规范,他们保证设计风格的统一,我保证如何通过组件库来落实这个统一的设计风格。
- 通过Layout组件规定了不同情况下的页边距和栅格样式——并且保证自适应(统一breakpoint)。
- 除了普通的h1, h2等,根据设计常用的字体样式,对应地建立了Typography的不同variant。另外,常用的“电脑版左对齐,手机版居中”被我定义成了
textAlign: auto
的API。 - MUI原生的button组件不支持“自动填充到父组件宽度”这一功能,我参考Antd,给orkaui的button组件添加了
block
属性。 - 建立了
orkaui/motion
这个动效组件,这个组件能说的内容比较多,详情见本文下一部分。
- 建立单独的
@orkaui/icons
库- 使用icons不再需要手动引入图片地址。
- 与antd或者MUI不同的是,我们的icons很讨厌,它不是那种纯色或者双色的简单icons,更像是一个illustration。为此,我们对于不同尺寸的部分icons设计了有细微差别的版本。我通过
small
,medium
,large
和自定义参数规定常用的icons尺寸,并且icons组件总是会根据当前的尺寸参数返回原始尺寸最接近的源文件(目前已经完成了一半)。 - 后续我们的网站可能会采用深色主题,icons使用svg,保留了变色的可能性。(但是这个变色的实现还比较复杂,因为我们的icons白色和透明没有完全分开,stroke和fill也会有一些不一致)
- 将上述设计规范的落实写成文档和示例代码,以便他人参考。
关于orkaui/motion
动效组件
给产品经理看的:这个组件可以干嘛
orkaui/motion
是我目前做过的最复杂的组件。在此过程中,我参考了Ant Motion组件库的QueueAnim
的一些设计理念,了解了它的一些设计上的取舍,又添加了我们团队用得上的功能。
以下是我对orkaui/motion
和rc-queue-anim/QueueAnim
功能上的对比(以下简称orkaui
和antd
):
orkaui
做的更好的(这是我们为什么用不了antd
的原因)antd
只支持从父元素中统一地指定动画样式,无法对每个单独的子元素进行样式规定,orkaui
的设计中,不同的子元素会有不同的样式;antd
要求动画播放的子元素必须<QueueAnim />
的一级子元素,而我们的设计采用Grid
嵌套布局;故orkaui
会搜索<ScrollFlow />
元素下的所有<FlowItem />
子元素,依次排序并赋予动画。(我实现过三个版本,第一次和antd
一样,并没有额外地设计<FlowItem />
子元素,但是它不支持嵌套;第二次会使用了子元素,但是不支持传参,而且会忽略掉其它元素,以及DOM层级关系;第三次保留了React/DOM完整的层级关系以及其参数,并加入动画效果)antd
组件动画不支持PC/mobile端实现不同的动画效果,orkaui
支持自定义,且给组件设置了PC和mobile端不同的默认值,以符合端设计规范。
- 我们都支持的功能
- 动画开始时间、动画方向、触发动画开始的threshold、动画位移量、动画的间隔时间
- 自定义动画顺序
antd
支持的更多的功能(主要功能)- 更多的动画方向和动画效果
- 动画样式自定义程度更高(可以设置CSS)
- 支持缓动
- 重复播放动画
不过咱们也不是只需要写这一个组件,所以,我写的orkaui
会比antd
更轻量、但是能更满足我们的设计需求。
给开发人员看的:这个组件怎么干的
- 动画原理:CSS的transition
- 监听事件以触发动画:使用IntersectionObserver来监听元素在DOM的位置。
- 迭代循环React Component:
- 使用
React.Fragment
代替根元素 - 当前元素没有
children
或者children
是纯文本:直接返回 - 当前元素不是
FlowItem
:继续迭代其子组件 - 当前元素是
FlowItem
:加上动画的props,一整个返回,不迭代
- 使用
遇到的困难
- 让组件适配SSR(如,Node.js没有document)
- 如何判断children是某个特定的React Component(遇到过生产和开发环境不一致的情况:
React.node
(child
).type.name
被简化了) - Safari对RegExp的支持出现问题(Safari不支持lookbehind)