前言

你应该需要:使用react搭建组件库:react+typescript+storybook
)

一、安装依赖

在组件中使用 fortawesome一套绝佳的图标字体库和CSS框架

1
2
3
npm install @fortawesome/fontawesome-svg-core
npm install @fortawesome/free-solid-svg-icons
npm install @fortawesome/react-fontawesome

二、编写组件

  • 新建 src/components/Icon/icon.tsx

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    import React, { FC } from "react";
    import classnames from "classnames";
    import { library } from "@fortawesome/fontawesome-svg-core";
    import { fas } from "@fortawesome/free-solid-svg-icons";

    import {
    FontAwesomeIconProps,
    FontAwesomeIcon,
    } from "@fortawesome/react-fontawesome";

    library.add(fas);

    export type theme =
    | "primary"
    | "secondary"
    | "success"
    | "info"
    | "warning"
    | "danger"
    | "light"
    | "dark";

    export interface IconProps extends FontAwesomeIconProps {
    /** 主题颜色 */
    theme?: theme;
    }

    export const Icon: FC<IconProps> = (props) => {
    const { className, theme, ...restProps } = props;
    const classes = classnames("lin-icon", className, {
    [`lin-icon-${theme}`]: theme,
    });

    return <FontAwesomeIcon className={classes} {...restProps} />;
    };

    export default Icon;
  • 新建 src/components/Icon/index.tsx

    1
    2
    3
    import Icon from "./icon";

    export default Icon;
  • 新建 src/components/Icon/_style.scss

    1
    2
    3
    4
    5
    6
    7
    @import "../../styles/variables/icon";
    // 循环
    @each $key, $val in $icon-theme-color {
    .lin-icon-#{$key} {
    color: $val;
    }
    }
  • 新建 styles/variables/_icon.scss文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @import "./common";

    $icon-theme-color: (
    "primary": $primary,
    "secondary": $secondary,
    "success": $success,
    "info": $info,
    "warning": $warning,
    "danger": $danger,
    "light": $light,
    "dark": $dark,
    );
  • 新建 src/styles/index.scss文件

    1
    2
    // icon样式
    @import "../components/Icon/style";
  • 修改App.tsx文件
    !! 对于fortawesome: [一套绝佳的图标字体库和CSS框架]中的图标都可以使用

    1
    2
    3
    4
    // 增加
    import Icon from "./components/Icon/icon";
    <Icon icon="coffee" size="5x" theme="danger" />
    <Icon icon="arrow-down" size="5x" />
  • 修改index.tsx文件

    1
    export { default as Icon } from "./components/Icon";

三、运行项目

执行命令

1
$ npm start

访问项目 可以看到Icon组件成功了!
image.png

四、编写storybook文档

  • 新建src/Icon/icon.stories.tsx文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    import React from 'react'

    import { storiesOf } from '@storybook/react'

    import Icon from './icon'



    const defaultIcon = () => {
    return (
    <div>
    <Icon
    icon="check"
    size="3x"
    />
    <Icon
    icon="times"
    size="3x"
    className='ml-20'
    />
    <Icon
    icon="anchor"
    size="3x"
    className='ml-20'
    />
    <Icon
    icon="trash"
    size="3x"
    className='ml-20'
    />
    </div>
    )
    }

    const iconWithTheme = () => {
    return (
    <div>
    <Icon
    icon="check"
    size="3x"
    theme="success"
    />
    <Icon
    icon="times"
    size="3x"
    theme="danger"
    className='ml-20'
    />
    <Icon
    icon="anchor"
    size="3x"
    theme="primary"
    className='ml-20'
    />
    <Icon
    icon="exclamation-circle"
    size="3x"
    theme="warning"
    className='ml-20'
    />
    </div>
    )
    }

    const iconWithOther = () => {
    return (
    <div>
    <Icon
    icon="spinner"
    size="3x"
    spin
    theme="primary"
    />
    <Icon
    icon="spinner"
    pulse
    size="3x"
    theme="success"
    className='ml-20'
    />
    </div>
    )
    }


    storiesOf('Icon 组件', module)
    .addParameters({
    info: {
    text: `
    ## 引用方法
    ~~~js
    import {Icon} from 'echo-rui
    ~~~
    `
    }
    })
    .add('默认的 Icon', defaultIcon)
    .add('不同主题的 Icon', iconWithTheme)
    .add('更多行为的 Icon', iconWithOther,{
    info: {
    text: `
    ## 引用方法
    ~~~js
    import {Icon} from 'echo-rui
    ~~~
    更多例子请参见:https://github.com/FortAwesome/react-fontawesome#basic
    `
    }
    })
  • 执行命令

    1
    $ npm run storybook

浏览器打开http://localhost:9009/,可以看到组件库文档生成了。
image.png

五、 发布到npm

✅ ✅ ✅ ✅ ✅

总结:大功告成✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️✌️