用 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?


目录
相关文章
|
16天前
|
存储 前端开发 JavaScript
深入浅出React框架:构建高效组件化网页的实战指南
【7月更文挑战第9天】在当今快速发展的前端技术领域,React凭借其强大的组件化思想、高效的虚拟DOM以及丰富的生态系统,成为了构建动态用户界面的首选框架之一。本文将带你深入浅出地探索React的核心概念,并通过实战示例,展示如何利用React构建高效、可维护的组件化网页。
48 8
|
1月前
|
前端开发 JavaScript Linux
分离前后端react和django3构建的应用
【6月更文挑战第4天】在本文中,我们介绍了如何设置React前端并连接到Django后端。并讨论了前后端分离的好处,并计划扩展API以支持更多HTTP操作和用户身份验证功能。
61 5
分离前后端react和django3构建的应用
|
2月前
|
前端开发 JavaScript API
使用React和GraphQL构建一个简单的博客应用
使用React和GraphQL构建一个简单的博客应用
31 1
|
1月前
|
Python API 前端开发
使用react和django3构建应用
【6月更文挑战第3天】首先,创建Django项目和todos应用,安装必要依赖,配置settings.py并建立数据库模型。通过makemigrations和migrate更新数据库。接着,设置REST_FRAMEWORK的权限为AllowAny,构建API的urls, views, serializers。在todos应用中定义ListTodo和DetailTodo视图,以及TodoSerializer。对于跨域资源共享(CORS),通过django-cors-headers中间件配置白名单。
33 0
|
2月前
|
JavaScript 前端开发 搜索推荐
构建一个基于React和Redux的简易电商购物车应用
构建一个基于React和Redux的简易电商购物车应用
38 0
|
2月前
|
存储 前端开发
构建一个简单的React待办事项列表应用
构建一个简单的React待办事项列表应用
31 0
|
2月前
|
前端开发
构建一个简单的React图片画廊应用
构建一个简单的React图片画廊应用
54 0
|
2月前
|
前端开发 IDE Java
构建一个基于React和Spring Boot的简易聊天室应用
构建一个基于React和Spring Boot的简易聊天室应用
46 0
|
2月前
|
JavaScript 前端开发
构建一个基于React和Redux的Todo应用
构建一个基于React和Redux的Todo应用
29 0
|
2月前
|
JavaScript 前端开发 测试技术
构建一个使用React和Redux的简单在线书店应用。
构建一个使用React和Redux的简单在线书店应用。
27 0