关于在Orka做UI组件库的一些事

在Orka干了1个月了,今天基本上写好了Orka App Page的大部分页面这篇文章用来记录一下我做orkaui的背景和动机。

大背景:公司规模的提升与设计规范的确立

  1. 公司以前的前端是由很多人兼职维护的,且刚开始start up的时候没有全职的前端开发人员,所以开发人员的代码风格及其不一致,包括但不限于:页边距、button的样式、布局模式——对于只有两三个页面的项目,这本身是没有问题的,但是随着app和听力测试功能的引入,以及公司马上发布二代产品,我们的前端需要一定的规范和更精简的代码。
  2. 前端开发和设计人员没有完全打通。在我看来,前端对于figma设计稿的落实程度是有着很大的差别的。再加上每个人只负责维护个别页面,导致页面很不规范。比如,页边距、动画时长、动画的实现方式。
  3. 代码的可复用性低。虽然不是每个组件都很复杂,但是相似或者同样的代码会在组件中大量的出现——因为我们目前的组件大部分是基于MUI的,但是有时候又借用了Antd的内容。所以,我们几乎每一个组件都会再由不同的开发人员wrap一层,但是这些代码又散布于各个地方,导致一个人封装了一个小组件,其他人没办法及时得知组件有哪些功能,会选择自己再去定制一个。
  4. 更多的项目。我们马上会推出新的网站,也会用到相似的设计。

开始:设计部门的Library

为了解决这个问题,首先是设计部的同事在figma上建立了自己的组件库——除了UI,还有他们自己画的icons。我们也相应的建立了一个项目内的“组件库”。然而,项目内的组件库并没有很好地完成代码精简的功能,短时间内可以缓解代码不规范的问题,但是长期下来,还是会让项目变得很臃肿。

我的工作内容——同步需求、写文档和组件库

基于这个背景,我的工作有了以下目的:

  1. 和设计的同事确定规范,他们保证设计风格的统一,我保证如何通过组件库来落实这个统一的设计风格。
    1. 通过Layout组件规定了不同情况下的页边距和栅格样式——并且保证自适应(统一breakpoint)。
    2. 除了普通的h1, h2等,根据设计常用的字体样式,对应地建立了Typography的不同variant。另外,常用的“电脑版左对齐,手机版居中”被我定义成了textAlign: auto的API。
    3. MUI原生的button组件不支持“自动填充到父组件宽度”这一功能,我参考Antd,给orkaui的button组件添加了block属性。
    4. 建立了orkaui/motion这个动效组件,这个组件能说的内容比较多,详情见本文下一部分。
  2. 建立单独的@orkaui/icons
    1. 使用icons不再需要手动引入图片地址。
    2. 与antd或者MUI不同的是,我们的icons很讨厌,它不是那种纯色或者双色的简单icons,更像是一个illustration。为此,我们对于不同尺寸的部分icons设计了有细微差别的版本。我通过small, medium, large和自定义参数规定常用的icons尺寸,并且icons组件总是会根据当前的尺寸参数返回原始尺寸最接近的源文件(目前已经完成了一半)。
    3. 后续我们的网站可能会采用深色主题,icons使用svg,保留了变色的可能性。(但是这个变色的实现还比较复杂,因为我们的icons白色和透明没有完全分开,stroke和fill也会有一些不一致)
  3. 将上述设计规范的落实写成文档和示例代码,以便他人参考。

关于orkaui/motion动效组件

给产品经理看的:这个组件可以干嘛

img

img

orkaui/motion是我目前做过的最复杂的组件。在此过程中,我参考了Ant Motion组件库的QueueAnim的一些设计理念,了解了它的一些设计上的取舍,又添加了我们团队用得上的功能。

以下是我对orkaui/motionrc-queue-anim/QueueAnim功能上的对比(以下简称orkauiantd):

  1. orkaui做的更好的(这是我们为什么用不了antd的原因)
    1. antd只支持从父元素中统一地指定动画样式,无法对每个单独的子元素进行样式规定,orkaui的设计中,不同的子元素会有不同的样式;
    2. antd要求动画播放的子元素必须<QueueAnim />的一级子元素,而我们的设计采用Grid嵌套布局;故orkaui会搜索<ScrollFlow />元素下的所有<FlowItem />子元素,依次排序并赋予动画。(我实现过三个版本,第一次和antd一样,并没有额外地设计<FlowItem />子元素,但是它不支持嵌套;第二次会使用了子元素,但是不支持传参,而且会忽略掉其它元素,以及DOM层级关系;第三次保留了React/DOM完整的层级关系以及其参数,并加入动画效果)
    3. antd组件动画不支持PC/mobile端实现不同的动画效果,orkaui支持自定义,且给组件设置了PC和mobile端不同的默认值,以符合端设计规范。
  2. 我们都支持的功能
    1. 动画开始时间、动画方向、触发动画开始的threshold、动画位移量、动画的间隔时间
    2. 自定义动画顺序
  3. antd支持的更多的功能(主要功能)
    1. 更多的动画方向和动画效果
    2. 动画样式自定义程度更高(可以设置CSS)
    3. 支持缓动
    4. 重复播放动画

不过咱们也不是只需要写这一个组件,所以,我写的orkaui会比antd更轻量、但是能更满足我们的设计需求。

给开发人员看的:这个组件怎么干的

  1. 动画原理:CSS的transition
  2. 监听事件以触发动画:使用IntersectionObserver来监听元素在DOM的位置。
  3. 迭代循环React Component:
    1. 使用React.Fragment代替根元素
    2. 当前元素没有children或者children是纯文本:直接返回
    3. 当前元素不是FlowItem:继续迭代其子组件
    4. 当前元素是FlowItem:加上动画的props,一整个返回,不迭代

遇到的困难

  1. 让组件适配SSR(如,Node.js没有document)
  2. 如何判断children是某个特定的React Component(遇到过生产和开发环境不一致的情况:React.nodechild.type.name被简化了)
  3. Safari对RegExp的支持出现问题(Safari不支持lookbehind)