发布于 2026-01-06 0 阅读
0

React Native 设计系统 (RNDS) 隆重登场 🎉🎉 什么是 RNDS 🧐?为什么要使用它?失败与经验教训 设计规则 入门指南 参考资料:DEV 的全球展示挑战赛,由 Mux 呈现:展示你的项目!

React Native 设计系统 (RNDS) 正式上线 🎉🎉

RNDS 是什么🧐?

何必呢?

失败与教训

设计规则

入门

参考:

由 Mux 赞助的 DEV 全球展示挑战赛:展示你的项目!

大家好,我一直在开发一个库,它是一个基于 React Native 的设计系统。这篇博客将解答一些你在浏览代码库时可能会遇到的常见问题。那么,让我们开始吧😁。

RNDS 是什么🧐?

RNDS简而言之React Native Design System,它是一套组件库和设计规则,可帮助您更快地构建 React Native 应用。它拥有完善的文档,经过生产环境测试,并可在 和 上运行AndroidiOS访问Web链接查看文档。

何必呢?

这个标题似乎比“动机”这个通用标题要好一些。那么,为什么要创建一个组件库呢?

过去一年里,我一直在做不同的项目,不断地复制粘贴自己开发的组件。
我当时想(和大多数开发者一样),不如把它们打包成一个包,然后在任何项目中导入。

我就是这么做的!我想要一个能更快地进行原型设计的工具,而这正是一个完美的解决方案。

一开始,我决定添加一些所有组件通用的属性,以减少 API 接口,因为说真的,谁想记住一大堆属性才能使用组件库呢?

我尽量让它接近 React Native 本身,这样我就不用学习任何新东西了。我的目标是创建一个能让用户在 10 分钟或更短时间内上手的东西。(后来我意识到,这并不容易😅)。下一节我会详细介绍我的方法,因为Failures那才是关键所在。

失败与教训

我会谈谈我在制作过程中遇到的失败以及我从中吸取的教训。如果你熟悉设计系统,就会发现其中大部分内容都很常见,但我却是走了不少弯路才学会的。我当时是在自己解决问题。

API

我想要灵活性,想要能够快速创建任何组件,所以一开始我添加了很多属性size,比如 `size`。`size`属性应该接收一个整数值,比如 `1` 。虽然需要一些计算来创建合适大小的组件,但可能性是无限的。我基本上可以创建大小从 `1`到 `2`的组件。我只需要尝试各种数字,看看哪个合适。`color` 属性应该接收一个颜色值,它会成为组件的颜色,比如 `1` 。在开发项目时,你通常只会得到一个颜色值,这样传递起来也很容易。那么问题出在哪里呢? 如果你是一位经验丰富的开发者,你可能已经猜到我有多蠢了,但请听我解释。问题在于:自由度过大会导致不一致性过大。color

Sizesize={17}10100

colorhex codeButton

为项目中的每次使用size都提供了不同的颜色,但当选项如此之多时,很难保持一致性。例如,`a` 和`b` 看起来几乎一样,但实际上并不相同。这在像素级完美设计方面是一个很大的失误。 第二个问题是将十六进制代码传递给属性。在实际应用中,按钮的数量并不多。这意味着我毫无理由地为每个按钮都传递了相同的颜色😑。color Buttonsize={16}size={17}

color

解决方案是使用令牌化的配置系统,并将可能性限制在涵盖大多数情况的最低限度。

关键在于找到自由与坚持之间的平衡。

定制化与一致性

正如我们前面讨论的,解决不一致问题的办法是将所有组件特定的配置定义在一个文件中。这解决的问题比预期的还要多。现在,所有内容都集中在一个地方,自定义组件就容易多了。
假设我有以下 7 种尺寸的按钮:

theme = {
  buttonSize: {
    'xxsmall': 8,
    'xsmall': 10,
    'small': 12,
    'medium': 14,
    'large': 16,
    'xlarge': 18,
    'xxlarge': 20,
  },
  ...
}
Enter fullscreen mode Exit fullscreen mode

这意味着我可以简单地这样做,根据我的需求指定不同的尺寸:

theme.buttonSize.medium = 15;
Enter fullscreen mode Exit fullscreen mode

这也有助于保持一致性。组件可以有 7 种不同的尺寸,我觉得这就足够了。再多的话就会造成歧义。你随时可以在主题文件中修改(或添加)这些内容。这对于颜色也同样适用。假设我们最初在主题文件中定义的颜色如下:

