Open WangShuXian6 opened 1 month ago
你好,欢迎你加入课程!
你是否曾在网页开发中想过创建自己的 UI 组件库?如果你的答案是肯定的,那么你来对地方了。欢迎参加“构建和发布 React UI 组件库到 NPM”的课程。
在演示组件库之前,我会先介绍项目的技术栈和学习曲线。开发组件其实并不复杂,只要你具备 HTML、CSS 和 React 的基础知识,就可以轻松开发这些组件。然而,更具挑战的是将其发布到 NPM、维护它并将其与 Storybook 集成。所以如果你想掌握所有这些内容,就需要全面了解项目的技术栈和学习曲线。
我将这个项目的学习过程分为六个阶段,每个阶段都介绍不同的技术。现在让我们从第一阶段开始吧!
大家好,现在我们进入我的 Storybook 应用程序,这里包含了所有组件。在详细介绍这些组件之前,先给大家看看 npm 库。
我们进入 npm,搜索 satya ui react
。可以看到,这就是我开发的库。在页面中,我们可以看到 satya ui react
的详细信息。目前已经发布了三个版本,并显示了 npm 的安装命令。在这里我每周有 34 次下载量,展示了我的项目代码库。
接下来,我们回到 Storybook,看一下所有组件。可以看到,我们有 10 个 UI 组件和一个主题提供器。组件包括:Alert(警告)、Button(按钮)、Flex Container(弹性容器)、Input(输入)、Modal(模态框)、Radio(单选按钮)、Select(选择)、Spinner(加载动画)、Switch(开关)和 Tabs(选项卡)。
首先来看 Alert 组件。点击后,你可以看到所有变体:信息、成功、错误、警告、不带图标的、可关闭的。页面顶部有文档,可以在简单的文档页中查看所有变体。可以看到:信息(蓝色背景)、成功(绿色背景)、错误、警告、不带图标、可关闭。如果点击关闭按钮,组件会关闭。
然后是 Button 组件。可以看到这是所有的属性和可用选项:按钮、轮廓、小号、中号、大号、禁用、圆角、边框半径、带图标、加载状态。如果想单独查看某个变体,可以点击该变体的按钮。
接下来是 Flex Container,它通常用于对齐项目。默认情况下,所有项目都是左对齐并靠顶部。你可以调整属性来实时查看效果,比如将项目居中、靠右等。
Input 组件支持基本、大号、错误、禁用、圆角等状态。Modal 组件包含标题和内容,还有带页脚的模式,以及无关闭按钮的模式。
Radio 单选按钮支持水平和垂直对齐。Select 下拉菜单可以显示标签和值,可以选择带图标的选项,选择后会显示相应的图标。Spinner 提供小、中、大三种尺寸。Switch 开关支持基本、水平、禁用等状态。
Tabs 组件可以显示基础的选项卡或禁用某些选项,还支持垂直排列。在每个变体中,你都可以查看代码示例。
最后,我们来看 Theme Provider(主题提供器)。通过调整主题的主色,可以统一改变按钮、输入框等组件的颜色。所有组件的颜色和边框都随着主题的调整实时更新。
这就是我们组件库的内容,总共有 10 个组件和一个主题提供器。希望你对这些组件有更深入的了解。谢谢大家,我们课程见!
欢迎回来!
在本视频中,我们将讨论 React UI 组件库的项目创建。在我的 VS Code 中,可以看到我已创建了一个名为 satya_ui
的空文件夹,这也将成为我的 UI 组件库的名称。
首先,我们需要使用 npm init
命令生成 package.json
文件。没有这个文件,我们无法在父文件夹中安装任何 npm 模块。如果希望在这里安装 npm 模块,必须先生成 package.json
。
点击“终端”,选择“新终端”,然后输入命令 npm init
。根据提示输入包名称 satya_ui
,版本号 1.0.0
,描述可以留空,入口文件为 index.js
,测试命令、git 仓库和关键字留空,作者填写你的名字,许可证可以留空,确认后完成创建。现在可以看到我们生成了 package.json
。
接下来,我们初始化 npm 模块。为了编写组件,首先需要安装 4 个 npm 模块:react
、typescript
、@types/react
,以及 tslib
。所有这些模块将作为开发依赖来安装,因此使用 --save-dev
选项。安装完成后,可以看到我们生成了 node_modules
文件夹和 package-lock.json
文件,它们会记录 npm 模块的版本信息。
接下来,我们设置 tsconfig.json
文件,因为我们将使用 TypeScript 编写组件。在文件中添加默认配置,这些配置包含 compilerOptions
和 include
两个属性。如果希望了解这些配置的详细作用,可以参考 TypeScript 的官方文档。
然后,我们创建项目的文件夹结构。在根目录中已有 tsconfig
、package.json
和 node_modules
。现在创建一个 src
文件夹,并在其中创建 components
文件夹和 index.ts
作为入口点。将来我们创建的组件将会导入到这里,并通过一条语句进行导出。
为了演示,我们先创建两个组件文件夹:button
和 input
。在每个文件夹中创建 index.tsx
文件,添加基本的功能组件。在 src/index.ts
中导入这些组件,并用一行代码导出它们。
在下一个视频中,我会展示如何编写一个简单的组件语法,以便可以导出和使用。我们已经完成了基本的功能组件编写,接下来将编写 UI 组件语法。
谢谢观看!
欢迎回来!
在本视频中,我们将开始制作按钮组件。我们将从一些基础属性和基本样式开始,待组件成功发布到 npm 后,再回过头来完善更多的属性和对应样式。
首先,我们定义接口 ButtonProps
,初期只设置两个属性:title
和 variant
。其中,variant
属性可以有两个值:outlined
和 contained
。
接着在组件中定义 title
和 variant
,并为 variant
设置默认值为 contained
。然后创建一个按钮,并显示 title
。
目前我们不编写 CSS 文件,而是直接使用内联样式。我们将 padding
设置为上下 5px、左右 10px。接下来,根据 variant
属性来应用不同的背景颜色、文本颜色和边框样式:
variant
为 outlined
,则设置背景颜色为透明,边框为 1px 黑色实线。variant
为 contained
,则背景色为黑色,文本颜色为白色。将样式附加到按钮上后,组件就准备好了。由于暂时使用了内联样式,接下来我们会完成发布过程,并在后续视频中用 Tailwind CSS 替换掉内联样式。这样可以加速测试流程。
在下一个视频中,我们将使用 Rollup 库来导出此组件。
谢谢观看!
欢迎回来!
在本视频中,我们将讨论什么是 Rollup 以及如何将其集成到当前项目中。
首先,Rollup 是一个 JavaScript 模块打包工具,它可以将项目源代码和所有依赖项打包为单一文件。Rollup 的作用是将代码中非 JavaScript 部分转换为纯 JavaScript,从而生成适合发布的版本。具体来说,像 JSX、TS、TSX 这些浏览器无法直接理解的代码,都会被 Rollup 转换为浏览器能理解的 JavaScript。
打个比方,如果我们的项目有多个 JavaScript 文件、JSX、TSX、CSS 和图片文件,那么在使用 Rollup 构建后,它会输出一个或多个 JavaScript 文件,同时保留原有的静态资源(如图片和 CSS)。
Rollup 的主要作用就是将非 JavaScript 代码转化为 JavaScript,确保可以直接发布到 npm 上。我们在项目发布之前需要进行这样的构建,以便得到纯 JavaScript 的输出。
接下来是如何在项目中设置 Rollup:
rollup.config.ts
配置文件。在下个视频中,我们将实际操作,完成 Rollup 的安装和项目中的配置。谢谢观看!
欢迎回来!
在本视频中,我们将讨论在当前应用中配置 Rollup 所需安装的 NPM 模块。
基本上,为了使用 Rollup,我们需要安装并配置七个 NPM 模块。接下来,我将依次介绍每个模块的用途:
Rollup:这是核心库,用于构建源代码并生成输出。没有这个库,其他 Rollup 功能都无法使用。
Rollup TypeScript Plugin:这个插件处理 TypeScript 语法并将其转换为 JavaScript。可以通过 npm install @rollup/plugin-typescript
命令安装。
Node Resolve Plugin:用于定位项目中的模块,并将非 JavaScript 代码转换为 JavaScript,这对于使用第三方模块很有用。
CommonJS:将 CommonJS 模块转换为 ES6 语法,以便在 Rollup 构建时包含它们。如果项目包含旧版 CommonJS 模块,这个插件会将它们转换为最新的 ES6 语法。
DTS:生成基于组件接口的类型文件,便于在使用时提供类型支持。
Terser Plugin:这个插件用于压缩代码。它能移除未使用的变量和导入语句,生成更小的打包文件。
Peer Dependencies External:用于从构建过程中排除指定的 npm 模块,避免与最终用户的应用重复加载模块。例如,如果最终用户应用中已经安装了 React,可以使用此插件防止重复打包。
接下来,我们将逐个安装这些模块,然后在下一视频中使用这些插件来编写 rollup.config.ts
配置文件。谢谢观看!
欢迎回来!
本视频将讨论 Rollup 配置文件的设置。首先,在项目根目录下创建一个名为 rollup.config.ts
的文件。
接下来,引入上一视频中安装的插件:
在配置文件中,首先指定 input
和 output
,其中 input
指向入口文件路径,output
指定为两种输出格式:CommonJS 和 ES 模块。
export default [
{
input: 'src/index.ts',
output: [
{
file: 'dist/cjs/index.js',
format: 'cjs',
sourcemap: true,
},
{
file: 'dist/esm/index.js',
format: 'esm',
sourcemap: true,
},
],
plugins: [
peerDepsExternal(),
resolve(),
commonjs(),
typescript(),
terser(),
],
},
{
input: 'src/index.ts',
output: {
file: 'dist/index.d.ts',
format: 'es',
},
plugins: [dts()],
},
];
在 plugins
中引入所有插件以进行不同的功能处理,例如,terser
用于压缩代码,dts
生成类型文件。对每个配置部分添加注释,以帮助理解每一部分的功能。
接下来,我们将在下节讨论 package.json
中的配置修改以生成 Rollup 构建。谢谢观看!
欢迎回来!
本视频中将介绍如何在 package.json
中进行更改,以便使用 Rollup 生成构建。
更新主入口:将 main
属性从 index.js
更新为 dist/cjs/index.js
,这与 Rollup 的 CommonJS 输出路径匹配。
添加 ECMAScript 支持:为 ECMAScript 输出添加 module
属性,指向 dist/esm/index.js
,确保与 Rollup 配置中的路径一致。
类型支持:在 types
属性中指定类型文件路径,设置为 dist/index.d.ts
。
更改完成后,可以使用 npm run build
命令进行构建。运行 build
命令时,若 Rollup 配置文件是 TypeScript 格式,则需添加参数 bundleConfigAsCJS
,以确保 Rollup 正确地编译 TypeScript。
最终,生成的 dist
文件夹将包含以下内容:
cjs
和 esm
文件夹:分别包含 CommonJS 和 ECMAScript 格式的构建输出和 source map 文件。index.d.ts
文件:位于根目录,用于类型支持。下一节将演示如何导出和导入组件。谢谢观看!
欢迎回来!
本视频将介绍如何将 React UI 组件库发布到 npm。
创建和登录 npm 帐户:前往 npm 网站,若无账户请先注册并验证邮箱。登录账户后,在终端中使用 npm login
命令输入用户名、密码和邮箱验证代码完成登录。
更新库名称:如果库名称与现有 npm 包冲突,可以在 package.json
中修改 name
属性以避免冲突。
发布库:确保登录成功后,使用 npm publish --access public
命令将组件库发布到 npm。如果发布成功,您将在 npm 账户的 Packages 列表中看到新发布的库。
检查发布结果:发布完成后,返回 npm 账户,刷新页面即可看到新发布的库。
接下来的视频将展示如何在独立的 React 应用中安装和测试该库的功能,确保库发布成功后再继续操作。
欢迎回来!
在上一个视频中,我们讨论了如何将 React UI 组件库发布到 npm。今天,我们将学习如何在一个独立的 React 应用中测试该发布的 npm 组件库。
创建测试项目:
npx create vite@latest satya-ui-testing
。安装依赖:
npm install
安装应用依赖。npm install satya-ui-react
安装我们发布的组件库。启动开发服务器:
npm run dev
启动开发服务器。localhost:5173
确认应用正常运行。导入组件并测试:
App.tsx
文件,清理不必要的代码。import { Button } from 'satya-ui-react'
引入 Button 组件。title
和 variant
属性,并观察组件渲染是否符合预期。验证类型检查:
size
),观察 TypeScript 是否抛出错误。title
和 variant
属性。本视频展示了如何在独立 React 项目中测试组件库,验证其功能和类型检查的准确性。下一步,我们将学习如何在发布更新时调整版本号。
欢迎回来!
在本视频中,我们将学习在 npm 库中如何进行版本升级。以下是步骤:
在组件库中做修改:
Button
组件,添加新的 onClick
属性,并添加一个光标样式,使按钮在悬停时显示为手形。cursor: pointer
,以改善用户体验。生成最新构建:
npm run build
,生成包含最新更改的构建文件。更新 package.json 的版本号:
package.json
中将版本号从 1.0.1
更新为 1.0.2
。npm publish
,发布更新的版本到 npm。在消费应用中更新版本:
npm install satya-ui-react@latest
。npm run dev
,确保应用加载最新库,并验证按钮组件的光标效果。接下来的视频中,我们将介绍如何在不发布到 npm 的情况下测试组件更新,以便更快速地验证小的代码改动。
欢迎回来!
本视频将介绍如何在本地测试组件库的更改,而无需发布到 npm。以下是具体步骤:
创建新应用程序:
npx create-vite@latest
创建一个新的 React 项目,如 satya-ui-testing-local
,并选择 TypeScript 模板。在组件库中使用 npm link
:
npm link
。这样,组件库将在本地全局注册,使其可以被其他应用程序引用。在测试应用程序中链接库:
npm link satya-ui-react
以便在该应用中使用本地版本的 satya-ui-react
,而无需从 npm 安装。构建组件库并测试更改:
npm run build
,生成最新构建。Button
组件并使用它来验证更改,例如添加 onClick
属性。动态更新样式和功能:
npm run build
,并刷新测试应用查看效果。完成本地测试:
这样,您可以高效地进行快速迭代,节省发布到 npm 的时间。完成本地验证后,就可以将更新推送到 npm 了。
欢迎回来!
在本视频中,我们将介绍如何在组件库中构建和处理 CSS 文件。具体步骤如下:
创建 CSS 文件并应用类样式:
Button
组件目录下创建 index.css
文件,并在该文件中定义样式类。btn
类定义通用样式,btn-outlined
和 btn-contained
类分别应用边框样式和背景色。className
属性引用这些类。引入和应用 CSS 文件:
import './index.css'
。className
,例如:
let className = 'btn';
if (variant === 'outlined') className += ' btn-outlined';
else className += ' btn-contained';
安装和配置 Rollup 的 PostCSS 插件:
rollup-plugin-postcss
插件。npm install rollup-plugin-postcss
。rollup.config.js
中添加以下代码:
import postcss from 'rollup-plugin-postcss';
postcss()
插件添加到 Rollup 配置中的插件列表。更新 Rollup 配置以排除 CSS 类型:
external
属性排除 .css
文件。exclude: /\.css$/
,从而避免 CSS 文件在类型生成阶段出现。构建并验证输出:
npm run build
构建项目。构建成功后,输出将包含新的 CSS 文件和应用了 CSS 类样式的组件库。下一步,我们将介绍如何在组件库中集成 Tailwind CSS。
欢迎回来!
在本视频中,我们将介绍如何在组件库中安装并设置 Tailwind CSS。以下是步骤:
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
tailwind.config.js
和 postcss.config.js
文件生成在项目根目录。tailwind.config.js
文件,在 content
属性中添加 src/**/*.{html,js,jsx,ts,tsx}
,使 Tailwind 可以处理这些文件类型。main.css
文件,并添加以下内容:
@tailwind base;
@tailwind components;
@tailwind utilities;
index.ts
)中引入这个 CSS 文件:
import './main.css';
tailwind.config.js
中,将 content
数组更新为:
content: ["./src/**/*.{html,js,jsx,ts,tsx}"],
corePlugins
中设置 preflight: false
:
corePlugins: {
preflight: false,
},
Button.tsx
),删除原有的普通 CSS 文件,并使用 Tailwind CSS 类:
let className = `py-2 px-5 cursor-pointer`;
if (variant === 'outlined') {
className += ` border border-solid border-black bg-white text-black`;
} else {
className += ` bg-black text-white`;
}
npm run build
通过这些步骤,您现在可以在项目中使用 Tailwind CSS 来构建样式。在下一个视频中,我们将介绍如何通过一个库来简化具有多种样式变体的类名写法。
欢迎回来!
本视频我们将介绍如何使用 classnames
库来简化条件渲染类名的流程。这一库的优势在于,可以帮助我们更轻松地基于条件动态应用样式类,而不必写很多 if-else 语句。以下是操作步骤:
npm install classnames
import classNames from 'classnames';
classNames
函数中:
const buttonClass = classNames(
"py-2 px-5 cursor-pointer", // 基础样式
{
"border border-solid border-black bg-white text-black": variant === "outlined",
"bg-black text-white": variant === "contained",
"pointer-events-none bg-gray-300 cursor-not-allowed border-none": disabled,
}
);
buttonClass
应用于 className
属性:
<button className={buttonClass} onClick={disabled ? null : handleClick}>
{label}
</button>
const buttonClass = classNames(
"py-2 px-5 cursor-pointer",
{
"border border-solid border-black bg-white text-black": variant === "outlined",
"bg-black text-white": variant === "contained",
"bg-gray-300 text-gray-700 border-none cursor-not-allowed": disabled,
}
);
npm run build
variant
和 disabled
属性的效果,确保所有条件样式都按预期应用。width
和 height
,并在 classnames
库中使用类似方式来管理这些样式。通过 classnames
库,您可以简化条件渲染类名的代码,使代码更简洁、更易读。如果您有任何关于 CSS 安装、Tailwind CSS 设置或 classnames
库使用的疑问,请随时提出!
欢迎回来!
在本视频中,我们将继续完善功能完备的按钮组件,添加 大小(size
)和 圆角(rounded
)属性,并进行样式调整。
size
和 rounded
两个属性:
size
:可选值为 small
、medium
、large
,默认值为 medium
。rounded
:可选值为 none
、small
、medium
、large
,默认值为 none
,用于控制边角的圆润程度。 const buttonClass = classNames(
"px-5 cursor-pointer",
{
"h-8": size === "small",
"h-10": size === "medium",
"h-12": size === "large",
"rounded-none": rounded === "none",
"rounded-sm": rounded === "small",
"rounded-md": rounded === "medium",
"rounded-lg": rounded === "large",
}
);
tailwind
的 h-
类来设置按钮高度,以及 rounded-
类来控制边角:
const buttonClass = classNames(
{
"h-8": size === "small",
"h-10": size === "medium",
"h-12": size === "large",
"rounded-none": rounded === "none",
"rounded-sm": rounded === "small",
"rounded-md": rounded === "medium",
"rounded-lg": rounded === "large",
}
);
size
默认使用 medium
,rounded
默认使用 none
,以保持矩形形状。size
和 rounded
组合,确保每种情况下样式都能正确渲染。 <Button size="large" rounded="large">Large Rounded Button</Button>
在 index.css
中导入 Poppins
字体,以提升按钮的整体美观性:
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap');
body {
font-family: 'Poppins', sans-serif;
}
size
和 rounded
属性的样式效果。通过改变 size
值,可以观察到按钮高度的变化,而改变 rounded
值则会使按钮的边角更圆滑或变为矩形。outline
和 contained
样式都能正确应用。如果您对组件的 size
和 rounded
属性或 Tailwind CSS 的设置有任何疑问,请随时提问!
欢迎回来!
在本视频中,我们将为按钮组件添加 图标 和 图标大小 属性。让我们逐步实现这些新功能。
icon
:用于传递图标组件,可以是任意的 React 节点。iconPosition
:用于定义图标的位置,可选值为 left
和 right
,默认值为 left
。 const Button = ({ icon, iconPosition = 'left', ...props }) => {
const buttonClass = classNames(
"px-5 cursor-pointer flex items-center",
{
"gap-3": icon, // 如果有图标,设置间距
"flex-row-reverse": icon && iconPosition === "right" // 如果图标在右侧,则反转方向
}
);
};
flex
布局和 gap
间距,方便图标和文本的组合展示。根据 iconPosition
值调整 flex
方向:
return (
<button className={buttonClass}>
{icon && iconPosition === 'left' && <Icon size={iconSize} />}
<span>{props.children}</span>
{icon && iconPosition === 'right' && <Icon size={iconSize} />}
</button>
);
iconPosition
值来控制图标的位置。Lucide React
作为图标库,安装并导入所需的图标:
npm install lucide-react
然后在代码中导入图标组件,并通过 icon
属性传递给按钮:
import { User } from "lucide-react";
<Button icon={<User size={16} />} iconPosition="left">
Add User
</Button>
<Button icon={<User size={16} />} iconPosition="left" />
size
属性控制其大小,以适应按钮的不同样式和尺寸。icon
和 iconPosition
都能正确渲染:
<Button variant="outline" icon={<User size={14} />} iconPosition="right">
Add User
</Button>
variant
、size
和 rounded
等属性,同时观察图标位置和样式效果。如果您对按钮组件的 icon
和 iconSize
属性有任何疑问,或者对图标库的使用有问题,请随时提问!
欢迎回来!
在本视频中,我们将介绍 Storybook 的安装、设置,以及如何为组件编写 Stories。让我们一步一步实现 Storybook 集成到我们的组件库中。
npm
发布并安装到测试应用中。 npx storybook@latest init
Vite
或 Webpack
)。.storybook
文件夹,这里面包含了 Storybook 的配置文件。 npm run storybook
为按钮组件创建一个 .stories.js
文件,例如 Button.stories.js
,并定义一些不同的状态:
import React from 'react';
import { Button } from './Button';
export default {
title: 'Example/Button',
component: Button,
};
const Template = (args) => <Button {...args} />;
export const Primary = Template.bind({});
Primary.args = {
variant: 'contained',
label: 'Primary Button',
};
export const Secondary = Template.bind({});
Secondary.args = {
variant: 'outline',
label: 'Secondary Button',
};
Primary
和 Secondary
)。通过此界面,您可以调整组件的属性,并在 Storybook 的隔离环境中进行交互式测试。如果您在安装或配置过程中有任何问题,请随时提问。
欢迎回来!
在上一个视频中,我们介绍了 Storybook,并完成了 Storybook 的安装和设置。今天我们将探讨 story 的概念,并演示如何移除默认的 Storybook 示例。
primary
、secondary
、large
、small
等。每种状态可以对应一个 story。stories
文件夹中的默认组件。.mdx
和 .storybook
文件夹,因为它们包含配置和文档内容。通过以上步骤,你现在应该理解了 Story 的概念以及它在 Storybook 中的作用。在接下来的视频中,我们将亲手编写第一个按钮组件的 Story。
欢迎回来!在本讲中,我们将学习如何为我们的按钮组件编写 story。
定位组件文件夹
SRC
,找到 components 文件夹,并在其中找到按钮组件的文件夹。button.stories.tsx
。编写基本故事
Button
组件和 ButtonProps
接口。export default
导出一个对象,其中包含 title
和 component
字段,定义 story 的名称和组件。编写第一个 story
export const
创建按钮的第一个变体 Contained
。args
中设置按钮的属性,如 title
和 variant
等。title
为“Primary Button”,variant
为“Contained”。扩展更多变体
Outlined
,并为不同的按钮样式指定不同的 args
。Small
、Medium
、Large
的大小变体,或是 Disabled
状态的按钮。使用 Tailwind CSS
PostCSS
插件以确保样式在 Storybook 中生效。.storybook/main.js
文件中,将插件 storybook/addon-postcss
添加到 addons
中,并根据 Storybook 的文档进行配置。main.css
文件到 Storybook 的 preview.js
中,以确保 Tailwind CSS 能够应用到 Storybook。运行 Storybook
npm run storybook
启动 Storybook,在浏览器中预览你创建的按钮故事。创建更多故事
props
(例如 variant
、size
、disabled
等),创建多个故事以展示不同的配置效果。建议创建至少 5 个变体,帮助更好地测试和展示组件。通过以上步骤,你可以使用 Storybook 为按钮组件创建多个不同的故事,实时测试和展示组件的不同状态。如果有任何疑问,请在继续前进一步交流。
欢迎回来!在本讲中,我们将为按钮组件添加两个新的 stories:一个是处理圆角属性,另一个是处理图标属性。
为按钮创建一个新的 story rounded
,在 args
中传入 borderRadius
为 large
。
示例代码:
export const Rounded = {
args: {
title: 'Click Me',
borderRadius: 'large',
},
};
outline
样式,以便更好地对比效果。lucid-react
图标库为按钮添加一个图标。如果还没有安装 lucid-react
,请先安装。确认它已经添加到项目的依赖中。
示例代码:
import { User } from 'lucid-react';
export const WithIcon = {
args: {
title: 'Click Me',
icon: <User size={16} />,
},
};
Rounded
和 WithIcon
故事。props
调整,可以实时更改按钮的属性,并查看更新后的样式效果。我们已经成功地为按钮组件添加了两个新的变体,展示了按钮的圆角和带图标的样式。在接下来的讲座中,我们将讨论如何为按钮添加 loading 状态的故事,以进一步丰富其样式变体。如果有任何疑问,请随时提问!
欢迎回来!在本视频中,我们将为按钮组件添加一个 loading 属性,以实现加载动画效果,并创建相应的 story。以下是实现过程:
loading
属性,类型为布尔值,默认为 false
。当 loading
为 true
时,按钮旁边将显示一个旋转的加载指示器。
示例代码:
export const Button = ({ loading = false, ...props }) => {
return (
<button className="btn" {...props}>
{props.children}
{loading && (
<span className="spinner w-3 h-3 border-2 border-t-transparent rounded-full animate-spin ml-2"></span>
)}
</button>
);
};
<span>
元素作为加载指示器。类 animate-spin
添加了旋转动画,border-t-transparent
隐藏顶部边框以形成旋转效果。variant
样式来调整指示器颜色,例如:border-white
和 border-black
。在 button.stories.js
文件中,为加载效果添加一个 story。
示例代码:
export const WithLoader = {
args: {
title: 'Click Me',
loading: true,
variant: 'contained', // 或 'outlined',根据需要选择样式
},
};
loading
为 true
时,会在按钮旁边显示加载指示器。WithLoader
story 的效果。可以尝试不同的 variant
和 size
属性值来测试加载指示器的外观。flex
布局来调整按钮文本和加载指示器的位置,以实现更整齐的对齐。width
和 height
参数来更改加载指示器的大小。现在我们已经为按钮组件添加了一个 loading
效果,并创建了相应的 story。加载指示器会在加载时显示,并伴随旋转动画。您可以继续探索其他样式组合和故事以丰富组件功能!
如果有任何疑问,请随时提出!
欢迎回来!在本视频中,我们将开始创建输入框组件,并为其添加基本的故事。以下是实现过程的关键步骤:
Input
组件并定义其属性 (props),例如 value
、onChange
、name
、placeholder
、type
、size
、rounded
、disabled
和 error
。使用 interface
定义输入框的属性类型,以确保输入框支持字符串或数字类型的值、各种尺寸、边框圆角、禁用状态和错误消息等。
示例代码:
interface InputProps {
value: string | number;
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
name: string;
placeholder?: string;
label?: string;
disabled?: boolean;
type?: 'text' | 'number' | 'password';
size?: 'small' | 'medium' | 'large';
rounded?: 'none' | 'small' | 'medium' | 'large';
error?: string;
}
export const Input = ({ value, onChange, name, placeholder, label, disabled, type = 'text', size, rounded, error }: InputProps) => {
return (
<div className="flex flex-col max-w-xs">
{label && <label htmlFor={name} className="mb-1">{label}</label>}
<input
type={type}
name={name}
value={value}
onChange={onChange}
placeholder={placeholder}
disabled={disabled}
className={`px-5 ${size === 'small' ? 'h-8' : size === 'medium' ? 'h-10' : 'h-12'}
${rounded === 'small' ? 'rounded-sm' : rounded === 'medium' ? 'rounded-md' : rounded === 'large' ? 'rounded-lg' : ''}
${error ? 'border border-red-500' : 'border border-gray-300'}
${disabled ? 'bg-gray-200 cursor-not-allowed' : ''}`}
/>
{error && <p className="text-red-500 mt-1">{error}</p>}
</div>
);
};
storybook
为输入框创建一个基本的故事,测试默认样式、占位符和禁用状态等属性。为了测试组件在 Storybook 中的显示效果,可以在 input.stories.tsx
文件中编写以下内容:
示例代码:
import { Input } from './Input';
export default {
title: 'Components/Input',
component: Input,
};
export const BasicInput = {
args: {
label: 'Username',
placeholder: 'Enter your username',
value: '',
disabled: false,
},
};
BasicInput
故事并验证输入框是否能正确显示占位符和禁用状态。size
和 rounded
等属性。error
属性显示红色文本和边框。cursor-not-allowed
样式以禁止点击操作。我们已经创建了基本的输入框组件,并在 Storybook 中进行了测试。接下来,可以继续为该输入框组件添加更多的变体和故事,探索不同的属性组合!
如有任何疑问,欢迎随时提出!
本视频中,我们将为输入框组件编写不同的故事,并利用不同的属性来展示其多种变体。以下是步骤:
large
)创建故事。这样可以清楚地展示每种尺寸的效果。 export const Large = {
args: {
label: 'Username',
placeholder: 'Enter your username',
size: 'large',
},
};
error
属性,我们可以在输入框中展示错误状态。 export const ErrorState = {
args: {
label: 'Username',
placeholder: 'Enter your username',
error: 'Invalid username',
},
};
disabled
属性,设置输入框为禁用状态。 export const Disabled = {
args: {
label: 'Username',
placeholder: 'Enter your username',
disabled: true,
value: 'Satya', // 设定初始值为用户名称
},
};
rounded
属性,设置输入框的圆角样式。可以选择不同的圆角级别,比如small
、medium
、large
或full
。 export const Rounded = {
args: {
label: 'Username',
placeholder: 'Enter your username',
size: 'large',
rounded: 'full', // 圆角样式为全圆
},
};
例如:
export default {
title: 'Components/Input',
component: Input,
};
export const BasicInput = {
args: {
label: 'Username',
placeholder: 'Enter your username',
},
};
export const LargeInput = { ...Large };
export const ErrorInput = { ...ErrorState };
export const DisabledInput = { ...Disabled };
export const FullRoundedInput = { ...Rounded };
通过这种方法,您可以创建多样化的输入框组件,并在Storybook中测试不同属性组合。接下来,我们将探索如何通过主题来统一控制组件的颜色和样式。
本视频中,我们讨论了如何在UI组件库中实现主题(theming)功能。以下是步骤概述:
ThemeProvider
组件,该组件接受一个primaryColor
属性,用于设置组件的主题颜色。如果没有传递此属性,默认颜色为黑色(#000
)。示例代码:
import React, { useEffect } from 'react';
export const ThemeProvider = ({ primaryColor = '#000', children }) => {
useEffect(() => {
document.documentElement.style.setProperty('--primary-color', primaryColor);
}, [primaryColor]);
return <>{children}</>;
};
--primary-color
的CSS变量,并设置默认值。 :root {
--primary-color: #000;
}
tailwind.config.js
文件中的extend
选项,将--primary-color
变量与Tailwind的colors
配置结合,这样我们可以在Tailwind类中引用这个颜色变量。 // tailwind.config.js
module.exports = {
theme: {
extend: {
colors: {
primary: 'var(--primary-color)',
},
},
},
};
primary
。 <button className="bg-primary text-white">Button</button>
ThemeProvider
包装在Storybook的组件故事中,以便能够在Storybook中动态更改主题颜色。示例代码:
import { ThemeProvider } from './ThemeProvider';
export default {
title: 'Components/Button',
component: Button,
decorators: [(Story) => <ThemeProvider primaryColor="#f00"><Story /></ThemeProvider>],
};
primaryColor
属性来动态观察颜色变化。例如,可以将颜色更改为蓝色或绿色,来验证组件是否正确响应主题更改。ThemeProvider
,确保它在实际场景中能够为组件提供一致的主题颜色控制。通过这些步骤,您可以实现一个可配置的主题系统,使组件在不同的项目中能方便地应用不同的主题。
在本视频中,我们演示了如何在原始React应用中测试ThemeProvider
主题提供程序的概念。以下是关键步骤:
ThemeProvider
组件可用,随后通过以下命令建立本地链接,以便在应用中测试库。npm link
命令将本地SatyaUI
库链接到应用程序中:
npm run build
npm link
npm link satya-ui-react
ThemeProvider
App.js
),并将组件放在ThemeProvider
组件内,以便这些组件能够使用该主题。示例:
import { ThemeProvider, Button } from 'satya-ui-react';
function App() {
return (
<ThemeProvider primaryColor="blue">
<Button title="Add User" variant="contained" />
<Button title="Submit" variant="outlined" />
</ThemeProvider>
);
}
useEffect
钩子有关的依赖冲突问题。为避免库中的React版本与消费者应用的React版本冲突,我们更新了rollup.config.js
配置文件,使用external
选项来排除React库。 external: ['react']
primaryColor
属性更改为不同的颜色值,并看到所有被包裹在ThemeProvider
中的组件的样式随之改变。这样可以确保ThemeProvider
的主题颜色在所有子组件上都能应用。 <ThemeProvider primaryColor="orange">
<Button title="Add User" variant="contained" />
<Button title="Submit" variant="outlined" />
<Input placeholder="Enter your name" />
</ThemeProvider>
primaryColor
的值,观察所有按钮、输入框的边框和背景颜色实时变化。ThemeProvider
中,这样各个页面和组件都能继承主题。可以在ThemeProvider
内部创建路由和页面,以便所有内容都能一致地应用主题颜色。通过这些步骤,我们成功地验证了ThemeProvider
在React应用中的功能,并展示了如何通过简单的属性更改来动态更新整个应用的样式。
在本视频中,我们介绍了如何创建并测试SelectField
组件,重点在于构建一个基础选择框组件。以下是关键步骤:
Select
组件,并在组件文件index.tsx
中定义了必要的属性接口SelectProps
,包括以下属性:
value
: 当前选中的值,类型为string
或number
。onChange
: 值更改时的回调函数。options
: 选项列表,为对象数组,包括label
(标签)和value
(值),可选的image
字段可以用来显示图标或国旗等。placeholder
: 占位符文本。showOptions
状态控制选项列表的显示与隐藏。当用户点击选择框时,通过setShowOptions
切换showOptions
的布尔值,从而显示或隐藏选项列表。.map()
方法遍历options
数组,将每个选项渲染为一个点击区域(div
),点击选项时,调用onChange
并将选项值传递给父组件。SelectField
的Storybook故事文件Select.stories.tsx
,并将基本的Select
组件故事定义为Basic
。placeholder
为“Select a country”,并传入了一些示例国家作为选项。SelectField
组件在点击后显示下拉菜单,并在控制台上验证所选值。px
和py
类,以确保选项在移动端和桌面端都有良好的显示效果。通过本次实现,我们搭建了SelectField
组件的基本框架,并展示了如何在React中实现带有占位符、点击展开选项、点击选项回调等基本功能的选择框。
在本次视频中,我们扩展了 SelectField
组件的功能,使其支持在下拉选项中显示图像,比如各个国家的国旗。以下是关键步骤:
countryflags.com
。Advanced
故事中,为每个国家(如印度、美国、英国和加拿大)添加对应的国旗图片链接。基本故事中没有图片,而高级故事则包括图片。Select
组件,在label
之前添加img
标签。检查选项对象中是否包含image
属性,如果存在,就渲染图像。img
的大小为20px x 20px
,并添加mr-5
样式在图像和文本之间留出一些间距。flex items-center
样式,使图片和文本垂直居中对齐。w-max
和 px-5
使组件显示效果更好,避免组件过度拉伸。ChevronDown
和 ChevronUp
图标,分别用于表示选项展开和隐藏状态。15px
,并使其颜色与主题颜色一致。justify-between
样式来调整图标与文本之间的间距。Advanced
组件,验证当选项展开时显示国旗和文本。transform
和 rotate
样式,以确保选项的展开和收起具有流畅的用户体验。通过这次实现,我们成功将SelectField
组件扩展至包含图像,并实现了基本的样式和交互效果,使组件更加完善和实用。
在本次视频中,我们探索了如何在Storybook中处理组件的状态管理(如 useState
和 useEffect
),并在选择项更改时动态显示选中的值。以下是实现步骤:
const template
,并将 args
作为参数。使用此模板定义初始状态和状态更新逻辑。useState
钩子创建 value
状态和 setValue
更新函数。初始状态为空。onChange
函数来处理选择项的更改,每次选择更改时调用 setValue
更新状态。Basic
和 Advanced
两个故事中添加 render: template
,使故事能够使用模板的状态管理功能。SelectField
组件中使用 find
方法查找当前选中的选项对象,并将 label
(标签)作为显示内容。value
存在,则显示选项的 label
;如果没有选项被选中,则显示占位符(placeholder)。image
属性,使用 img
标签显示图片。div
中,并添加样式 flex
、gap-2
和 items-center
,以确保图片和文本对齐。options.map
中,根据每个选项的 value
是否等于当前 value
状态,添加 bg-gray-300
背景样式来高亮显示当前选中的选项。px-3
和 py-2
调整各个元素的内边距,使得组件在视觉上更加整齐。通过这些改进,组件能够动态显示选中内容,并在高级模式下显示图像,实现了更多的交互性和视觉效果。希望本视频帮助你在Storybook中更好地管理组件状态!
在这段视频中,我们添加了一个禁用(disabled)状态的故事给 SelectField
组件,并提出了一个小任务:为组件添加 size
和 rounded
属性。以下是具体步骤:
disabled
属性,并将默认值设为 false
。classNames
函数中,根据 disabled
状态添加禁用样式,例如:
bg-gray-200
,并根据需要进行调整。cursor-not-allowed
。size
和 rounded
属性:
size
属性接受值 small
、medium
和 large
,用于控制组件的大小。rounded
属性接受值 small
、medium
、large
和 full
,用于控制组件的圆角大小。size
和 rounded
值的效果。例如:
className={`${size === 'small' ? 'py-1 px-2' : size === 'medium' ? 'py-2 px-4' : 'py-3 px-6'} ${rounded === 'full' ? 'rounded-full' : rounded === 'large' ? 'rounded-lg' : 'rounded-sm'}`}
size
和 rounded
属性的任务。通过这些改进,可以在使用 SelectField
组件时更好地适应不同的使用场景,包括设置组件的大小、圆角以及禁用状态。希望这些步骤对您有所帮助!
在本视频中,我们开始创建 RadioField
组件及其基本样式,主要功能包括:
RadioField
组件的核心实现与 SelectField
类似,但呈现方式不同。radioProps
接口,包含了 label
、options
、disabled
、size
、rounded
等属性。orientation
属性,用于控制组件的水平或垂直布局。classNames
库在 className
中实现条件样式,以便在选中时更改边框宽度和颜色。RadioField
中,通过循环 options
数组来生成每个选项,默认情况下未选中的选项显示较浅的边框。useState
钩子保存当前选中的值,通过 onClick
事件更新选中状态。onClick
事件,在用户点击时触发选项的边框样式更改。RadioField
的 stories
文件中创建了模板,通过 args
和模板函数实现动态更新值。这个组件的实现提供了良好的基础,您可以进一步使用不同的颜色和样式来提升视觉效果。如果您对组件的细节还有疑问,请随时告知。
在本视频中,我们完成了 SelectField
组件的基础故事,并开始设计 RadioField
组件。主要要点如下:
RadioField
和 SelectField
具有相似的结构,但 RadioField
使用不同的 UI 表现方式。label
和 options
等属性来初始化 RadioField
组件,并添加了 orientation
属性来控制水平和垂直布局。orientation
(水平或垂直)、disabled
(是否禁用)、和 size
(组件尺寸)。radio
选项添加了自定义样式,包括高亮的边框和不同的颜色。classNames
库对 className
进行条件渲染,在选中时动态更新样式。useState
钩子来存储当前选中项,并通过 onClick
事件处理点击交互。RadioField
的 stories
文件中创建了一个模板,使得可以轻松管理和更新选项值。box-sizing: border-box
设置让边框内缩,从而避免超出问题。本视频为基础样式和交互逻辑打下了良好基础。如果对组件设计有疑问或建议,请随时告知!
在本视频中,我们完善了 RadioButton
组件的样式,并创建了相应的故事。主要步骤和改进包括:
border-4
和 border-5
),以更清晰地指示选中状态。border-primary
)和灰色(例如 border-gray-300
)。orientation
属性,用于切换水平和垂直布局。orientation
值(水平或垂直),使用 classNames
库动态调整布局方向。bg-gray-100
和 text-gray-300
)。pointer events
,并设置 cursor
为 not-allowed
,表示不可点击。RadioButton
。size
和 rounded
)的处理方式,以完成所有自定义需求。本视频使 RadioButton
组件的外观更加美观,并且通过增强其状态指示和布局配置,实现了更好的用户体验。如果有更多的疑问或需求,可以继续在下一视频中探索!
在本视频中,我们开发了开关 (Switch) 组件的基本功能,并编写了初始的故事。以下是主要步骤和实现细节:
Switch
组件,包含 label
、checked
、onChange
和 disabled
属性。checked
属性用于决定开关的状态(开/关),onChange
函数处理状态切换。className
条件渲染背景颜色和位置,根据 checked
状态改变开关的背景色(例如,打开时主色,关闭时灰色)。rounded
类使背景和白色圆形指示器的边缘更平滑。flex
布局,使白色指示器在不同状态下分别对齐到左侧或右侧。bg-gray-400
,而开启时使用 bg-primary
(设置为蓝色)。label
为“is active”,默认状态 checked
为 false
。useState
创建模板以管理 checked
状态,确保点击组件时状态发生切换。onClick
和 onChange
切换状态,从 false
到 true
并反之,以显示切换效果。本视频中为 Switch
组件奠定了基础,并且初步实现了主要功能。在下一视频中,我们将进一步优化并扩展该组件的功能,以满足更多需求。
在本视频中,我们进一步完善了开关 (Switch) 组件,增加了 orientation
和 disabled
属性,使其功能更加完整。以下是主要内容概述:
disabled
属性的实现disabled
属性后,即使 checked
为 true
,用户也无法更改开关状态。disabled
状态,使用了 opacity
降低组件透明度,并禁用了指针事件(pointer-events: none
)以阻止交互操作。cursor: not-allowed
,进一步增强了禁用时的视觉提示。orientation
属性的实现orientation
属性控制开关和标签的布局方向:
vertical
,开关在标签下方。horizontal
,开关则会显示在标签右侧。flex
布局调整方向,当 orientation
为 horizontal
时,使用 flex-row
,并通过 items-center
保证居中对齐。className
通过条件渲染,根据 orientation
的值灵活应用不同的 flex
样式。horizontal
和 vertical
布局。checked
为 true
且 disabled
的组合状态,以确保组件在禁用状态下显示正确。orientation
属性,并展示了组件的交互效果。flex-col
导致布局方向不变的问题。视频中为 Switch
组件引入了关键的交互属性,并通过 Storybook 展示了不同状态下的效果。若有任何疑问或需要进一步帮助,请随时提出。
在本视频中,我们开始开发模型弹出框 (Modal Popup) UI 组件,以下是主要内容的概述:
Modal
文件夹,并生成了主文件 index.tsx
。props
,包括:
showModal
:控制弹出框是否显示的布尔值。onCancel
:当点击关闭按钮时的回调函数。footer
:用于显示或隐藏弹出框底部的布尔值。title
和 children
:用于显示弹出框标题和内容。showModal
为 false
,组件将直接返回 null
,从而避免渲染。story
,用于展示弹出框组件的基础内容和关闭按钮。showModal
为 true
,以便默认显示弹出框。children
设置为简单的字符串 "Modal Content",可以替换为任何 HTML 内容。通过本视频的学习,我们搭建了模型弹出框组件的基础架构。在后续视频中,我们将继续改进组件,使其更具功能性和美观性。
在本视频中,我们继续为弹出框 (Modal Popup) UI 组件编写模板和样式。以下是关键步骤的概述:
stories
文件中创建模板函数 template
,并引入按钮,用于触发弹出框。showModal
状态为 true
以显示弹出框。outline
变体,并使用中等圆角边框。position: absolute
和 inset: 0
实现,并将背景颜色设为半透明黑色 (透明度 20-30%)。flex
布局,并使用 items-center
和 justify-center
实现水平和垂直居中。h1
标签,显示在左侧,右侧显示一个关闭图标,用户可以通过点击图标关闭弹出框。X
图标作为关闭按钮,添加 cursor-pointer
类名,以便图标显示为可点击状态。children
元素,接受字符串或 HTML 元素,确保弹出框可以包含多种内容。size
属性 (小、中、大) 来动态调整弹出框的宽度。small
显示为 1/4 屏宽,medium
为 1/2 屏宽,large
为 3/4 屏宽。medium
,并确保在故事文件中配置该默认值。通过本视频,我们实现了弹出框组件的模板和基础样式。在下一步中,将继续改进页脚部分,使弹出框更具功能性和实用性。
本视频中,我们开始构建一个标签 (Tabs) 组件。以下是主要的步骤:
Tabs
组件的文件和结构,并定义了接口 TabsProps
。tabsData
:包含多个对象的数组,每个对象代表一个标签页,包含 title
和 content
。activeTab
:表示当前活动的标签页索引。onTabChange
:用于在标签页切换时更新活动标签。disabledTabIndexes
:包含禁用标签页索引的数组。tabs.stories.tsx
文件来编写测试案例。tabsData
定义了三个基本标签页内容,分别为 tab1
、tab2
和 tab3
。template
,其中包含状态变量 activeTab
和 setActiveTab
。setActiveTab
函数处理标签切换,将 activeTab
传递给组件并更新标签页显示。Tabs
组件的样式,使其更具交互性和视觉效果,包括处理禁用标签页的样式和动态内容切换。这个基础结构为标签组件的样式和功能增强打下了良好的基础,后续步骤将进一步提升其可用性和用户体验。
本视频中,我们为标签组件 (Tabs) 添加了样式。以下是具体步骤:
flex
布局显示,并在每个标签之间增加 gap 5
。tabsData
循环遍历标签并渲染每个标签的标题。text-sm
和 text-primary
。border-primary
),并通过条件渲染来控制活动标签的颜色和边框宽度。onClick
事件,在点击标签时更新 activeTab
值,使得该标签成为活动标签。onTabChange
函数进行切换,成功地实现了标签的切换效果。text-gray-500
),只有活动标签具有主色。classNames
函数,动态切换标签的文本颜色和样式。tabsData[activeTab].content
),并确保每次切换时展示正确的内容。mt-5
用于控制内容与标签间的间距。theme provider
中更改主色以验证样式更新。下一步,我们将继续完善标签组件的功能,并为禁用的标签添加样式。
在本视频中,我们实现了标签组件 (Tabs) 的禁用功能,并增加了垂直布局。以下是具体步骤:
withDisabledTabs
示例,禁用某个指定的标签(如第二个标签)。pointer-events: none
阻止禁用标签的点击事件,使其不可点击。orientation
属性,默认情况下标签为水平排列。orientation
为 vertical
,则使用 flex-row
,否则使用 flex-column
。justify-start
和 border-right
来设置标签项和内容的对齐方式。border-right
代替 border-bottom
。gap
间距,使其在不同的布局下保持一致的视觉效果。padding
值,以优化组件的间距和对齐效果。通过本次视频的讲解,我们顺利实现了标签的禁用功能和垂直排列。我们还优化了组件的样式,使得各个布局效果在视觉上清晰直观。下个视频中,我们将继续完善标签组件的其他功能。
在本视频中,我们实现了一个基础的 Alert 组件,用于向用户显示信息性消息(如成功、失败、警告或错误提示)。以下是主要步骤:
components
目录下新建 Alert
组件文件 (index.tsx
)。AlertProps
,包括:
message
: 字符串,必填,表示警告信息。type
: 枚举类型,包括 success
, error
, warning
, 和 info
,表示消息类型。description
: 字符串,选填,作为消息的详细描述。showIcon
: 布尔值,表示是否显示图标(可选)。Alert.stories.tsx
文件,添加一个基础信息提示示例。className
函数进行样式控制:
padding
和 rounded
样式,确保每个 Alert 消息有适当的边距和圆角样式。bg-opacity
,以控制背景色的透明度,使其与内容形成适当的对比度。font-size
和 font-weight
,以确保用户可以清晰区分标题和描述。text-sm
,描述设置为 text-xs
,并根据需要设置适当的加粗样式。通过本次视频的讲解,我们实现了一个基础的 Alert 组件,涵盖了消息类型的多样化显示及基本样式。下个视频中,我们将继续为组件添加更多的故事示例,以进一步完善其功能和可用性。
在本视频中,我们继续完善了 Alert 组件的不同示例,添加了多种警报类型(成功、错误、警告)以及图标支持。以下是步骤总结:
Alert.stories.tsx
中添加了四种类型的警报(info、success、error 和 warning)。bg-opacity
设为 10,以确保颜色看起来不太浓重,同时保留了边框颜色的清晰度,使背景与内容形成适当对比。lucid-react
图标库,为每个警报类型选择合适的图标。通过 showIcon
属性控制图标的显示。Alert
组件中,通过条件渲染实现图标的显示,只有在 showIcon
设置为 true
时才渲染对应的图标。textColor
和图标大小,以确保整体外观的一致性。text
中增加 gap
和 item-center
等样式,以确保图标和文本之间有合适的空间。至此,我们已完成了 Alert 组件的不同类型和图标功能。在下个视频中,我们将添加关闭按钮的功能,使用户可以手动关闭警报消息。希望您喜欢这个演示!
在本视频中,我们实现了 Alert 组件的关闭功能。以下是具体步骤:
Alert
组件的属性中添加 closeable
作为布尔类型的属性。默认值为 false
,这样用户可以选择是否需要显示关闭按钮。Alert.stories.tsx
中的一个示例中将 closeable
设置为 true
,确保可以在故事中看到该功能。Alert
组件内部,添加了 showAlert
状态和 setShowAlert
函数。showAlert
为 true
时,组件正常显示;当它为 false
时,组件不会渲染。closeable
属性为 true
,在标题旁边添加了一个关闭按钮(一个 X
图标)。cursor pointer
,并在点击时调用 setShowAlert(false)
,从而隐藏警报。closeable
为 true
的情况下才会显示关闭图标。用户现在可以通过点击关闭图标来隐藏警报组件,从而实现了更好的用户交互。下一个步骤就是对这个功能进行全面测试并调整样式以确保一致性。
这就是 Alert 组件的关闭功能实现,感谢观看!
在本视频中,我们实现了 Spinner 组件。以下是实现步骤:
components
文件夹中创建了 Spinner
组件文件 Spinner.tsx
。spinnerProps
接口,定义了 size
(大小)、color
(颜色)等属性,用于自定义 Spinner。Spinner.stories.tsx
文件中为组件创建了不同的故事,以展示不同尺寸和颜色的 Spinner(如 small
、medium
和 large
)。classNames
库添加条件样式,根据 size
值设置高度、宽度和边框大小。animate-spin
和圆形 rounded-full
样式,使其看起来像一个旋转的圆圈。border-t-transparent
,以便形成旋转效果。style
属性设置 borderColor
,使其可以动态变化颜色。borderWidth
设置,通过调整不同尺寸的 Spinner 边框宽度来实现视觉差异。color
和 size
正常工作。现在,Spinner 组件可用于显示加载动画,并且可以根据需要定制尺寸和颜色。感谢观看!
在本视频中,我们为 Spinner 组件增加了辅助文本功能,用于在加载指示器下方显示文本,例如 "loading products"、"loading categories"、"loading users" 等。以下是实现步骤:
spinnerProps
中添加一个可选的 text
属性,用于传递要显示的加载文本。span
元素,用于显示辅助文本。text-gray-500
和 text-sm
设置文本的颜色和大小。flex-col
布局,并使用 gap-1
增加适当的间隔。Spinner.stories.tsx
文件中添加示例故事,传递不同的 text
值,如 "loading products",来测试 Spinner 的显示效果。通过这些步骤,我们的 Spinner 组件现在支持在指示器下方显示自定义文本,非常适用于不同的加载场景。感谢观看!
在这个视频中,我们实现了 Flex 容器的对齐和显示属性功能,帮助我们更灵活地控制组件的布局。以下是实现过程的概要:
classNames
库,并设置 Flex 容器的基本类名。flex
布局。direction
属性,以控制 Flex 容器的方向:
direction
是 "column",添加 flex-col
类,否则默认使用行布局。justify-start
、justify-center
和 justify-end
类控制水平对齐。items-start
、items-center
和 items-end
类控制垂直对齐。row
布局,垂直对齐属性应用于 column
布局。我们根据 align
和 justify
属性的值条件性地添加这些类。gap
属性并将其应用到样式中,设置组件之间的间距。showBorder
布尔属性,用于在 Flex 容器和子项上显示边框,便于观察布局和对齐效果。column
时,justify
属性将影响垂直方向,而 align
属性将控制水平方向的对齐。这样,我们就成功地实现了一个可以在不同方向和对齐方式之间切换的灵活布局组件。希望这个视频对你有所帮助!
在这个视频中,我们探讨了 Flex 容器的对齐和显示属性的实现步骤。以下是要点总结:
classNames
库,将 flex
设置为基础类名,因为组件本身是一个 Flex 容器。flex
类始终存在,无论传入的 props 是什么。direction
属性来控制 Flex 容器的方向:
direction
为 "column" 时,使用 flex-col
类,否则默认方向为行。flex-row
类。justify-start
、justify-center
和 justify-end
类来控制水平方向上的对齐。items-start
、items-center
和 items-end
类来控制垂直方向上的对齐。row
布局,而垂直对齐适用于 column
布局。gap
属性,并通过样式直接应用到组件中,以控制元素间的间距。showBorder
布尔属性,便于调试时观察布局效果。showBorder
为 true
时,为容器及其子元素添加灰色边框。column
,则 justify
用于控制垂直对齐,而 align
用于水平对齐。该视频展示了如何配置和测试 Flex 布局的对齐方式,帮助我们灵活地控制组件内容的布局。
在这个视频中,我们介绍了 Storybook 的 autodocs 功能及其在组件文档中的应用。以下是主要内容总结:
.stories
文件中,导出 component
和 title
。tags
属性,将其设置为包含 "autodocs"
的字符串数组。Autodocs 功能大大提高了组件文档的可读性和用户体验,非常适合更复杂的 UI 组件。
在本次视频中,我们讲解了如何将 Storybook 应用部署到云服务 Chromatic 上,以便轻松分享和维护组件库的文档。以下是关键步骤和内容的总结:
npm run build-storybook
来生成静态文档。storybook-static
文件夹推送到 GitHub,并确保项目的 .gitignore
文件中忽略 node_modules
和其他不必要的文件夹。npx chromatic --project-token=<your-token>
来启动 Storybook 的云端部署。通过这几个步骤,Chromatic 让我们能够快速部署和分享组件库的 Storybook 文档,简化了组件库的可访问性和可维护性。
构建并发布React UI组件库到NPM / Build and Publish React UI Component Library to NPM
课程大纲:
1 - 宣传与演示
2 - 介绍
3 - 配置 Rollup 并将库发布到 npm
4 - 测试与升级
5 - 添加 Tailwind CSS
6 - 增强按钮组件
7 - Storybook
8 - 输入框 (Input)
9 - 主题提供器
10 - 选择框 (Select)
11 - 单选框 (Radio)
12 - 开关 (Switch)
13 - 模态框 (Modal)
14 - 标签页 (Tabs)
15 - 警告框 (Alert)
16 - 加载动画 (Spinner)
17 - 弹性容器 (Flex Container)
18 - 文档编写与部署
这个大纲带你从项目设置和创建第一个组件开始,一步步指导如何发布到 npm、为库编写 story 并测试、添加 Tailwind CSS 和部署最终文档,让你能够顺利完成一个完整的 UI 组件库开发项目。
1 - Promo & Demo 1 -Course promo 2 -UI Component library demo
2 - Introduction 1 -Project setup 2 -Create first component
3 - Setup rollup and publish library in npm 1 -What is rollup 2 -Rollup installation 3 -Create rollup config 4 -Build with rollup 5 -Publish to npm
4 - Testing and upgrading 1 -Test published library 2 -Upgrade published library 3 -Testing library without re-publish
5 - Adding tailwind css 1 -Add pure css and build 2 -Add tailwind css and build 3 -Add classnames library for conditional classes
6 - Enhance button component 1 -Add size and border radius props 2 -Add icon prop
7 - Storybook 1 -Storybook intro 2 -Learn what is story and how to write 3 -Write story for button component - part 1 4 -Write story for button component - part 2 5 -Write story for button component - part 3
8 - Input 1 -Input component 2 -Input stories
9 - Theme provider 1 -Create theme provider wrapper 2 -Testing theme provider
10 - Select 1 -Create select component 2 -Select component stories - part 1 3 -Select component stories - part 2 4 -Select component stories - part 3
11 - Radio 1 -Create radio component 2 -Radio component stories - part 1 3 -Radio component stories - part 3
12 - Switch 1 -Create switch component 2 -Switch component stories
13 - Modal 1 -Create modal component 2 -Modal stories and UI
14 - Tabs 1 -Tabs component 2 -Tabs component UI and stories - part 1 3 -Tabs component UI and stories - part 2
15 - Alert 1 -Alert component 2 -Alert component stories - part 1 3 -Alert component stories - part 2
16 - Spinner 1 -Spinner component 2 -Spinner component stories
17 - Flex container 1 -Flex container component 2 -Flex container stories
18 - Documentation and deployment 1 -Add documentation to stories 2 -Deploy storybook app to chromatic