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


目录
相关文章
|
30天前
|
前端开发
深入解析React Hooks:构建高效且可维护的前端应用
本文将带你走进React Hooks的世界,探索这一革新特性如何改变我们构建React组件的方式。通过分析Hooks的核心概念、使用方法和最佳实践,文章旨在帮助你充分利用Hooks来提高开发效率,编写更简洁、更可维护的前端代码。我们将通过实际代码示例,深入了解useState、useEffect等常用Hooks的内部工作原理,并探讨如何自定义Hooks以复用逻辑。
|
1天前
|
前端开发 JavaScript 开发者
从零开始构建你的第一个React应用
从零开始构建你的第一个React应用
8 2
|
16天前
|
资源调度 前端开发 数据可视化
构建高效的数据可视化仪表板:D3.js与React的融合之道
【10月更文挑战第25天】在数据驱动的时代,将复杂的数据集转换为直观、互动式的可视化表示已成为一项至关重要的技能。本文深入探讨了如何结合D3.js的强大可视化功能和React框架的响应式特性来构建高效、动态的数据可视化仪表板。文章首先介绍了D3.js和React的基础知识,然后通过一个实际的项目案例,详细阐述了如何将两者结合使用,并提供了实用的代码示例。无论你是数据科学家、前端开发者还是可视化爱好者,这篇文章都将为你提供宝贵的洞见和实用技能。
35 5
|
1月前
|
前端开发 JavaScript UED
构建现代Web应用:使用React框架打造单页面应用
【10月更文挑战第9天】构建现代Web应用:使用React框架打造单页面应用
|
1月前
|
前端开发 JavaScript 测试技术
构建响应式Web应用程序:React实战指南
【10月更文挑战第9天】构建响应式Web应用程序:React实战指南
|
1月前
|
存储 JavaScript 前端开发
如何使用React和Redux构建现代化Web应用程序
【10月更文挑战第4天】如何使用React和Redux构建现代化Web应用程序
|
1月前
|
JavaScript 前端开发
使用 React 和 Redux 构建动态图表应用
【10月更文挑战第3天】使用 React 和 Redux 构建动态图表应用
|
1月前
|
JavaScript 前端开发
使用 React 和 Redux 构建一个计数器应用
【10月更文挑战第3天】使用 React 和 Redux 构建一个计数器应用
|
2月前
|
移动开发 前端开发 JavaScript
构建高效跨平台移动应用:React Native入门指南
【8月更文挑战第47天】在移动开发领域,React Native凭借其跨平台特性和高效的开发模式赢得了开发者的青睐。本文将通过一个简易的待办事项应用实例,带领读者快速入门React Native,并展示如何利用JavaScript和React框架构建具有原生性能的应用。我们将探讨环境配置、界面布局、状态管理和数据流,以及如何打包和发布您的应用。准备好,让我们开始React Native之旅!
70 20
|
1月前
|
设计模式 SQL 前端开发
使用 GraphQL 和 React 构建动态前端应用
【10月更文挑战第2天】使用 GraphQL 和 React 构建动态前端应用
46 0