theme = {
  brandColor: {
    'primary': '#1e88e5',
    'secondary': '#f9a825',
    'tertiary': '#e53935',
    'background': '#f8f8f8',
    ...
  },
}
Enter fullscreen mode Exit fullscreen mode

您可以轻松地更改主品牌颜色(或任何品牌颜色),方法如下:

theme.brandColor.primary = '#aeea00';
Enter fullscreen mode Exit fullscreen mode

太好了!我们继续吧。

设计语言

一切都是相互关联的。解决了前两个问题后,第三个问题也迎刃而解,而我之前对此一无所知。之前

的方案存在沟通障碍。如果你想让别人帮你创建一个按钮,你需要提供确切的尺寸(数量)和十六进制代码(字符串)。基于令牌的主题和尺寸限制也解决了这个问题。 你只需要说“嘿,你能创建一个中等大小、色调的按钮吗?”就这么简单。这有利于沟通,避免了混淆。sizecolor

设计规则

应用原型设计远不止是简单地把组件拖放到屏幕上。在前端开发中,空间比组件本身更重要。我最初尝试为每个组件单独管理空间,但这很困难。后来

我添加了一些专门负责空间的独立组件,例如 `<div>`、`<span>`Layout componentsStack` <span> `。它们的唯一作用就是为子组件提供间距。你可以在文档中的 Stack Playground 上查看实时演示。 其他组件,例如 `<div>` Inline` <span>` 等,都拥有独立的空间属性BoxCard

ButtonBadge0 margins

这样就把问题分成了两类:

  1. 一个普通的组件应该只关注一件事:渲染一个大小合适的组件。
  2. 布局组件应该只负责为组件提供空间。

还有一些其他规则将在本文后面讨论(也可在文档中找到)。

布局组件的设计灵感/借鉴自Braid 设计系统🙈

文档

如果你不知道如何使用某个库,那它又有什么用呢?一个设计系统至少应该包含设计库、设计规则和文档,其目的在于提升你的工作效率。如果你把时间浪费在研究如何使用某个组件上,那显然是不可能实现的。

创建完整个库之后,我立刻搜索了“如何像专业人士一样为库编写文档”,并决定使用React DocGen。我写了一半的文档,但效果并不理想,所以我决定改用Docz。Docz非常好用,我甚至用它重写了所有文档,但是……

后来我去参加了JSLovers组织的一次设计系统交流会,有人建议我改用StoryBook。它简直完美,正是我需要的。它是一个交互式的实验环境,不仅能帮助你探索组件,还能让你更快地独立创建组件。有了它StoryBook,你甚至不需要阅读完整的文档。只需在实验环境中试用组件就足够了。

StoryBook所以,对于第三个版本,我决定重写整个文档,这就是您将在rnds.netlify.comMDX上看到的最终版本

使用 React Native 时还存在其他一些复杂情况/障碍,MDX但我不会赘述。

标识

费了九牛二虎之力,我只想做到完美,结果看看我一开始做出来的东西😂👇

第一个标志

第一反应,肯定不太妙😣。所以,经过一番思考,我运用我的 Photoshop 技术制作了这些:

第二个标志

看起来不错,但我还能做得更好。所以,经过反复思考后,这是最终版本👇。

最终标志

这看起来很令人满意,也表达了我创作这件作品的初衷。

以上是我在开发过程中遇到的一些失败。我从中学习到了很多东西,从 webpack 配置到复合组件,还有很多内容无法在这篇文章中一一赘述。我知道还有其他很棒的库,比如NativeBaseReact Native Element,但我当时只是想解决自己的问题,而这正是我反复迭代的结果。

Sanket SahuNader Debit在上述库的开发方面做得非常出色。库的名字React Native Design System是 Nader 本人建议的,我非常感谢他帮助我完成了这个项目。

设计规则

这部分是该库的核心,我花费了大量时间对其进行迭代改进。 它基于我在创建过程中考虑的四个关键方面。It's not much but it's honest work.

欢迎提交 PR 进行更正,这些都是个人观点,我也在努力学习。😅

1. 表面积小

大多数 props 在所有组件中都是通用的,或者与从 React Native 导入的父组件相同。这确保您无需学习一整套额外的 props,只需使用您已经熟悉的内容即可。

