安装shadcn
Shadcn UI 是一个现代化的组件库集合,它基于 Radix UI 和 Tailwind CSS 构建。与传统的组件库不同,它采用了”复制粘贴”的方式 —— 你可以直接将组件代码复制到你的项目中,完全掌控组件的样式和行为。
接下来,让我们参考shadcn官方文档 来安装一下这个组件库。
在vscode中打开一个新的终端,运行如下命令(为了保持版本一致,我们指定一下shadcn的版本):
npx shadcn@2.3.0 init
如果你使用的是其他类型的包管理器,可以在上面的参考文档中找到相应的初始化命令来运行。
你可以指定版本,也可以不指定,直接用@latest
来安装最新的版本,只是我不确定不同的版本在后面是否会造成冲突。但是一般不会。如果在这里指定了版本,在后面安装其他shadcn组件时最好页指定一下同样的版本,以免造成冲突。
运行结果:
✔ Preflight checks.
✔ Verifying framework. Found Next.js.
✔ Validating Tailwind CSS.
✔ Validating import alias.
√ Which style would you like to use? » New York
√ Which color would you like to use as the base color? » Neutral
√ Would you like to use CSS variables for theming? ... no / yes
✔ Writing components.json.
✔ Checking registry.
✔ Updating tailwind.config.ts
✔ Updating srcappglobals.css
✔ Installing dependencies.
✔ Created 1 file:
- srclibutils.ts
Success! Project initialization completed.
You may now add components.
这时我们可以看到我们的项目目录已经产生了一些变化:
- src目录中增加了一个lib/utils.ts,其中定义了一个
cn
函数,供我们后续定义样式时合并类名使用; - globals.css增加了一些样式层;
- package.json里面新增了一些icon和样式依赖;
- tailwind.config.ts文件中新增了一些主题设置;
- 多了一个components.json文件,其中设置了一些关于shadcn和tailwindcss的信息。
安装shadcn组件
我们可以在shadcn官方文档的components下面挑选我们想要使用的组件,然后直接复制文档中的安装命令,即可安装相应的组件。在这里,我们先来安装一个button组件:
npx shadcn@2.3.0 add button
输出结果:
✔ Checking registry.
✔ Installing dependencies.
✔ Created 1 file:
- srccomponentsuibutton.tsx
这时候我们的src目录下就会新增一个components目录及其子目录ui和其中的button.tsx文件。我们可以在这个组件中自定义我们的button样式和属性。
测试button组件
删掉默认的根页面return中的视图层代码,改成如下代码:
import { Button } from "@/components/ui/button";
export default function Home() {
return (
<div className="flex space-x-2 m-4">
<Button variant="default">default</Button>
<Button variant="destructive">destructive</Button>
<Button variant="outline">outline</Button>
<Button variant="secondary">secondary</Button>
<Button variant="ghost">ghost</Button>
<Button variant="link">link</Button>
</div>
);
}
现在我们再看页面,就可以看到shadcn的Button组件自带的五种不同样式的按钮:
自定义button组件样式
除了这些自带的样式,我们还可以直接在components/ui/button.tsx
文件中定义我们自己的代码:
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
{
variants: {
variant: {
default:
"bg-primary text-primary-foreground shadow hover:bg-primary/90",
destructive:
"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
outline:
"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
secondary:
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
theme: "bg-indigo-500 text-white hover:bg-indigo-700"
},
size: {
default: "h-9 px-4 py-2",
sm: "h-8 rounded-md px-3 text-xs",
lg: "h-10 rounded-md px-8",
icon: "h-9 w-9",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button"
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
)
}
)
Button.displayName = "Button"
export { Button, buttonVariants }
如果想要设置自己的颜色,大家可以在tailwindcss官方文档 中查找相应的颜色名称,也可以通过在vscode中安装Tailwind CSS IntelliSense组件来激活tailwindcss样式的提示功能,直接在下拉提示框中选择自己想要的颜色即可。
然后在Home页增加一个variant
为theme
的Button
组件:
import { Button } from "@/components/ui/button";
export default function Home() {
return (
<div className="flex space-x-2 m-4">
<Button variant="default">default</Button>
<Button variant="destructive">destructive</Button>
<Button variant="outline">outline</Button>
<Button variant="secondary">secondary</Button>
<Button variant="ghost">ghost</Button>
<Button variant="link">link</Button>
<Button variant="theme">Theme</Button>
</div>
);
}
效果:
除了样式,我们还可以通过size="sm"
或size="lg"
规定按钮的大小,具体的样式可以查看components/ui/button.tsx
的代码。
在随后的开发中,我们还会用到shadcn的其他组件,等用到的时候再进行安装。如果你感兴趣,也可以找到自己喜欢的组件安装并试试效果。