将生产组件引入FramerX

在Datadog,我们在基于React的设计系统中设计和构建组件的速度一直在提升。同时使用怎样的设计工具   统一处理这些组件的挑战也随之而来。

我们的团队收到了beta版Framer X的邀请,我们花了几天时间测试其功能。Framer X的强大之处在于它能够让设计师自由切换画布和代码模式。

Framer X的代码并不是生产环境代码,但它具有与常规React项目相同的功能。因此,我们开始探索将生产组件引入Framer X的工作流程的可能性。

我们写了这篇文章作为部分指南及文档。它遵循我们将生产组件引入Framer X的过程。

 

入门

本指南假设您具有Node,Yarn和Git的基本开发环境设置,以及基本的Javascript和React知识。让我们从克隆构建系统仓库开始:

git clone https://github.com/shiftsave/framerx-build-system.git

接下来,安装依赖项:

cd framerx-build-system && yarn install

绑定代码库

首先,我们需要将生产代码库捆绑为Framer X可以解释的格式。类似简单的ES6和CSS。我们使用Webpack将生产代码库捆绑到一个无依赖库(代码中称为“lib”)。

库的入口是index.ts文件,它从生产代码库中导入相关的元素和组件。这包括来自JSX,TSX,LESS,Sass甚至SVG图像等任何形式。

其中最大的障碍之一是在我们导出的库中正确解析所有生产组件依赖项。例如,依赖于类名的下拉组件。

 

 

要将此构建系统与生产代码库一起使用,请将Webpack entry指向你的代码库。我们建议您在生产代码库中创建一个symlink以避免重复。

无论你跟我们示例操作还是用自己的方法,你只需运行yarn build即可。这将捆绑_production中的代码并将捆绑的库复制到design-system.framerx

 

 

使用捆绑的组件

在我们开始之前,我们需要解开一些关于Framer X运作的疑团。一个 .framerx文件是一个捆绑为二进制格式的压缩文件夹。

打开压缩包,Framer X将文件解压到macOS的AutoSave Information文件夹中。当文件关闭时,Framer X将内容拉回到文件中。

 

添加组件

我们将从lib中取出我们的生产组件,并将其包装在一个新组件中作为生产代码和Framer X之间的桥梁。我们需要这个封装器来显示Property Controls(我们很快会谈到这些)

我们整合的构建系统包括一个示例Button组件。我们将在本节中使用此组件。

打开design-system.framerx并创建一个名为新代码组件的Button。Framer X将在Visual Studio Code中打开Button.tsx

 

 

让我们删除示例代码并逐步添加我们需要的东西。

我们将从导入声明开始。我们建议使用别名导入声明,{ Button as _Button }这允许我们使用原始组件名称作为Framer X代码组件的名称。

import * as React from "react";
import { Button as _Button } from "../lib"// <- This is the bundled production code we inserted with yarn build.

接下来,让我们定义组件及其props。下面示例中的props与我们与Webpack捆绑在一起的生产文件夹中的组件中定义的props相匹配。props用来改变组件的内容和视觉样式,下面的示例里用来修改按钮的尺寸,类型和标题。

import * as React from "react";
import { Button as _Button } from "../lib";
enum SIZE_OPTIONS {
EXTRA_SMALL = "xs",
SMALL = "sm",
MEDIUM = "md",
LARGE = "lg"
}
// Define type of property
interface Props {
buttonType?:
| "default"
| "primary"
| "success"
| "warning"
| "danger"
| "toggle";
size: SIZE_OPTIONS;
title: string;
// Width and height of the component when loaded in the canvas
width: number;
height: number;
}
export class Button extends React.Component {
render() {
return <_Button {...this.props}>{this.props.title}</_Button>;
}
}

现在该组件在Framer X中,但你会注意到它渲染出来有些偏差。这是因为我们还没有初始化任何defaultProps。让我们初始化一些props,让默认的组件外观更好看一些。

