Components
UI 组件
shadcn/ui 组件库使用指南
UI 组件
Vibetake 集成了 shadcn/ui 组件库,提供了一套高质量、可定制的 React 组件。
特性
- 🎨 现代设计 - 基于 Radix UI 和 Tailwind CSS
- 🔧 高度可定制 - 完全控制样式和行为
- ♿ 无障碍访问 - 遵循 WAI-ARIA 标准
- 📱 响应式 - 适配各种屏幕尺寸
- 🎯 TypeScript - 完整的类型支持
基础组件
Button 按钮
import { Button } from "@/components/ui/button";
export default function ButtonExample() {
return (
<div className="space-x-2">
<Button variant="default">默认按钮</Button>
<Button variant="secondary">次要按钮</Button>
<Button variant="destructive">危险按钮</Button>
<Button variant="outline">轮廓按钮</Button>
<Button variant="ghost">幽灵按钮</Button>
<Button variant="link">链接按钮</Button>
</div>
);
}
Input 输入框
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
export default function InputExample() {
return (
<div className="space-y-2">
<Label htmlFor="email">邮箱</Label>
<Input
id="email"
type="email"
placeholder="请输入邮箱地址"
/>
</div>
);
}
Card 卡片
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Button } from "@/components/ui/button";
export default function CardExample() {
return (
<Card className="w-[350px]">
<CardHeader>
<CardTitle>创建项目</CardTitle>
<CardDescription>
部署你的新项目只需一键操作。
</CardDescription>
</CardHeader>
<CardContent>
<form>
<div className="grid w-full items-center gap-4">
<div className="flex flex-col space-y-1.5">
<Label htmlFor="name">项目名称</Label>
<Input id="name" placeholder="我的项目" />
</div>
</div>
</form>
</CardContent>
<CardFooter className="flex justify-between">
<Button variant="outline">取消</Button>
<Button>部署</Button>
</CardFooter>
</Card>
);
}
表单组件
Form 表单
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { Button } from "@/components/ui/button";
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
const formSchema = z.object({
username: z.string().min(2, {
message: "用户名至少需要 2 个字符。",
}),
});
export default function FormExample() {
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
username: "",
},
});
function onSubmit(values: z.infer<typeof formSchema>) {
console.log(values);
}
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
<FormField
control={form.control}
name="username"
render={({ field }) => (
<FormItem>
<FormLabel>用户名</FormLabel>
<FormControl>
<Input placeholder="请输入用户名" {...field} />
</FormControl>
<FormDescription>
这是你的公开显示名称。
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit">提交</Button>
</form>
</Form>
);
}
导航组件
Tabs 标签页
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
export default function TabsExample() {
return (
<Tabs defaultValue="account" className="w-[400px]">
<TabsList>
<TabsTrigger value="account">账户</TabsTrigger>
<TabsTrigger value="password">密码</TabsTrigger>
</TabsList>
<TabsContent value="account">
<p>在这里管理你的账户设置。</p>
</TabsContent>
<TabsContent value="password">
<p>在这里修改你的密码。</p>
</TabsContent>
</Tabs>
);
}
反馈组件
Alert 警告
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { AlertCircle } from "lucide-react";
export default function AlertExample() {
return (
<Alert>
<AlertCircle className="h-4 w-4" />
<AlertTitle>注意!</AlertTitle>
<AlertDescription>
你可以在设置中添加组件到你的应用。
</AlertDescription>
</Alert>
);
}
Toast 提示
import { Button } from "@/components/ui/button";
import { useToast } from "@/components/ui/use-toast";
export default function ToastExample() {
const { toast } = useToast();
return (
<Button
onClick={() => {
toast({
title: "操作成功",
description: "你的设置已保存。",
});
}}
>
显示提示
</Button>
);
}
数据展示
Table 表格
import {
Table,
TableBody,
TableCaption,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
const invoices = [
{
invoice: "INV001",
paymentStatus: "已支付",
totalAmount: "$250.00",
paymentMethod: "信用卡",
},
// 更多数据...
];
export default function TableExample() {
return (
<Table>
<TableCaption>最近发票列表。</TableCaption>
<TableHeader>
<TableRow>
<TableHead className="w-[100px]">发票</TableHead>
<TableHead>状态</TableHead>
<TableHead>方式</TableHead>
<TableHead className="text-right">金额</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{invoices.map((invoice) => (
<TableRow key={invoice.invoice}>
<TableCell className="font-medium">{invoice.invoice}</TableCell>
<TableCell>{invoice.paymentStatus}</TableCell>
<TableCell>{invoice.paymentMethod}</TableCell>
<TableCell className="text-right">{invoice.totalAmount}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
);
}
自定义主题
颜色配置
/* globals.css */
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;
/* 更多颜色变量... */
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
/* 暗色主题变量... */
}
}
组件定制
// 自定义按钮变体
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
interface CustomButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: "default" | "custom";
}
export function CustomButton({ className, variant = "default", ...props }: CustomButtonProps) {
return (
<Button
className={cn(
variant === "custom" && "bg-gradient-to-r from-purple-500 to-pink-500",
className
)}
{...props}
/>
);
}
最佳实践
- 一致性 - 在整个应用中保持组件使用的一致性
- 可访问性 - 确保所有交互元素都有适当的 ARIA 标签
- 响应式 - 使用 Tailwind 的响应式类名适配不同屏幕
- 性能 - 按需导入组件,避免打包体积过大
- 定制 - 根据品牌需求适当定制组件样式