使用 Storybook、Tailwind 和 Typescript 创建组件库。
更快地为你的 React 项目构建组件。
看看最终效果。
什么是故事书?
Storybook 是一个用于独立开发 UI 组件的工具,这意味着我们可以将这些组件放在主应用程序之外,进行必要的更改,然后将它们导入到我们的应用程序中,并知道它们的外观。
设计系统已成为产品开发流程的重要组成部分,您很可能已经在使用某种设计系统。该系统为设计师和开发人员提供风格指南。您可能有很多具有不同模式和变体的 UI 组件,而 Storybook 正是解决此类问题的理想选择。
Tailwind的优势
Tailwind CSS 是一个高度可定制的底层 CSS 框架。它不像许多其他框架那样是一个 UI 工具包,而是让你完全通过 CSS 类来控制网站的外观。
搭建一个 React 应用并安装 Tailwind。
我将从零开始创建一个项目create-react-appp。
npx create-react-app storybook-ts --template typescript
让我们安装依赖项。
npm install tailwindcss postcss-cli autoprefixer
postcss.config.js在应用程序根目录下创建一个名为 `.htm` 的新文件,并添加以下代码。
module.exports = {
plugins: [require('tailwindcss'), require('autoprefixer')],
};
我们将进行处理tailwind,postcss并autoprefixer解析 CSS 并添加浏览器支持的厂商前缀。
现在将此脚本添加到package.json文件中。
{
"scripts": {
...
"build:tailwind": "postcss src/scss/base.scss -o src/scss/tailwind.scss"
},
...
}
scss在内部创建一个新文件夹src。我将使用 sass 文件,因为我将用它base.scss来编写更多类,但您也可以使用其他格式的文件css。
如果你决定使用 sass,别忘了安装node-sass。
base.scss在文件夹内创建一个文件scss,内容如下。
@tailwind base;
@tailwind components;
@tailwind utilities;
在控制台上运行此命令,即可生成 Tailwind 文件。
npm run build:tailwind
将生成的 Tailwind 文件放入您的 App 组件中。
// App.tsx
import './scss/tailwind.scss';
本教程将使用 Tailwind 的默认配置,您可以根据需要进行调整。运行此命令npx tailwind init将生成一个 Tailwind 配置文件,您可以添加更适合您的值。这是 Tailwind 的默认配置,仅供参考。
components在文件夹内创建一个新文件夹src,并添加一个button.tsx文件。
import React, { FC } from 'react';
type ButtonTypes = {
/**
* Label of the button
*/
label: string;
/**
* Boolean value to define the button style
*/
outlined?: boolean;
/**
* Button click action
*/
onClick(): void;
}
const BASE_BUTTON = 'rounded outline-none shadow py-3 px-12 font-normal uppercase tracking-wider text-lg'
const CONTAINED_BUTTON = `${BASE_BUTTON} bg-teal-400 border border-teal-400 text-white`
const OUTLINED_BUTTON = `${BASE_BUTTON} border border-teal-400 text-teal-400`
export const Button:FC<ButtonTypes> = ({ onClick, label = "Some label", outlined }) => {
return (
<button
onClick={onClick}
className={outlined ? OUTLINED_BUTTON : CONTAINED_BUTTON}
>
<span>{label}</span>
</button>
)
};
让我们一起深入故事书吧!
为了使用 Storybook 处理 TypeScript 文件,我们需要扩展 webpack 配置。让我们在项目根目录下创建一个名为 `<path>` 的新文件夹.storybook,并在其中创建一个main.js文件。
但首先,让我们安装所需的依赖项。
npm install --save-dev @storybook/react @storybook/preset-create-react-app babel-loader react-docgen-typescript-loader @storybook/addon-actions @storybook/addon-info @storybook/addon-knobs @storybook/addon-notes @storybook/addons
我们将使用插件为我们的故事启用高级功能。
在main.js文件中添加以下代码。
module.exports = {
stories: ['../src/stories/**/*.stories.tsx'],
addons: [
'@storybook/addon-actions/register',
'@storybook/addon-knobs/register',
'@storybook/addon-notes/register',
],
webpackFinal: async config => {
config.module.rules = [
...config.module.rules,
{
test: /\.(ts|tsx)$/,
use: [
{
loader: require.resolve("babel-loader"),
options: {
presets: [require.resolve("babel-preset-react-app")]
}
},
require.resolve("react-docgen-typescript-loader")
]
}
],
config.resolve.extensions.push('.ts', '.tsx');
return config;
},
};
让我们来创作我们的第一个故事。
stories在 `<path>` 内创建一个文件夹src,并在其中创建一个名为 `<filename>` 的文件button.stories.tsx。我们将添加一些插件,以便直接从 Storybook 更改按钮的属性。
import React from "react";
import { Button } from '../components/button';
import { action } from '@storybook/addon-actions';
import { withKnobs, text, boolean } from "@storybook/addon-knobs";
export default {
title: "Button",
decorators: [withKnobs]
};
export const primary = () => {
const label = text("Label", "See now");
const outlined = boolean("Oultined", false);
return (
<Button onClick={action('clicked')} outlined={outlined} label={label} />
)
};
让我们在package.json文件中添加一个脚本来运行 Storybook。
{
"scripts": {
...
"build:tailwind": "postcss src/scss/base.scss -o src/scss/tailwind.scss",
"storybook": "start-storybook -p 5000"
},
...
}
现在如果我们运行程序,npm run storybook就会看到类似这样的内容。
这是我们的按钮!但是没有样式。我们来创建一个新Layout组件来解决这个问题。从现在开始,我们创建的所有文件都将放在.storybook这个文件夹里。
import React from 'react';
import '../src/scss/tailwind.scss';
const Layout = ({ children }) => {
return (
<div className="px-20 py-10">
{children}
</div>
)
}
export default Layout;
创建preview.js文件。
import React from 'react';
import { addDecorator } from '@storybook/react';
import { withInfo } from '@storybook/addon-info';
import Layout from './Layout';
addDecorator(storyFn => <Layout>{storyFn()}</Layout>);
addDecorator(withInfo({
inline: true,
propTablesExclude: [Layout]
}));
如果再次运行 Storybook,我们的故事现在看起来会是这样。信息插件会生成源代码和一个属性类型表。
备注:
-
如果导入 Tailwind 文件时遇到问题,需要
sass-loader在 webpack 配置中添加一个main.js。 -
如果你看不到任何 proptypes,请检查你的组件文件。确保解构 React 导入,或者像这样导入 React。或者尝试不要
export default在你的组件中使用 React。
import * as React from 'react';
import React, { FC } from 'react';
export const Button = () => {} //don't use export default.
深色模式。
我们的应用看起来很棒,但你知道怎样才能让它看起来更好吗?没错,使用深色模式。
首先,创建一个manager.js文件并添加以下代码。
import { addons } from '@storybook/addons';
import { themes } from '@storybook/theming';
addons.setConfig({
theme: themes.dark,
});
这将为您的故事书应用添加深色主题。
在前一个preview.js文件中,添加此代码以更改信息的样式。
import React from 'react';
import { addDecorator } from '@storybook/react';
import { withInfo } from '@storybook/addon-info';
import Layout from './Layout';
addDecorator(storyFn => <Layout>{storyFn()}</Layout>);
addDecorator(withInfo({
inline: true,
styles: (base) => ({
...base,
infoBody: {
...base.infoBody,
backgroundColor: '#303030',
color: 'white',
},
source: {
h1: {
margin: '20px 0',
padding: '0 0 5px 0',
fontSize: '25px',
borderBottom: '1px solid #EEE',
},
},
}),
propTablesExclude: [Layout]
}));
我们几乎完成了。但是现在属性类型表格中的文本看起来不太好。
创建一个preview-body.html并添加这段代码。
<style>
.info-table, .info-table td, .info-table th{
color: #fff;
}
</style>
再运行一遍故事书。
现在,Storybook 已经可以在深色模式下运行,并支持 Tailwind 组件和 TypeScript。
请查看此仓库中的代码。
文章来源:https://dev.to/elisealcala/start-a-component-library-with-storybook-tailwind-and-typescript-2ofa