例如:

  • 如果是按钮,它将接收 React Native 的 Touchable 组件的所有属性。
  • 如果是模态框,则接收模态框的所有属性。
  • 每个组件都会接收一个prop size值可以是以下值之一:xxsmall,,,,,,& 你只需要传递具有这些值之一的 prop 即可。xsmallsmallmediumlargexlargexxlargesize
  • 另一个例子是prop。你可以将主题中color定义的颜色之一传递给任何组件。brandColor
  • 如果它是一个基于布局的组件,例如`<div> Box`、 ` Stack<span>` 或Inline`<span>` Card,那么它会接收一个space`prop`。该属性的值介于 `--spacing`xxsmall和`--spacing` 之间xxlarge(加上 `--spacing` space="none"),并为组件之间提供适当的间距。
  • 每个组件都会接收一个 ` <style>` 属性style和一个 ` textStyle<text>` 属性(如果涉及文本)。这用于某些特殊情况,例如需要覆盖默认样式时。theme为了保持一致性并避免重复添加,style最好调整 `<style>` 属性。

这些属性是所有组件通用的。其他组件特有的属性也很简单明了。

2. 速度

大多数情况下,默认样式(例如 `<style>`size={medium}或 `<style> space={medium}`)就足够了。在其他情况下,最多只需两到三个属性即可实现所需效果。这加快了原型制作速度。布局组件使使用属性实现所需的屏幕布局更加容易space。请参阅文档中的示例Stack

像素级精确设计的关键要素之一是组件之间的间距。该设计系统提出了两点:

  1. 每个 UI 组件的边距均为 0。
  2. 任何组件的间距都将由其父布局组件决定。

职责分离使工作更轻松。布局组件应该只负责布局,而 UI 组件应该只负责 UI,例如,布局组件应该只负责 UI,spaceUI 组件应该只负责 UI colorsize

3. 一致性

自由与坚持之间的平衡很难做到。

  1. 为了获得自由,你可以直接使用诸如color和之类的道具size
  2. 为了保持一致性,您需要在主题文件中定义这些配置,即单一数据源

它有助于保持所有使用场景的一致性。它还允许您拥有多种选择,并根据需要使用它们。有关默认配置,请查看本指南的主题部分。

4. 连接

大问题分解成小问题总是更容易解决。系统的设计语言被分解为颜色、字体、大小和间距。每个组件都遵循这些API。

颜色

颜色基本上分为两种类型:

  • brandColor: "primary", "secondary", "tertiary", "background", "disabled", "semitransparent".
  • textColor: "default", "heading", "grey", "subtle", "disabled", "white"

排版

为了保持简洁和一致性,字体有两种选择:

  • 标题
  • 文本

尺寸

  • 可用的尺寸有"xxsmall""xsmall""small"默认值为 ,如果未传递任何参数"medium"则应用此默认值。"large""xlarge""xxlarge""medium"
  • 字体大小也类似,范围从“xxsmall”到“xxlarge”。

空间

Space 的 API 与 size 类似,但多了一个特性。你可以传递"none"一个范围为"xxsmall"0 到 1的值。Space 是布局组件(例如<div>、<div>和<div>)"xxlarge"的专用属性StackInlineBoxCard

您可以为主题做出贡献。请分享您常用的颜色标记、您在各种应用中常用的字体大小等等。让我们一起使主题配置更加通用。

入门

安装

只需打开命令行并运行此命令即可。

yarn add react-native-design-system
Enter fullscreen mode Exit fullscreen mode

您可以根据自己的喜好使用yarn或。npm

npm install react-native-design-system
Enter fullscreen mode Exit fullscreen mode

这个库react-native-vector-icons也需要安装,所以请继续安装它才能获得所有炫酷的图标。请查看安装指南

用法

步骤 1. 导入ThemeProvidertheme包装您的根组件。

这一步很重要。我们要传递theme的是上下文值,每个组件都可以访问这个值。

//your root component
import { ThemeProvider, theme } from 'react-native-design-system';

function App(){
  return (
    <ThemeProvider value={theme}>
      <Root />
    </ThemeProvider>
  );
}
Enter fullscreen mode Exit fullscreen mode

步骤 2. 使用组件。

//inside any file
import { Button } from 'react-native-design-system';

function HomeScreen(){
  return (
    <Button>
      Press Me
    </Button>
  );
}
Enter fullscreen mode Exit fullscreen mode

点击这里了解更多信息。

参考:

感谢每一位给我反馈的朋友。此外,以下这些讲座和文章也对我有所帮助:

如果您对此感兴趣,请在代码仓库上点个星标。点击此链接

我们非常欢迎您的贡献,您可以点击此处查看贡献指南。

文章来源:https://dev.to/iamshadmirza/introducing-react-native-design-system-rnds-eg1