import * as React from "react";
import { PropertyControls, ControlType } from "framer";
import { Button as _Button } from "../lib";
enum SIZE_OPTIONS {
  EXTRA_SMALL = "xs",
  SMALL = "sm",
  MEDIUM = "md",
  LARGE = "lg"
}
// Define type of property
interface Props {
  buttonType?:
    | "default"
    | "primary"
    | "success"
    | "warning"
    | "danger"
    | "toggle";
  size: SIZE_OPTIONS;
  title: string;
// Width and height of the component when loaded in the canvas
  width: number;
  height: number;
}
export class Button extends React.Component<Props> {
  // Set default properties
  static defaultProps = {
    title: "Button",
    size: "md",
    buttonType: "default",
    width: 68,
    height: 28
  };
render() {
    return <_Button {...this.props}>{this.props.title}</_Button>;
  }
}

瞧!生产组件在Framer X中!

 

 

属性控件

接下来,让我们添加一些属性控件。Property Controls是Framer X最强大的功能之一; 它们允许你公开显示控件以便与组件的Props交互。有关详细信息,请参阅Framer X文档。

import * as React from "react";
import { PropertyControls, ControlType } from "framer";
import { Button as _Button } from "../lib";
enum SIZE_OPTIONS {
  EXTRA_SMALL = "xs",
  SMALL = "sm",
  MEDIUM = "md",
  LARGE = "lg"
}
// Define type of property
interface Props {
  buttonType?:
    | "default"
    | "primary"
    | "success"
    | "warning"
    | "danger"
    | "toggle";
  size: SIZE_OPTIONS;
  title: string;
// Width and height of the component when loaded in the canvas
  width: number;
  height: number;
}
export class Button extends React.Component<Props> {
  // Set default properties
  static defaultProps = {
    title: "Button",
    size: "md",
    buttonType: "default",
    width: 68,
    height: 28
  };
// Items shown in property panel
  static propertyControls: PropertyControls = {
    title: { type: ControlType.String, title: "Title" },
    buttonType: {
      type: ControlType.Enum,
      options: ["default""primary""success""warning""danger""toggle"],
      title: "Button Type"
    },
    size: {
      type: ControlType.SegmentedEnum,
      options: ["xs""sm""md""lg"],
      title: "Size"
    }
  };
render() {
    return <_Button {...this.props}>{this.props.title}</_Button>;
  }
}

协作和版本控制

在此过程中我们必须克服的最大障碍之一是协作,以及跟踪GitHub中的变化。这意味着将Framer X文件中的组件提取到仓库主支干上。

我们在里面写了三个脚本package.json,允许我们通过目录的src同步Framer文件,反之亦然。这使我们能够为设计和代码组件提供完整的版本控制功能从而最大程度避免对工作流程的影响。目前这方法还很凑下,除非Framer X以后有更好的方法来处理版本控制。

我们为管理构建系统而实施的程序包括:

yarn build
将生产代码库捆绑到ES6中并将其复制到lib内部的Framer X目录里。

yarn sync:lib
使用最新版本的构建替换Framer X目录里的lib

yarn sync:src
用Framer X目录文件的替换src目录。

yarn sync:framerx
libsrc目录文件构建一个新的Framer X文件,以防出现冲突或文件损坏。

总结

此工作流程仍处于早期阶段 – 但好处是真实环境:

允许跨职能团队拥有已批准组件的集中库。
简化设计和工程之间的协作。我们可以轻松列出新功能所需的组件和规格。
使具有开发经验的设计人员能够构建几乎可以生产的组件。
允许设计人员更快地构建真实交互的原型。

在Datadog,我们正在设计能够让工程师了解其云基础架构的产品。我们的设计系统很复杂,有许多活动部件,因此我们很高兴能够测试Framer X能否帮助我们填补设计和工程师之间的鸿沟。

如果您有兴趣应对这些挑战并希望帮助我们在Datadog进行设计,我们很乐意听取您的意见!

译自Ivan Cruz的Medium文章:Bringing Design System Component from Production into FramerX,点击原文链接查看原帖。

刷牙君

View posts by 刷牙君
处女座设计师一枚,涉及的专业领域视觉,交互,前端。

Leave a Reply

Your email address will not be published. Required fields are marked *