shadcn/ui

文章目录

  • 前言
    • ✅ 核心特点
    • 支持组件(常用)
    • 安装使用(框架支持)
      • 初始化(Next.js 项目为例)
      • 添加一个组件
    • 对比其他组件库
    • 官方资源
    • ✅ 总结
      • ✅ 功能特性:
    • 依赖项(需先安装)
    • 页面代码:`ChatPage.tsx`
    • 可选样式增强(全局 CSS)
    • 进一步可添加功能


前言

shadcn/ui 是一个由社区维护的现代 UI 组件库模板集合,专为 React + Tailwind CSS 生态设计,主打:

  • ✨ 可完全控制样式 &行为(不像 MUI、AntD 那样封闭)
  • 基于 Radix UI(可访问性强)
  • 可选的组件拼装,不强绑设计系统
  • ⚙️ 支持 Server Component、SSR、RSC 等现代特性

✅ 核心特点

特性 说明
✨ 美观现代 默认采用干净、优雅的设计(类似 Vercel / Linear)
Tailwind 驱动 100% Tailwind CSS 控制样式,自由修改
⚛️ Radix UI 底层 提供无障碍可访问性支持(A11y)
可组合 所有组件是“导入代码”的方式,无 run-time 限制
可维护性强 你拥有组件代码本体(不再受限组件黑箱)

支持组件(常用)

分类 组件
表单 Input, Textarea, Select, Switch, Checkbox, Form
弹窗 Dialog, Popover, Tooltip, AlertDialog, Sheet
导航 Tabs, Accordion, DropdownMenu, NavigationMenu
其他 Toast, Badge, Card, Avatar, Skeleton, Progress

安装使用(框架支持)

支持 Vite、Next.js、Remix 等现代 React 框架。

初始化(Next.js 项目为例)

npx shadcn-ui@latest init

你会被提示:

  • 是否使用 TypeScript
  • UI 目录位置(如 components/ui
  • Tailwind 配置路径
  • 是否安装组件(如 Button, Dialog

添加一个组件

npx shadcn-ui@latest add button

生成的文件:

components/ui/button.tsx

你可以自由修改样式类或行为。


对比其他组件库

特性 shadcn/ui MUI Ant Design Chakra UI
样式控制 ✅ 完全控制 ❌ 封闭 ❌ 封闭 ⚠️ 类似
设计系统 ⚠️ 提供默认样式 ✅ 有 ✅ 有 ✅ 有
SSR 支持 ✅ 优秀 ⚠️ 需调整 ⚠️ 有限 ⚠️ 有限
适合 Tailwind ✅ 最佳搭配 ❌ 不兼容 ❌ 不兼容 ❌ 有冲突

官方资源

  • 官网:https://ui.shadcn.com
  • GitHub:https://github.com/shadcn-ui/ui
  • Demo 示例:https://ui.shadcn.com/docs/components/slider

✅ 总结

适合你吗? 条件
✅ 喜欢 Tailwind 强烈推荐
✅ 需要 SSR / RSC 兼容 推荐
✅ 想要样式可控且干净 UI 推荐
❌ 想要“开箱即用 + Theme切换 + 组件黑盒” 不太适合

下面是一个基于 shadcn/uiReactTailwind CSS 封装的 AI 聊天界面模板,具备如下特性:

✅ 功能特性:

  • 支持聊天消息滚动显示
  • 用户输入框 + 发送按钮
  • 显示用户消息和 AI 消息
  • 使用 shadcn/ui 组件:Input, Button, Card, ScrollArea, Skeleton
  • Tailwind 风格美观整洁

依赖项(需先安装)

npx shadcn-ui@latest init
npx shadcn-ui@latest add button input card scroll-area

页面代码:ChatPage.tsx

import { useState, useRef, useEffect } from "react"
import { Input } from "@/components/ui/input"
import { Button } from "@/components/ui/button"
import { ScrollArea } from "@/components/ui/scroll-area"
import { Card, CardContent } from "@/components/ui/card"

interface Message {
  role: "user" | "assistant"
  content: string
}

export default function ChatPage() {
  const [messages, setMessages] = useState<Message[]>([])
  const [input, setInput] = useState("")
  const scrollRef = useRef<HTMLDivElement>(null)

  const handleSend = async () => {
    if (!input.trim()) return

    const userMsg: Message = { role: "user", content: input }
    setMessages((prev) => [...prev, userMsg])
    setInput("")

    // 模拟 AI 回复
    setTimeout(() => {
      const aiMsg: Message = {
        role: "assistant",
        content: `你说的是:“${userMsg.content}`
      }
      setMessages((prev) => [...prev, aiMsg])
    }, 1000)
  }

  useEffect(() => {
    scrollRef.current?.scrollIntoView({ behavior: "smooth" })
  }, [messages])

  return (
    <div className="flex flex-col h-screen p-4 max-w-2xl mx-auto">
      <h2 className="text-2xl font-bold mb-4">AI Chat Assistant</h2>

      <ScrollArea className="flex-1 border rounded-lg p-4 space-y-2 bg-muted">
        {messages.map((msg, index) => (
          <Card key={index} className={msg.role === "user" ? "ml-auto bg-white" : "mr-auto bg-gray-100"}>
            <CardContent className="p-3 text-sm whitespace-pre-wrap">
              <strong>{msg.role === "user" ? "You" : "AI"}:</strong> {msg.content}
            </CardContent>
          </Card>
        ))}
        <div ref={scrollRef} />
      </ScrollArea>

      <div className="mt-4 flex gap-2">
        <Input
          placeholder="Ask something..."
          value={input}
          onChange={(e) => setInput(e.target.value)}
          onKeyDown={(e) => e.key === "Enter" && handleSend()}
        />
        <Button onClick={handleSend}>Send</Button>
      </div>
    </div>
  )
}

可选样式增强(全局 CSS)

body {
  @apply bg-background text-foreground;
}

进一步可添加功能

功能 shadcn 组件建议
Markdown 渲染 react-markdown 自定义卡片内容
Skeleton 骨架 Skeleton 组件用于 AI 回复加载中
多轮对话滚动 ScrollArea + useRef 自动滚动到底部
AI 流式回复 useEffect 模拟逐字加载即可

你可能感兴趣的:(AI应用开发相关,react,ui)