- Published on
Shadcn UI 现代 UI 组件库
前言
不知道大家是否使用过 Shadcn UI,它在Github 上拥有了 35k star,它与大多数 UI 组件库(如 Ant desgin 和 Chakra UI)不同,一般组件库都是通过 npm 的方式给项目使用,代码都是存在 node_modules
中,而 Shadcn UI 可以将单个 UI 组件的源代码下载到项目源代码中(src 目录下),开发者可以自由的修改和使用想要的 UI 组件,它已经被一些知名的网站(vercel.com、bestofjs.org)等使用。那么它到底有什么优势呢? 一起来来探讨下。
Shadcn UI 介绍
Shadcn UI 实际上并不是组件库或 UI 框架。相反,它是可以根据文档“让我们复制并粘贴到应用程序中的可复用组件的集合”。它是由 vercel 的工程师Shadcn创建的,他还创建了一些知名的开源项目,如 Taxonomy,Next.js for Drupal和Reflexjs。
Radix UI - 是一个无头 UI 库。也就是说,它有组件 API,但没有样式。Shadcn UI 建立在 Tailwind CSS 和 Radix UI 之上,目前支持 Next.js、Gatsby、Remix、Astro、Laravel 和 Vite,并且拥有与其他项目快速集成的能力——安装指南。
Shadcn UI 功能特点
多主题和主题编辑器
在 Shadcn UI 的官网上有一个主题编辑器,我们可以点击 Customize
按钮实时切换风格和主题颜色,设计完成后,我们只需要拷贝 css 主要变量到我们的程序中即可。 下图是需要拷贝的 css 颜色变量。
颜色使用 hls 表示,主题变量分为背景色(background) 和 前景色(foreground),Shadcn UI 约定 css 变量省略 background,比如 --card
就是表示的是 card 组件的背景颜色。
深色模式
可以看到复制的 css 变量支持生成深色模式,如果你使用 react, 可以使用 next-themes,这个包来实现主题切换,当然也可以通过 js 在 html 上切换 dark 这个样式来实现。 除了 react 版,社区还自发实现了 vue 和 svelte 版本
CLI
除了手动从文档中复制组件代码到项目中,还可以使用 cli 来自动生成代码
- 初始化配置
npx shadcn-ui@latest init
- 添加组件
npx shadcn-ui@latest add
按空格选择想要的组件,按回车就会下载选中的 UI 组件代码
下载的源码在 components/ui
目录下,并且自动安装 Radix UI 对应的组件。
丰富的组件库
Shadcn UI 拥有丰富的组件,包括 常见的 Form、 Table、 Tab 等 40+ 组件。
使用 Shadcn UI 创建登录表单
接下来我们一起实战下,使用 Shadcn UI 创建登录表单, 由于 Shadcn UI 是一个纯 UI 组件,对于复杂的表单,我们还需要使用 react-hook-form 和 zod。
首先下载 UI
npx shadcn-ui@latest add form
安装 react-hook-form 以及 zod 验证相关的包
yarn add add react-hook-form zod @hookform/resolvers
zod 用于格式验证
下面代码是最基本的 Form 结构
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@/components/ui/form'
import { Input } from '@/components/ui/input'
;<FormField
control={form.control}
name="username"
render={({ field }) => (
<FormItem>
<FormLabel>Username</FormLabel>
<FormControl>
<Input placeholder="shadcn" {...field} />
</FormControl>
<FormDescription>This is your public display name.</FormDescription>
<FormMessage />
</FormItem>
)}
/>
FormField
用于生成受控的表单字段FormMessage
显示表单错误信息
登录表单代码
'use client'
import { zodResolver } from '@hookform/resolvers/zod'
import { useForm } from 'react-hook-form'
import * as z from 'zod'
import { Button } from '@/components/ui/button'
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@/components/ui/form'
import { Input } from '@/components/ui/input'
const formSchema = z.object({
email: z.string().email({ message: '邮箱格式不正确' }),
password: z.string({ required_error: '不能为空' }).min(6, {
message: '密码必须大于6位',
}),
})
export default function ProfileForm() {
// 1. Define your form.
const form =
useForm <
z.infer <
typeof formSchema >>
{
resolver: zodResolver(formSchema),
defaultValues: {
email: '',
},
}
// 2. Define a submit handler.
function onSubmit(values: z.infer<typeof formSchema>) {
// Do something with the form values.
// ✅ This will be type-safe and validated.
console.log(values)
}
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="mx-auto mt-10 w-80 space-y-4">
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>邮箱</FormLabel>
<FormControl>
<Input placeholder="请输入邮箱" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="password"
render={({ field }) => (
<FormItem>
<FormLabel>密码</FormLabel>
<FormControl>
<Input placeholder="请输入密码" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit">登录</Button>
</form>
</Form>
)
}
展示效果
小结
与其他组件库相比,Shadcn UI 提供了几个好处。
- 易用性:使用复制和粘贴或 CLI 安装方法可以轻松访问其组件.
- 可访问性:Shadcn UI 的组件是完全可访问的,并符合 Web 内容可访问性指南 (WCAG) 标准,它支持屏幕阅读器、键盘导航和其他辅助设备。
- 灵活和可扩展性:Shadcn UI 只会下载需要使用的组件在源码中,并且开发者可以灵活定制和修改。
当然需要手动拷贝安装每一个组件可能是一件麻烦的事情,这也会导致源码量的增加,因此是否使用 Shadcn UI 还得开发者自行决定,总的来说 Shadcn UI,我还是非常看好,我将配合 next.js 在一些新项目中使用。