用 React 构建可复用的设计系统(二)

简介: 用 React 构建可复用的设计系统

分子组成原子


目前为止,我们仅创建了 web 应用中最基本的元素,只是这样,它们是没有用的。我们可以在示例的基础上扩展构建一个简单的模态弹窗。

首先,我们定义了模态弹窗的组件类。

// design-system/Portal.js
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import {Box, Flex} from './layouts/Layouts';
import { Type, TextSize, TextAlign} from './type/Type';
import './portal.scss';
export class Portal extends React.Component {
    constructor(props) {
        super(props);
        this.el = document.createElement('div');
    }
    componentDidMount() {
        this.props.root.appendChild(this.el);
    }
    componentWillUnmount() {
        this.props.root.removeChild(this.el);
    }
    render() {
        return ReactDOM.createPortal(
            this.props.children,
            this.el,
        );
    }
}
export const Modal = ({ children, root, closeModal, header}) 
=> {
    return <Portal root={root} className="ds-modal">
        <div className="modal-wrapper">
        <Box>
        <Type tagName="h6" size={TextSize.lg}>{header}</Type>
    <Type className="close" onClick={closeModal} 
align={TextAlign.right}>x</Type>
    </Box>
    <Box>
    {children}
    </Box>
    </div>
    </Portal>
}

接下来,我们为模态弹窗定义 CSS 样式。

#modal - root {
.modal - wrapper {
        background - color: white;
        border - radius: 10px;
        max - height: calc(100 % - 100px);
        max - width: 560px;
        width: 100 %;
        top: 35 %;
        left: 35 %;
        right: auto;
        bottom: auto;
        z - index: 990;
        position: absolute;
    }
> div {
        background - color: transparentize(black, .5);
        position: absolute;
        z - index: 980;
        top: 0;
        right: 0;
        left: 0;
        bottom: 0;
    }
.close {
        cursor: pointer;
    }
}

对于初学者来说,createPortal 除了会把子元素渲染在父组件之外的层级中,它和 render 方法类似。在 React 16 有详细介绍。


使用 Modal 组件


现在,组件已经定义好了,让我们看看如何在业务场景中使用它。

//src/App.js
import React, { Component } from 'react';
//...
import { Type, TextBold, TextSize } from './design_system/type/Type';
import { Modal } from './design_system/Portal';
class App extends Component {
    constructor() {
        super();
        this.state = {showModal: false}
    }
    toggleModal() {
        this.setState({ showModal: !this.state.showModal });
    }
    render() {
    <button onClick={this.toggleModal.bind(this)}>
        Show Alert
        </button>
        {this.state.showModal &&
        <Modal root={document.getElementById("modal-root")} 
header="Test Modal" 
closeModal={this.toggleModal.bind(this)}>
            Test rendering
        </Modal>}
            //....
        }
    }

我们可以在任何地方使用 modal,然后在调用的地方维护它的状态。很简单,对吧?但是,这有个 bug。关闭按钮无效。这是因为我们构建的所有组件都是一个封闭的系统。 它只会使用需要的 props,并且无视其他的。在当前的示例中,text 组件忽略了 onClick 事件。幸运的是,这很容易被修复。

// In  design-system/type/Type.js
export const Type = ({ tag = 'span', size= TextSize.default, 
boldness = TextBold.default, children, className='', 
align=TextAlign.default, ...rest}) => {
    const Tag = `${tag}`;
    const classNames = `ds-text ${size} ${boldness} ${align} 
${className}`;
    return <Tag className={classNames} {...rest}>
        {children}
    </Tag>
};

ES6 可以很容易的把剩余的参数以数组的方式提取出来。使用这种方法,然后把参数传递给组件。


分享组件


随着团队的扩大,很难把有效的组件同步给每个人。Storybooks 是一种很好的分享组件的方法。让我们配置一个基础的 storybook。

开始:

npm i -g @storybook/cli 
getstorybook

storybook 还需要一些必要的配置。从这里开启,剩下的设置都很简单。让我们添加一个简单的 story 代表 Type 不同的状态。

import React from 'react';
import { storiesOf } from '@storybook/react';
import { Type, TextSize, TextBold } from '../design_system/type/Type.js';
storiesOf('Type', module)
    .add('default text', () => (
        <Type>
            Lorem ipsum
        </Type>
    )).add('bold text', () => (
    <Type boldness={TextBold.semibold}>
        Lorem ipsum
    </Type>
)).add('header text', () => (
    <Type size={TextSize.lg}>
        Lorem ipsum
    </Type>
));

API 非常简单。storiesOf 定义了一个新的 story,一般就是你的组件。然后,通过 add 添加新的章节,为了展示组件不同的状态。

e391f9e209032ea1bec2781fd499cf8f_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png

当然,这是非常基本的,但是 storybooks 有一些插件可以帮助你添加文档。我还注意到她们也支持 emoji?


目录
相关文章
|
13小时前
|
JavaScript 前端开发 测试技术
构建一个使用React和Redux的简单在线书店应用。
构建一个使用React和Redux的简单在线书店应用。
3 0
|
1天前
|
前端开发 NoSQL JavaScript
基于 React + Nest 全栈开发的后台系统
这篇文章介绍了一个基于React+Nest全栈开发的后台系统XmwAdmin。项目包括前端和后端技术栈,线上预览地址和登录信息。作者推荐使用pnpm包管理工具和特定的环境依赖。文章提供了项目的运行和编译代码,以及各个功能模块的介绍。还包括演示图和项目活动以及总结部分。数据库下载链接也提供了,该项目已完成后台的核心功能。
基于 React + Nest 全栈开发的后台系统
|
1天前
|
存储 前端开发 数据可视化
构建基于React的动态数据可视化应用
【5月更文挑战第27天】构建基于React的动态数据可视化应用,通过Create React App快速搭建环境,使用Recharts等库封装组件。在`useState`和`useEffect` Hooks管理状态,处理动态数据。优化性能,添加交互功能,实现响应式设计,确保可访问性,打造高性能、用户体验佳的可视化应用。
|
13天前
|
前端开发
【边做边学】系统解读一下React Hooks
【边做边学】系统解读一下React Hooks
|
13天前
|
前端开发 JavaScript
详解React:Props构建可复用UI的基石
详解React:Props构建可复用UI的基石
17 0
|
13天前
|
前端开发 JavaScript 安全
使用React、TypeScript和Ant Design构建现代化前端应用
使用React、TypeScript和Ant Design构建现代化前端应用
37 0
|
13天前
|
开发框架 前端开发 JavaScript
使用React、Redux和Bootstrap构建社交媒体应用
使用React、Redux和Bootstrap构建社交媒体应用
19 0
|
13天前
|
JavaScript 前端开发 开发者
React和Vue的生态系统有何不同?
React和Vue的生态系统有何不同?
|
13天前
|
存储 开发框架 前端开发
深入探索React:构建动态、交互式前端应用的终极指南
深入探索React:构建动态、交互式前端应用的终极指南
103 0
|
13天前
|
存储 前端开发 中间件
React组件间的通信
React组件间的通信
19 1

热门文章

最新文章