更新日志
最新更新和公告。
2024 年 8 月 - npx shadcn init
新的 CLI 现已可用。它是一个完全重写的版本,包含许多新功能和改进。现在您可以使用 npx shadcn add
安装组件、主题、hooks、utils 等。
这是朝着分发您和您的 LLM 可以访问和使用的代码迈出的重要一步。
- 首先,cli 现在开箱即用地支持所有主要的 React 框架。Next.js、Remix、Vite 和 Laravel。当您初始化到新应用中时,我们会更新您现有的 Tailwind 文件,而不是覆盖它们。
- 组件现在自带其依赖项。以手风琴组件为例,它可以定义自己的 Tailwind keyframes。当您将其添加到您的项目时,我们将相应地更新您的 tailwind.config.ts 文件。
- 您还可以使用 url 安装远程组件。
npx shadcn add https://acme.com/registry/navbar.json
。 - 我们还改进了 init 命令。它具有框架检测功能,甚至可以使用一个命令初始化一个全新的 Next.js 应用程序。
npx shadcn init
。 - 我们创建了一个新的 schema,您可以使用它来发布您自己的组件注册表。由于它支持 url,您甚至可以使用它来分发私有组件。
- 还有一些更新,例如更好的错误处理和 monorepo 支持。
您今天就可以试用新的 cli。
pnpm dlx shadcn init sidebar-01 login-01
更新您的项目
要更新现有项目以使用新的 CLI,请更新您的 components.json
文件,以包含您的组件、utils、ui、lib 和 hooks 的导入别名。
{
"$schema": "https://ui.shadcn.org.cn/schema.json",
"style": "new-york",
"tailwind": {
// ...
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
}
}
如果您使用的是不同的导入别名前缀,例如 ~
,请将 @
替换为您的前缀。
2024 年 4 月 - 引入 Lift Mode
我们为 Blocks 引入了一种新模式,称为 Lift Mode。
启用 Lift Mode 可自动从区块模板“提取”较小的组件,以进行复制和粘贴。
![Lift Mode](/_next/image?url=%2Fimages%2Flift-mode-light.png&w=3840&q=75)
使用 Lift Mode,您将能够复制构成区块模板的较小组件(如卡片、按钮和表单),并将它们直接粘贴到您的项目中。
访问 Blocks 页面进行试用。
2024 年 3 月 - 引入 Blocks
自发布以来,最受请求的功能之一是布局:带有侧边栏的管理仪表板、营销页面部分、卡片等。
今天,我们发布了 Blocks.
![管理仪表板](/_next/image?url=%2Fimages%2Fdashboard-1.jpg&w=1920&q=75)
Blocks 是现成的组件,您可以使用它们来构建您的应用程序。它们是完全响应式的、可访问的且可组合的,这意味着它们的构建原则与 shadcn/ui 中的其余组件相同。
我们从仪表板布局和身份验证页面开始,并计划在未来几周内添加更多区块。
开源
Blocks 是开源的。您可以在 GitHub 上找到源代码。在您的项目中使用它们,自定义它们并贡献代码。
![AI 游乐场](/_next/image?url=%2Fimages%2Fdashboard-2.jpg&w=1920&q=75)
请求区块
我们还推出了“请求区块”功能。如果您想看到特定的区块,只需在 GitHub 上创建一个请求,社区可以投票并构建它。
![设置页面](/_next/image?url=%2Fimages%2Fdashboard-3.jpg&w=1920&q=75)
v0
如果您有 v0 帐户,则可以使用“在 v0 中编辑”功能在 v0 上打开代码以进行提示和进一步生成。
就这样。期待看到您使用 Blocks 构建的内容。
2024 年 3 月 - 面包屑和 OTP 输入框
我们添加了一个新的面包屑组件和一个 OTP 输入框组件。
面包屑
一个可访问且灵活的面包屑组件。它支持折叠项目、自定义分隔符、自带路由 <Link />
以及可与 shadcn/ui 组件组合。
OTP 输入框
一个功能齐全的 OTP 输入框组件。它支持数字和字母数字代码、自定义长度、复制粘贴和可访问性。OTP 输入框构建于 input-otp 之上,作者是 @guilherme_rodz。
如果您有 v0,则新组件可用于生成。
2023 年 12 月 - 新组件、CLI 及更多
我们向 shadcn/ui 添加了新组件,并对 CLI 进行了许多改进。
以下是新功能的快速概述
- 轮播 - 一个具有动画、滑动和键盘支持的轮播组件。
- 抽屉 - 一个在移动设备上看起来很棒的抽屉组件。
- 分页 - 一个带有页面导航、上一个和下一个按钮的分页组件。
- 可调整大小 - 一个用于构建可调整大小的面板组和布局的可调整大小的组件。
- Sonner - 您需要的最后一个 toast 组件。
- CLI 更新 - 支持自定义 Tailwind 前缀 和
tailwind.config.ts
。
轮播
我们添加了一个功能齐全的轮播组件,具有动画、滑动和键盘支持。构建于 Embla Carousel 之上。
它支持无限循环、自动播放、垂直方向等。
抽屉
哦,抽屉组件😍。构建于 Vaul 之上,作者是 emilkowalski_。
尝试在移动设备上打开以下抽屉。它看起来很棒!
分页
我们添加了一个分页组件,其中包含页面导航、上一个和下一个按钮。简单、灵活,并且适用于您框架的 <Link />
组件。
可调整大小
使用此 <Resizable />
组件构建可调整大小的面板组和布局。
<Resizable />
使用 react-resizable-panels 构建,作者是 bvaughn。它支持鼠标、触摸和键盘。
Sonner
又一个来自 emilkowalski_ 的作品。您需要的最后一个 toast 组件。Sonner 现在在 shadcn/ui 中可用。
CLI 更新
这是最受请求的功能之一。您现在可以配置自定义 Tailwind 前缀,并且 cli 在添加组件时会自动为您的实用程序类添加前缀。
这意味着您现在可以轻松地将 shadcn/ui 组件添加到现有项目(如 Docusaurus、Nextra 等)。作为您现有设计系统的直接替代品,没有任何冲突。🔥
<AlertDialog className="tw-grid tw-gap-4 tw-border tw-bg-background tw-shadow-lg" />
它适用于 cn
、cva
和 CSS 变量。
cli 现在还可以检测 tailwind.config.ts
并为您添加 config 的 TypeScript 版本。
就这样。节日快乐。
2023 年 7 月 - JavaScript
此项目和组件是用 TypeScript 编写的。我们建议您的项目也使用 TypeScript。
但是,我们通过 cli 提供组件的 JavaScript 版本。
Would you like to use TypeScript (recommended)? no
要选择退出 TypeScript,您可以使用 tsx
标志在您的 components.json
文件中。
{
"style": "default",
"tailwind": {
"config": "tailwind.config.js",
"css": "src/app/globals.css",
"baseColor": "zinc",
"cssVariables": true
},
"rsc": false,
"tsx": false,
"aliases": {
"utils": "~/lib/utils",
"components": "~/components"
}
}
要配置导入别名,您可以使用以下 jsconfig.json
{
"compilerOptions": {
"paths": {
"@/*": ["./*"]
}
}
}
2023 年 6 月 - 新 CLI、样式及更多
今天我有很多更新要与您分享
- 新 CLI - 从头开始重写了 CLI。您现在可以添加组件、依赖项和配置导入路径。
- 主题 - 在使用 CSS 变量或 Tailwind CSS 实用程序类进行主题设置之间进行选择。
- 基础颜色 - 为您的项目配置基础颜色。这将用于生成组件的默认调色板。
- React Server Components - 选择不使用 React Server Components。CLI 将自动附加或删除
use client
指令。 - 样式 - 引入一个名为 Style 的新概念。样式带有自己的一组组件、动画、图标等。
- 退出动画 - 为所有组件添加了退出动画。
- 其他更新 - 新的
icon
按钮尺寸,更新的sheet
组件等。 - 更新您的项目 - 如何更新您的项目以获取最新更改。
新 CLI
在过去的几周里,我一直在开发一个新的 CLI。这是一个完全重写的版本。它带有许多新功能和改进。
init
pnpm dlx shadcn-ui@latest init
当您运行 init
命令时,系统会询问您几个问题来配置 components.json
。
Which style would you like to use? › Default
Which color would you like to use as base color? › Slate
Where is your global CSS file? › › app/globals.css
Do you want to use CSS variables for colors? › no / yes
Where is your tailwind.config.js located? › tailwind.config.js
Configure the import alias for components: › @/components
Configure the import alias for utils: › @/lib/utils
Are you using React Server Components? › no / yes
此文件包含有关您的组件的所有信息:组件的安装位置、导入路径、样式设置方式等等。
您可以使用此文件来更改组件的导入路径、设置 baseColor 或更改样式方法。
{
"style": "default",
"tailwind": {
"config": "tailwind.config.ts",
"css": "src/app/globals.css",
"baseColor": "zinc",
"cssVariables": true
},
"rsc": false,
"aliases": {
"utils": "~/lib/utils",
"components": "~/components"
}
}
这意味着您现在可以将 CLI 与任何目录结构一起使用,包括 src
和 app
目录。
add
pnpm dlx shadcn-ui@latest add
add
命令现在功能更强大了。您现在不仅可以添加 UI 组件,还可以导入更复杂的组件(即将推出)。
CLI 将自动解析所有组件和依赖项,根据您的自定义配置格式化它们,并将它们添加到您的项目中。
diff
(实验性功能)
pnpm dlx shadcn-ui diff
我们还引入了一个新的 diff
命令,以帮助您跟踪上游更新。
您可以使用此命令查看上游存储库中发生了哪些更改,并相应地更新您的项目。
运行 diff
命令以获取可用更新的组件列表
pnpm dlx shadcn-ui diff
The following components have updates available:
- button
- /path/to/my-app/components/ui/button.tsx
- toast
- /path/to/my-app/components/ui/use-toast.ts
- /path/to/my-app/components/ui/toaster.tsx
然后运行 diff [component]
以查看更改
pnpm dlx shadcn-ui diff alert
const alertVariants = cva(
- "relative w-full rounded-lg border",
+ "relative w-full pl-12 rounded-lg border"
)
使用 CSS 变量或 Tailwind Colors 进行主题化
您可以选择使用 CSS 变量或 Tailwind CSS 实用程序类进行主题化。
当您添加新组件时,CLI 将根据您的 components.json
配置自动使用正确的主题化方法。
实用程序类
<div className="bg-zinc-950 dark:bg-white" />
要使用实用程序类进行主题化,请在您的 components.json
文件中将 tailwind.cssVariables
设置为 false
。
{
"tailwind": {
"config": "tailwind.config.js",
"css": "app/globals.css",
"baseColor": "slate",
"cssVariables": false
}
}
CSS 变量
<div className="bg-background text-foreground" />
要使用 CSS 变量类进行主题化,请在您的 components.json
文件中将 tailwind.cssVariables
设置为 true
。
{
"tailwind": {
"config": "tailwind.config.js",
"css": "app/globals.css",
"baseColor": "slate",
"cssVariables": true
}
}
基础颜色
您现在可以为您的项目配置基础颜色。这将用于生成组件的默认调色板。
{
"tailwind": {
"config": "tailwind.config.js",
"css": "app/globals.css",
"baseColor": "zinc",
"cssVariables": false
}
}
在 gray
、neutral
、slate
、stone
或 zinc
之间选择。
如果您将 cssVariables
设置为 true
,我们将在您的 globals.css
文件中将基础颜色设置为 CSS 变量。如果您将 cssVariables
设置为 false
,我们将在您的组件中内联 Tailwind CSS 实用程序类。
React Server Components
如果您使用的框架不支持 React Server Components,您现在可以通过将 rsc
设置为 false
来选择退出。添加组件时,我们将自动附加或删除 use client
指令。
{
"rsc": false
}
样式
我们正在引入一个名为 *样式* 的新概念。
*您可以将样式视为视觉基础:形状、图标、动画和排版。* 一种样式带有自己的一组组件、动画、图标等等。
我们正在发布两种样式:default
和 new-york
(更多样式即将推出)。
![Default vs New York style](/_next/image?url=%2Fimages%2Fstyle.jpg&w=1920&q=75)
default
样式是您已经习惯的样式。它是自本项目开始以来我们一直使用的样式。它使用 lucide-react
作为图标,tailwindcss-animate
作为动画。
new-york
样式是一种新样式。它配备了更小的按钮、带有阴影的卡片以及来自 Radix Icons 的一组新图标。
当您运行 init
命令时,系统会询问您想使用哪种样式。这会保存在您的 components.json
文件中。
{
"style": "new-york"
}
主题化
从样式作为基础开始,然后使用 CSS 变量或 Tailwind CSS 实用程序类进行主题化,以完全改变组件的外观。
![Style with theming](/_next/image?url=%2Fimages%2Fstyle-with-theming.jpg&w=1920&q=75)
退出动画
我为所有组件添加了退出动画。单击下面的组合框以查看细微的退出动画。
可以使用实用程序类自定义动画。
其他更新
按钮
- 添加了新的按钮尺寸
icon
Sheet
- 将
position
重命名为side
以匹配其他元素。
- 删除了
size
属性。使用className="w-[200px] md:w-[450px]"
进行响应式尺寸调整。
更新您的项目
由于我们遵循复制粘贴的方法,您需要手动更新您的项目以获取最新的更改。
注意:我们正在开发一个 diff
命令,以帮助您跟踪上游更新。
添加 components.json
在根目录中创建 components.json
文件
{
"style": "default",
"rsc": true,
"tailwind": {
"config": "tailwind.config.js",
"css": "app/globals.css",
"baseColor": "slate",
"cssVariables": true
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils"
}
}
更新 tailwind.css
和 aliases
的值以匹配您的项目结构。
按钮
将 icon
尺寸添加到 buttonVariants
const buttonVariants = cva({
variants: {
size: {
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
lg: "h-11 rounded-md px-8",
icon: "h-10 w-10",
},
},
})
Sheet
- 将
sheet.tsx
的内容替换为以下内容
"use client"
import * as React from "react"
import * as SheetPrimitive from "@radix-ui/react-dialog"
import { cva, type VariantProps } from "class-variance-authority"
import { X } from "lucide-react"
import { cn } from "@/lib/utils"
const Sheet = SheetPrimitive.Root
const SheetTrigger = SheetPrimitive.Trigger
const SheetClose = SheetPrimitive.Close
const SheetPortal = ({
className,
...props
}: SheetPrimitive.DialogPortalProps) => (
<SheetPrimitive.Portal className={cn(className)} {...props} />
)
SheetPortal.displayName = SheetPrimitive.Portal.displayName
const SheetOverlay = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Overlay>,
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Overlay
className={cn(
"fixed inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className
)}
{...props}
ref={ref}
/>
))
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName
const sheetVariants = cva(
"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
{
variants: {
side: {
top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
bottom:
"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
right:
"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
},
},
defaultVariants: {
side: "right",
},
}
)
interface SheetContentProps
extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
VariantProps<typeof sheetVariants> {}
const SheetContent = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Content>,
SheetContentProps
>(({ side = "right", className, children, ...props }, ref) => (
<SheetPortal>
<SheetOverlay />
<SheetPrimitive.Content
ref={ref}
className={cn(sheetVariants({ side }), className)}
{...props}
>
{children}
<SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">
<X className="h-4 w-4" />
<span className="sr-only">Close</span>
</SheetPrimitive.Close>
</SheetPrimitive.Content>
</SheetPortal>
))
SheetContent.displayName = SheetPrimitive.Content.displayName
const SheetHeader = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col space-y-2 text-center sm:text-left",
className
)}
{...props}
/>
)
SheetHeader.displayName = "SheetHeader"
const SheetFooter = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
className
)}
{...props}
/>
)
SheetFooter.displayName = "SheetFooter"
const SheetTitle = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Title>,
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Title
ref={ref}
className={cn("text-lg font-semibold text-foreground", className)}
{...props}
/>
))
SheetTitle.displayName = SheetPrimitive.Title.displayName
const SheetDescription = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Description>,
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Description
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
))
SheetDescription.displayName = SheetPrimitive.Description.displayName
export {
Sheet,
SheetTrigger,
SheetClose,
SheetContent,
SheetHeader,
SheetFooter,
SheetTitle,
SheetDescription,
}
- 将
position
重命名为side
- <Sheet position="right" />
+ <Sheet side="right" />
感谢
我想感谢每一位使用本项目、提供反馈并为其做出贡献的人。我真的很感激。谢谢 🙏