2025年10月 - 新组件
Spinner、Kbd、Button Group、Input Group、Field、Item 和 Empty 组件。
对于这一轮组件,我看了我们每天构建的东西,那些我们一遍又一遍重建的乏味东西,并且制作了你实际上可以使用的可重用抽象。
🌐 For this round of components, I looked at what we build every day, the boring stuff we rebuild over and over, and made reusable abstractions you can actually use.
这些组件可与所有组件库配合使用,无论是 Radix、Base UI、React Aria,都可以。复制并粘贴到你的项目中。
- Spinner:用于显示加载状态的指示器。
- Kbd:显示一个键盘按键或一组按键。
- 按钮组:一组用于操作和分割按钮的按钮。
- 输入组:包含图标、按钮、标签等的输入。
- 字段:一个组件。你所有的表单。
- 项目:显示项目列表、卡片等。
- 空:用于空状态。
旋转器
🌐 Spinner
好吧,让我们从最简单的开始:Spinner 和 Kbd。非常基础。我们都知道它们的作用。
🌐 Okay let's start with the easiest ones: Spinner and Kbd. Pretty basic. We all know what they do.
这是你呈现加载动画的方法:
🌐 Here's how you render a spinner:
import { Spinner } from "@/components/ui/spinner"<Spinner />它看起来像这样:
🌐 Here's what it looks like:
import { Spinner } from "@/components/ui/spinner"
export function SpinnerBasic() {它在按钮上的样子是这样的:
🌐 Here's what it looks like in a button:
import { Button } from "@/components/ui/button"
import { Spinner } from "@/components/ui/spinner"
你可以编辑代码,并用你自己的加载动画替换它。
🌐 You can edit the code and replace it with your own spinner.
import { LoaderIcon } from "lucide-react"
import { cn } from "@/lib/utils"键盘
🌐 Kbd
Kbd 是一个呈现键盘按键的组件。
🌐 Kbd is a component that renders a keyboard key.
import { Kbd, KbdGroup } from "@/components/ui/kbd"<Kbd>Ctrl</Kbd>使用 KbdGroup 将键盘上的按键分组。
🌐 Use KbdGroup to group keyboard keys together.
<KbdGroup>
<Kbd>Ctrl</Kbd>
<Kbd>B</Kbd>
</KbdGroup>import { Kbd, KbdGroup } from "@/components/ui/kbd"
export function KbdDemo() {你可以将其添加到按钮、工具提示、输入组等。
🌐 You can add it to buttons, tooltips, input groups, and more.
按钮组
🌐 Button Group
我收到了很多关于这个的请求:按钮组。它是一个容器,用于将相关按钮组合在一起,并保持一致的样式。非常适合操作组、分割按钮等。
🌐 I got a lot of requests for this one: Button Group. It's a container that groups related buttons together with consistent styling. Great for action groups, split buttons, and more.
"use client"
import * as React from "react"这是代码:
🌐 Here's the code:
import { ButtonGroup } from "@/components/ui/button-group"<ButtonGroup>
<Button>Button 1</Button>
<Button>Button 2</Button>
</ButtonGroup>你可以嵌套按钮组以创建具有间距的更复杂的布局。
🌐 You can nest button groups to create more complex layouts with spacing.
<ButtonGroup>
<ButtonGroup>
<Button>Button 1</Button>
<Button>Button 2</Button>
</ButtonGroup>
<ButtonGroup>
<Button>Button 3</Button>
<Button>Button 4</Button>
</ButtonGroup>
</ButtonGroup>使用 ButtonGroupSeparator 创建分割按钮。经典下拉模式。
🌐 Use ButtonGroupSeparator to create split buttons. Classic dropdown pattern.
"use client"
import {你也可以使用它向输入框添加前缀或后缀按钮和文本。
🌐 You can also use it to add prefix or suffix buttons and text to inputs.
"use client"
import * as React from "react"<ButtonGroup>
<ButtonGroupText>Prefix</ButtonGroupText>
<Input placeholder="Type something here..." />
<Button>Button</Button>
</ButtonGroup>输入组
🌐 Input Group
输入组让你可以在输入框中添加图标、按钮等元素。你知道的,那些你总是需要在输入框周围的小东西。
🌐 Input Group lets you add icons, buttons, and more to your inputs. You know, all those little bits you always need around your inputs.
import {
InputGroup,
InputGroupAddon,
InputGroupInput,
} from "@/components/ui/input-group"<InputGroup>
<InputGroupInput placeholder="Search..." />
<InputGroupAddon>
<SearchIcon />
</InputGroupAddon>
</InputGroup>这是带图标的预览:
🌐 Here's a preview with icons:
import {
CheckIcon,
CreditCardIcon,你也可以向输入组添加按钮。
🌐 You can also add buttons to the input group.
"use client"
import * as React from "react"或文本、标签、工具提示,...
🌐 Or text, labels, tooltips,...
import {
InputGroup,
InputGroupAddon,它也适用于文本区域,因此你可以构建具有许多旋钮和拨盘的复杂组件,或者另一个提示表单。
🌐 It also works with textareas so you can build really complex components with lots of knobs and dials or yet another prompt form.
import {
IconBrandJavascript,
IconCopy,哦,这里有一些带旋转器的很酷的东西:
🌐 Oh here are some cool ones with spinners:
import { LoaderIcon } from "lucide-react"
import {字段
🌐 Field
介绍 Field,一个用于构建非常复杂表单的组件。这种抽象非常美妙。
🌐 Introducing Field, a component for building really complex forms. The abstraction here is beautiful.
我花了很长时间才弄对,但我让它与你所有的表单库一起工作:Server Actions、React Hook Form、TanStack Form、Bring Your Own Form。
🌐 It took me a long time to get it right but I made it work with all your form libraries: Server Actions, React Hook Form, TanStack Form, Bring Your Own Form.
import {
Field,
FieldDescription,
FieldError,
FieldLabel,
} from "@/components/ui/field"这是一个带有输入框的基本字段:
🌐 Here's a basic field with an input:
<Field>
<FieldLabel htmlFor="username">Username</FieldLabel>
<Input id="username" placeholder="Max Leiter" />
<FieldDescription>
Choose a unique username for your account.
</FieldDescription>
</Field>import {
Field,
FieldDescription,它适用于所有表单控件。输入框、文本区域、下拉选择框、复选框、单选按钮、开关、滑块,尽你所能想到的都有。下面是一个完整的示例:
🌐 It works with all form controls. Inputs, textareas, selects, checkboxes, radios, switches, sliders, you name it. Here's a full example:
import { Button } from "@/components/ui/button"
import { Checkbox } from "@/components/ui/checkbox"
import {这里有一些复选框字段:
🌐 Here are some checkbox fields:
Your Desktop & Documents folders are being synced with iCloud Drive. You can access them from other devices.
import { Checkbox } from "@/components/ui/checkbox"
import {
Field,你可以使用 FieldGroup 和 FieldSet 将字段分组。非常适合多部分表单。
🌐 You can group fields together using FieldGroup and FieldSet. Perfect for
multi-section forms.
<FieldSet>
<FieldLegend />
<FieldGroup>
<Field />
<Field />
</FieldGroup>
</FieldSet>import {
Field,
FieldDescription,让它具有响应性很简单。使用 orientation="responsive",它会根据容器宽度在垂直和水平布局之间切换。完成。
🌐 Making it responsive is easy. Use orientation="responsive" and it switches
between vertical and horizontal layouts based on container width. Done.
import { Button } from "@/components/ui/button"
import {
Field,等等,还有更多。将你的字段封装在 FieldLabel 中以创建一个可选择的字段组。非常简单。而且看起来很棒。
🌐 Wait here's more. Wrap your fields in FieldLabel to create a selectable field group. Really easy. And it looks great.
import {
Field,
FieldContent,条目
🌐 Item
这是一个简单的弹性容器,几乎可以容纳任何类型的内容。
🌐 This one is a straightforward flex container that can house nearly any type of content.
我已经多次构建这个,因此我决定为它创建一个组件。现在我一直在使用它。我用它来显示项目列表、卡片等等。
🌐 I've built this so many times that I decided to create a component for it. Now I use it all the time. I use it to display lists of items, cards, and more.
import {
Item,
ItemContent,
ItemDescription,
ItemMedia,
ItemTitle,
} from "@/components/ui/item"这是一个基本条目:
🌐 Here's a basic item:
<Item>
<ItemMedia variant="icon">
<HomeIcon />
</ItemMedia>
<ItemContent>
<ItemTitle>Dashboard</ItemTitle>
<ItemDescription>Overview of your account and activity.</ItemDescription>
</ItemContent>
</Item>A simple item with title and description.
import { BadgeCheckIcon, ChevronRightIcon } from "lucide-react"
import { Button } from "@/components/ui/button"你可以向该项目添加图标、头像或图片。
🌐 You can add icons, avatars, or images to the item.
New login detected from unknown device.
import { ShieldAlertIcon } from "lucide-react"
import { Button } from "@/components/ui/button"Last seen 5 months ago
Invite your team to collaborate on this project.
import { Plus } from "lucide-react"
import {下面是带有 ItemGroup 的项目列表的样子:
🌐 And here's what a list of items looks like with ItemGroup:
shadcn@vercel.com
maxleiter@vercel.com
evilrabbit@vercel.com
import * as React from "react"
import { PlusIcon } from "lucide-react"
需要作为链接吗?使用 asChild 属性:
🌐 Need it as a link? Use the asChild prop:
<Item asChild>
<a href="/dashboard">
<ItemMedia variant="icon">
<HomeIcon />
</ItemMedia>
<ItemContent>
<ItemTitle>Dashboard</ItemTitle>
<ItemDescription>Overview of your account and activity.</ItemDescription>
</ItemContent>
</a>
</Item>import { ChevronRightIcon, ExternalLinkIcon } from "lucide-react"
import {空
🌐 Empty
好了,最后一个:空。在你的应用中使用它来显示空状态。
🌐 Okay last one: Empty. Use this to display empty states in your app.
import {
Empty,
EmptyContent,
EmptyDescription,
EmptyMedia,
EmptyTitle,
} from "@/components/ui/empty"使用方法如下:
🌐 Here's how you use it:
<Empty>
<EmptyMedia variant="icon">
<InboxIcon />
</EmptyMedia>
<EmptyTitle>No messages</EmptyTitle>
<EmptyDescription>You don't have any messages yet.</EmptyDescription>
<EmptyContent>
<Button>Send a message</Button>
</EmptyContent>
</Empty>import { IconFolderCode } from "@tabler/icons-react"
import { ArrowUpRightIcon } from "lucide-react"
你可以将它用于头像:
🌐 You can use it with avatars:
import {
Avatar,
AvatarFallback,或者对于搜索结果或电子邮件订阅等内容,使用输入组:
🌐 Or with input groups for things like search results or email subscriptions:
import { SearchIcon } from "lucide-react"
import {就是这样。七个新组件。兼容你所有的库。为你的项目做好准备。
🌐 That's it. Seven new components. Works with all your libraries. Ready for your projects.