mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-07-01 00:24:20 +00:00
@@ -79,7 +79,10 @@ export default async function Page(props: {
|
||||
|
||||
const doc = page.data
|
||||
const MDX = doc.body
|
||||
const neighbours = findNeighbour(source.pageTree, page.url)
|
||||
const isChangelog = params.slug?.[0] === "changelog"
|
||||
const neighbours = isChangelog
|
||||
? { previous: null, next: null }
|
||||
: findNeighbour(source.pageTree, page.url)
|
||||
const raw = await page.data.getText("raw")
|
||||
|
||||
return (
|
||||
|
||||
140
apps/v4/app/(app)/docs/changelog/page.tsx
Normal file
140
apps/v4/app/(app)/docs/changelog/page.tsx
Normal file
@@ -0,0 +1,140 @@
|
||||
import Link from "next/link"
|
||||
import { Button } from "@/examples/radix/ui/button"
|
||||
import { mdxComponents } from "@/mdx-components"
|
||||
import { IconRss } from "@tabler/icons-react"
|
||||
|
||||
import { getChangelogPages, type ChangelogPageData } from "@/lib/changelog"
|
||||
import { absoluteUrl } from "@/lib/utils"
|
||||
import { OpenInV0Cta } from "@/components/open-in-v0-cta"
|
||||
|
||||
export const revalidate = false
|
||||
export const dynamic = "force-static"
|
||||
|
||||
export function generateMetadata() {
|
||||
return {
|
||||
title: "Changelog",
|
||||
description: "Latest updates and announcements.",
|
||||
openGraph: {
|
||||
title: "Changelog",
|
||||
description: "Latest updates and announcements.",
|
||||
type: "article",
|
||||
url: absoluteUrl("/docs/changelog"),
|
||||
images: [
|
||||
{
|
||||
url: `/og?title=${encodeURIComponent(
|
||||
"Changelog"
|
||||
)}&description=${encodeURIComponent(
|
||||
"Latest updates and announcements."
|
||||
)}`,
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default function ChangelogPage() {
|
||||
const pages = getChangelogPages()
|
||||
const latestPages = pages.slice(0, 5)
|
||||
const olderPages = pages.slice(5)
|
||||
|
||||
return (
|
||||
<div
|
||||
data-slot="docs"
|
||||
className="flex scroll-mt-24 items-stretch pb-8 text-[1.05rem] sm:text-[15px] xl:w-full"
|
||||
>
|
||||
<div className="flex min-w-0 flex-1 flex-col">
|
||||
<div className="h-(--top-spacing) shrink-0" />
|
||||
<div className="mx-auto flex w-full max-w-[40rem] min-w-0 flex-1 flex-col gap-6 px-4 py-6 text-neutral-800 md:px-0 lg:py-8 dark:text-neutral-300">
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<h1 className="scroll-m-24 text-4xl font-semibold tracking-tight sm:text-3xl">
|
||||
Changelog
|
||||
</h1>
|
||||
<Button variant="secondary" size="sm" asChild>
|
||||
<a href="/rss.xml" target="_blank" rel="noopener noreferrer">
|
||||
<IconRss />
|
||||
RSS
|
||||
</a>
|
||||
</Button>
|
||||
</div>
|
||||
<p className="text-muted-foreground text-[1.05rem] sm:text-base sm:text-balance md:max-w-[80%]">
|
||||
Latest updates and announcements.
|
||||
</p>
|
||||
</div>
|
||||
<div className="w-full flex-1 pb-16 sm:pb-0">
|
||||
{latestPages.map((page) => {
|
||||
const data = page.data as ChangelogPageData
|
||||
const MDX = page.data.body
|
||||
|
||||
return (
|
||||
<article key={page.url} className="mb-12 border-b pb-12">
|
||||
<h2 className="font-heading text-xl font-semibold tracking-tight">
|
||||
{data.title}
|
||||
</h2>
|
||||
<div className="prose-changelog mt-6 *:first:mt-0">
|
||||
<MDX components={mdxComponents} />
|
||||
</div>
|
||||
</article>
|
||||
)
|
||||
})}
|
||||
{olderPages.length > 0 && (
|
||||
<div id="more-updates" className="mb-24 scroll-mt-24">
|
||||
<h2 className="font-heading mb-6 text-xl font-semibold tracking-tight">
|
||||
More Updates
|
||||
</h2>
|
||||
<ul className="flex flex-col gap-4">
|
||||
{olderPages.map((page) => {
|
||||
const data = page.data as ChangelogPageData
|
||||
return (
|
||||
<li key={page.url} className="flex items-center gap-3">
|
||||
<Link
|
||||
href={page.url}
|
||||
className="font-medium hover:underline"
|
||||
>
|
||||
{data.title}
|
||||
</Link>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="sticky top-[calc(var(--header-height)+1px)] z-30 ml-auto hidden h-[90svh] w-72 flex-col gap-4 overflow-hidden overscroll-none pb-8 lg:flex">
|
||||
<div className="h-(--top-spacing) shrink-0"></div>
|
||||
<div className="no-scrollbar flex flex-col gap-8 overflow-y-auto px-8">
|
||||
<div className="flex flex-col gap-2 p-4 pt-0 text-sm">
|
||||
<p className="text-muted-foreground bg-background sticky top-0 h-6 text-xs font-medium">
|
||||
On This Page
|
||||
</p>
|
||||
{latestPages.map((page) => {
|
||||
const data = page.data as ChangelogPageData
|
||||
return (
|
||||
<Link
|
||||
key={page.url}
|
||||
href={page.url}
|
||||
className="text-muted-foreground hover:text-foreground text-[0.8rem] no-underline transition-colors"
|
||||
>
|
||||
{data.title}
|
||||
</Link>
|
||||
)
|
||||
})}
|
||||
{olderPages.length > 0 && (
|
||||
<a
|
||||
href="#more-updates"
|
||||
className="text-muted-foreground hover:text-foreground text-[0.8rem] no-underline transition-colors"
|
||||
>
|
||||
More Updates
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="hidden flex-1 flex-col gap-6 px-6 xl:flex">
|
||||
<OpenInV0Cta />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -57,6 +57,11 @@ export const metadata: Metadata = {
|
||||
apple: "/apple-touch-icon.png",
|
||||
},
|
||||
manifest: `${siteConfig.url}/site.webmanifest`,
|
||||
alternates: {
|
||||
types: {
|
||||
"application/rss+xml": `${siteConfig.url}/rss.xml`,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export default function RootLayout({
|
||||
|
||||
44
apps/v4/app/rss.xml/route.ts
Normal file
44
apps/v4/app/rss.xml/route.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { NextResponse } from "next/server"
|
||||
|
||||
import { getChangelogPages, type ChangelogPageData } from "@/lib/changelog"
|
||||
import { siteConfig } from "@/lib/config"
|
||||
|
||||
export const revalidate = false
|
||||
|
||||
export async function GET() {
|
||||
const pages = getChangelogPages()
|
||||
|
||||
const items = pages
|
||||
.map((page) => {
|
||||
const data = page.data as ChangelogPageData
|
||||
const date = page.date?.toUTCString() ?? new Date().toUTCString()
|
||||
const link = `${siteConfig.url}/docs/${page.slugs.join("/")}`
|
||||
|
||||
return ` <item>
|
||||
<title><![CDATA[${data.title}]]></title>
|
||||
<link>${link}</link>
|
||||
<guid>${link}</guid>
|
||||
<description><![CDATA[${data.description || ""}]]></description>
|
||||
<pubDate>${date}</pubDate>
|
||||
</item>`
|
||||
})
|
||||
.join("\n")
|
||||
|
||||
const xml = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>${siteConfig.name} Changelog</title>
|
||||
<link>${siteConfig.url}</link>
|
||||
<description>${siteConfig.description}</description>
|
||||
<language>en-us</language>
|
||||
<atom:link href="${siteConfig.url}/rss.xml" rel="self" type="application/rss+xml"/>
|
||||
${items}
|
||||
</channel>
|
||||
</rss>`
|
||||
|
||||
return new NextResponse(xml, {
|
||||
headers: {
|
||||
"Content-Type": "application/rss+xml; charset=utf-8",
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -49,7 +49,7 @@ const TOP_LEVEL_SECTIONS = [
|
||||
href: "/docs/changelog",
|
||||
},
|
||||
]
|
||||
const EXCLUDED_SECTIONS = ["installation", "dark-mode"]
|
||||
const EXCLUDED_SECTIONS = ["installation", "dark-mode", "changelog"]
|
||||
const EXCLUDED_PAGES = ["/docs", "/docs/changelog"]
|
||||
|
||||
export function DocsSidebar({
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,7 +13,7 @@
|
||||
"javascript",
|
||||
"blocks",
|
||||
"figma",
|
||||
"changelog",
|
||||
"[Changelog](/docs/changelog)",
|
||||
"[llms.txt](/llms.txt)",
|
||||
"legacy"
|
||||
]
|
||||
|
||||
478
apps/v4/content/docs/changelog/2023-06-new-cli.mdx
Normal file
478
apps/v4/content/docs/changelog/2023-06-new-cli.mdx
Normal file
@@ -0,0 +1,478 @@
|
||||
---
|
||||
title: June 2023 - New CLI, Styles and more
|
||||
description: Complete CLI rewrite with new styles, theming options, and more.
|
||||
date: 2023-06-22
|
||||
---
|
||||
|
||||
I have a lot of updates to share with you today:
|
||||
|
||||
- [**New CLI**](#new-cli) - Rewrote the CLI from scratch. You can now add components, dependencies and configure import paths.
|
||||
- [**Theming**](#theming-with-css-variables-or-tailwind-colors) - Choose between using CSS variables or Tailwind CSS utility classes for theming.
|
||||
- [**Base color**](#base-color) - Configure the base color for your project. This will be used to generate the default color palette for your components.
|
||||
- [**React Server Components**](#react-server-components) - Opt out of using React Server Components. The CLI will automatically append or remove the `use client` directive.
|
||||
- [**Styles**](#styles) - Introducing a new concept called _Style_. A style comes with its own set of components, animations, icons and more.
|
||||
- [**Exit animations**](#exit-animations) - Added exit animations to all components.
|
||||
- [**Other updates**](#other-updates) - New `icon` button size, updated `sheet` component and more.
|
||||
- [**Updating your project**](#updating-your-project) - How to update your project to get the latest changes.
|
||||
|
||||
---
|
||||
|
||||
### New CLI
|
||||
|
||||
I've been working on a new CLI for the past few weeks. It's a complete rewrite. It comes with a lot of new features and improvements.
|
||||
|
||||
### `init`
|
||||
|
||||
```bash
|
||||
npx shadcn@latest init
|
||||
```
|
||||
|
||||
When you run the `init` command, you will be asked a few questions to configure `components.json`:
|
||||
|
||||
```txt showLineNumbers
|
||||
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
|
||||
```
|
||||
|
||||
This file contains all the information about your components: where to install them, the import paths, how they are styled...etc.
|
||||
|
||||
You can use this file to change the import path of a component, set a baseColor or change the styling method.
|
||||
|
||||
```json title="components.json" showLineNumbers
|
||||
{
|
||||
"style": "default",
|
||||
"tailwind": {
|
||||
"config": "tailwind.config.ts",
|
||||
"css": "src/app/globals.css",
|
||||
"baseColor": "zinc",
|
||||
"cssVariables": true
|
||||
},
|
||||
"rsc": false,
|
||||
"aliases": {
|
||||
"utils": "~/lib/utils",
|
||||
"components": "~/components"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This means you can now use the CLI with any directory structure including `src` and `app` directories.
|
||||
|
||||
### `add`
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add
|
||||
```
|
||||
|
||||
The `add` command is now much more capable. You can now add UI components but also import more complex components (coming soon).
|
||||
|
||||
The CLI will automatically resolve all components and dependencies, format them based on your custom config and add them to your project.
|
||||
|
||||
### `diff` (experimental)
|
||||
|
||||
```bash
|
||||
npx shadcn diff
|
||||
```
|
||||
|
||||
We're also introducing a new `diff` command to help you keep track of upstream updates.
|
||||
|
||||
You can use this command to see what has changed in the upstream repository and update your project accordingly.
|
||||
|
||||
Run the `diff` command to get a list of components that have updates available:
|
||||
|
||||
```bash
|
||||
npx shadcn diff
|
||||
```
|
||||
|
||||
```txt
|
||||
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
|
||||
```
|
||||
|
||||
Then run `diff [component]` to see the changes:
|
||||
|
||||
```bash
|
||||
npx shadcn diff alert
|
||||
```
|
||||
|
||||
```diff /pl-12/
|
||||
const alertVariants = cva(
|
||||
- "relative w-full rounded-lg border",
|
||||
+ "relative w-full pl-12 rounded-lg border"
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Theming with CSS Variables or Tailwind Colors
|
||||
|
||||
You can choose between using CSS variables or Tailwind CSS utility classes for theming.
|
||||
|
||||
When you add new components, the CLI will automatically use the correct theming methods based on your `components.json` configuration.
|
||||
|
||||
#### Utility classes
|
||||
|
||||
```tsx /bg-zinc-950/ /text-zinc-50/ /dark:bg-white/ /dark:text-zinc-950/
|
||||
<div className="bg-zinc-950 dark:bg-white" />
|
||||
```
|
||||
|
||||
To use utility classes for theming set `tailwind.cssVariables` to `false` in your `components.json` file.
|
||||
|
||||
```json {6} title="components.json" showLineNumbers
|
||||
{
|
||||
"tailwind": {
|
||||
"config": "tailwind.config.js",
|
||||
"css": "app/globals.css",
|
||||
"baseColor": "slate",
|
||||
"cssVariables": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### CSS Variables
|
||||
|
||||
```tsx /bg-background/ /text-foreground/
|
||||
<div className="bg-background text-foreground" />
|
||||
```
|
||||
|
||||
To use CSS variables classes for theming set `tailwind.cssVariables` to `true` in your `components.json` file.
|
||||
|
||||
```json {6} title="components.json" showLineNumbers
|
||||
{
|
||||
"tailwind": {
|
||||
"config": "tailwind.config.js",
|
||||
"css": "app/globals.css",
|
||||
"baseColor": "slate",
|
||||
"cssVariables": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Base color
|
||||
|
||||
You can now configure the base color for your project. This will be used to generate the default color palette for your components.
|
||||
|
||||
```json {5} title="components.json" showLineNumbers
|
||||
{
|
||||
"tailwind": {
|
||||
"config": "tailwind.config.js",
|
||||
"css": "app/globals.css",
|
||||
"baseColor": "zinc",
|
||||
"cssVariables": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Choose between `gray`, `neutral`, `slate`, `stone` or `zinc`.
|
||||
|
||||
If you have `cssVariables` set to `true`, we will set the base colors as CSS variables in your `globals.css` file. If you have `cssVariables` set to `false`, we will inline the Tailwind CSS utility classes in your components.
|
||||
|
||||
---
|
||||
|
||||
### React Server Components
|
||||
|
||||
If you're using a framework that does not support React Server Components, you can now opt out by setting `rsc` to `false`. We will automatically append or remove the `use client` directive when adding components.
|
||||
|
||||
```json title="components.json" showLineNumbers
|
||||
{
|
||||
"rsc": false
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Styles
|
||||
|
||||
We are introducing a new concept called _Style_.
|
||||
|
||||
_You can think of style as the visual foundation: shapes, icons, animations & typography._ A style comes with its own set of components, animations, icons and more.
|
||||
|
||||
We are shipping two styles: `default` and `new-york` (with more coming soon).
|
||||
|
||||
<Image
|
||||
src="/images/style.jpg"
|
||||
width="716"
|
||||
height="402"
|
||||
alt="Default vs New York style"
|
||||
className="mt-6 overflow-hidden rounded-lg border"
|
||||
/>
|
||||
|
||||
The `default` style is the one you are used to. It's the one we've been using since the beginning of this project. It uses `lucide-react` for icons and `tailwindcss-animate` for animations.
|
||||
|
||||
The `new-york` style is a new style. It ships with smaller buttons, cards with shadows and a new set of icons from [Radix Icons](https://icons.radix-ui.com).
|
||||
|
||||
When you run the `init` command, you will be asked which style you would like to use. This is saved in your `components.json` file.
|
||||
|
||||
```json title="components.json" showLineNumbers
|
||||
{
|
||||
"style": "new-york"
|
||||
}
|
||||
```
|
||||
|
||||
### Theming
|
||||
|
||||
Start with a style as the base then theme using CSS variables or Tailwind CSS utility classes to completely change the look of your components.
|
||||
|
||||
<Image
|
||||
src="/images/style-with-theming.jpg"
|
||||
width="716"
|
||||
height="402"
|
||||
alt="Style with theming"
|
||||
className="mt-6 overflow-hidden rounded-lg border"
|
||||
/>
|
||||
|
||||
---
|
||||
|
||||
### Exit animations
|
||||
|
||||
I added exit animations to all components. Click on the combobox below to see the subtle exit animation.
|
||||
|
||||
<ComponentPreview name="combobox-demo" className="[&_.preview]:items-start" />
|
||||
|
||||
The animations can be customized using utility classes.
|
||||
|
||||
---
|
||||
|
||||
### Other updates
|
||||
|
||||
### Button
|
||||
|
||||
- Added a new button size `icon`:
|
||||
|
||||
<ComponentPreview name="button-icon" />
|
||||
|
||||
### Sheet
|
||||
|
||||
- Renamed `position` to `side` to match the other elements.
|
||||
|
||||
<ComponentPreview name="sheet-side" />
|
||||
|
||||
- Removed the `size` props. Use `className="w-[200px] md:w-[450px]"` for responsive sizing.
|
||||
|
||||
---
|
||||
|
||||
### Updating your project
|
||||
|
||||
Since we follow a copy and paste approach, you will need to manually update your project to get the latest changes.
|
||||
|
||||
<Callout className="mt-4">
|
||||
Note: we are working on a [`diff`](#diff-experimental) command to help you
|
||||
keep track of upstream updates.
|
||||
</Callout>
|
||||
|
||||
<Steps>
|
||||
|
||||
### Add `components.json`
|
||||
|
||||
Creating a `components.json` file at the root:
|
||||
|
||||
```json title="components.json" showLineNumbers
|
||||
{
|
||||
"style": "default",
|
||||
"rsc": true,
|
||||
"tailwind": {
|
||||
"config": "tailwind.config.js",
|
||||
"css": "app/globals.css",
|
||||
"baseColor": "slate",
|
||||
"cssVariables": true
|
||||
},
|
||||
"aliases": {
|
||||
"components": "@/components",
|
||||
"utils": "@/lib/utils"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Update the values for `tailwind.css` and `aliases` to match your project structure.
|
||||
|
||||
### Button
|
||||
|
||||
Add the `icon` size to the `buttonVariants`:
|
||||
|
||||
```tsx {7} title="components/ui/button.tsx" showLineNumbers
|
||||
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
|
||||
|
||||
1. Replace the content of `sheet.tsx` with the following:
|
||||
|
||||
```tsx title="components/ui/sheet.tsx" showLineNumbers
|
||||
"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(
|
||||
"bg-background/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 backdrop-blur-sm",
|
||||
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="ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-none disabled:pointer-events-none">
|
||||
<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-foreground text-lg font-semibold", 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-muted-foreground text-sm", className)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
SheetDescription.displayName = SheetPrimitive.Description.displayName
|
||||
|
||||
export {
|
||||
Sheet,
|
||||
SheetTrigger,
|
||||
SheetClose,
|
||||
SheetContent,
|
||||
SheetHeader,
|
||||
SheetFooter,
|
||||
SheetTitle,
|
||||
SheetDescription,
|
||||
}
|
||||
```
|
||||
|
||||
2. Rename `position` to `side`
|
||||
|
||||
```diff /position/ /side/
|
||||
- <Sheet position="right" />
|
||||
+ <Sheet side="right" />
|
||||
```
|
||||
|
||||
</Steps>
|
||||
|
||||
### Thank you
|
||||
|
||||
I'd like to thank everyone who has been using this project, providing feedback and contributing to it. I really appreciate it. Thank you.
|
||||
45
apps/v4/content/docs/changelog/2023-07-javascript.mdx
Normal file
45
apps/v4/content/docs/changelog/2023-07-javascript.mdx
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
title: July 2023 - JavaScript
|
||||
description: JavaScript version of components available via the CLI.
|
||||
date: 2023-07-04
|
||||
---
|
||||
|
||||
This project and the components are written in TypeScript. **We recommend using TypeScript for your project as well**.
|
||||
|
||||
However we provide a JavaScript version of the components, available via the [cli](/docs/cli).
|
||||
|
||||
```txt
|
||||
Would you like to use TypeScript (recommended)? no
|
||||
```
|
||||
|
||||
To opt-out of TypeScript, you can use the `tsx` flag in your `components.json` file.
|
||||
|
||||
```json {10} title="components.json" showLineNumbers
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To configure import aliases, you can use the following `jsconfig.json`:
|
||||
|
||||
```json {4} title="jsconfig.json" showLineNumbers
|
||||
{
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"@/*": ["./*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
68
apps/v4/content/docs/changelog/2023-12-new-components.mdx
Normal file
68
apps/v4/content/docs/changelog/2023-12-new-components.mdx
Normal file
@@ -0,0 +1,68 @@
|
||||
---
|
||||
title: December 2023 - New Components
|
||||
description: Carousel, Drawer, Pagination, Resizable, Sonner, and CLI updates.
|
||||
date: 2023-12-22
|
||||
---
|
||||
|
||||
We've added new components to shadcn/ui and made a lot of improvements to the CLI.
|
||||
|
||||
Here's a quick overview of what's new:
|
||||
|
||||
- [**Carousel**](#carousel) - A carousel component with motion, swipe gestures and keyboard support.
|
||||
- [**Drawer**](#drawer) - A drawer component that looks amazing on mobile.
|
||||
- [**Pagination**](#pagination) - A pagination component with page navigation, previous and next buttons.
|
||||
- [**Resizable**](#resizable) - A resizable component for building resizable panel groups and layouts.
|
||||
- [**Sonner**](#sonner) - The last toast component you'll ever need.
|
||||
- [**CLI updates**](#cli-updates) - Support for custom **Tailwind prefix** and `tailwind.config.ts`.
|
||||
|
||||
### Carousel
|
||||
|
||||
We've added a fully featured carousel component with motion, swipe gestures and keyboard support. Built on top of [Embla Carousel](https://www.embla-carousel.com).
|
||||
|
||||
It has support for infinite looping, autoplay, vertical orientation, and more.
|
||||
|
||||
<ComponentPreview name="carousel-demo" />
|
||||
|
||||
### Drawer
|
||||
|
||||
Oh the drawer component. Built on top of [Vaul](https://github.com/emilkowalski/vaul) by [emilkowalski](https://twitter.com/emilkowalski).
|
||||
|
||||
Try opening the following drawer on mobile. It looks amazing!
|
||||
|
||||
<ComponentPreview name="drawer-demo" />
|
||||
|
||||
### Pagination
|
||||
|
||||
We've added a pagination component with page navigation, previous and next buttons. Simple, flexible and works with your framework's `<Link />` component.
|
||||
|
||||
<ComponentPreview name="pagination-demo" />
|
||||
|
||||
### Resizable
|
||||
|
||||
Build resizable panel groups and layouts with this `<Resizable />` component.
|
||||
|
||||
<ComponentPreview name="resizable-demo-with-handle" />
|
||||
|
||||
`<Resizable />` is built using [react-resizable-panels](https://github.com/bvaughn/react-resizable-panels) by [bvaughn](https://github.com/bvaughn). It has support for mouse, touch and keyboard.
|
||||
|
||||
### Sonner
|
||||
|
||||
Another one by [emilkowalski](https://twitter.com/emilkowalski). The last toast component you'll ever need. Sonner is now availabe in shadcn/ui.
|
||||
|
||||
<ComponentPreview name="sonner-demo" />
|
||||
|
||||
### CLI updates
|
||||
|
||||
This has been one of the most requested features. You can now configure a custom Tailwind prefix and the cli will automatically prefix your utility classes when adding components.
|
||||
|
||||
This means you can now easily add shadcn/ui components to existing projects like Docusaurus, Nextra...etc. A drop-in for your existing design system with no conflict.
|
||||
|
||||
```tsx /tw-/
|
||||
<AlertDialog className="tw-grid tw-gap-4 tw-border tw-bg-background tw-shadow-lg" />
|
||||
```
|
||||
|
||||
It works with `cn`, `cva` and CSS variables.
|
||||
|
||||
The cli can now also detect `tailwind.config.ts` and add the TypeScript version of the config for you.
|
||||
|
||||
That's it. Happy Holidays.
|
||||
99
apps/v4/content/docs/changelog/2024-03-blocks.mdx
Normal file
99
apps/v4/content/docs/changelog/2024-03-blocks.mdx
Normal file
@@ -0,0 +1,99 @@
|
||||
---
|
||||
title: March 2024 - Introducing Blocks
|
||||
description: Ready-made components for dashboards and authentication pages.
|
||||
date: 2024-03-22
|
||||
---
|
||||
|
||||
One of the most requested features since launch has been layouts: admin dashboards with sidebar, marketing page sections, cards and more.
|
||||
|
||||
**Today, we're launching [**Blocks**](/blocks)**.
|
||||
|
||||
<a href="/blocks">
|
||||
<Image
|
||||
src="/images/dashboard-1.jpg"
|
||||
width="716"
|
||||
height="430"
|
||||
alt="Admin dashboard"
|
||||
className="mt-6 w-full overflow-hidden rounded-lg border dark:hidden"
|
||||
/>
|
||||
<Image
|
||||
src="/images/dashboard-1-dark.jpg"
|
||||
width="716"
|
||||
height="430"
|
||||
alt="Admin dashboard"
|
||||
className="mt-6 hidden w-full overflow-hidden rounded-lg border shadow-sm dark:block"
|
||||
/>
|
||||
<span className="sr-only">View the blocks library</span>
|
||||
</a>
|
||||
|
||||
Blocks are ready-made components that you can use to build your apps. They are fully responsive, accessible, and composable, meaning they are built using the same principles as the rest of the components in shadcn/ui.
|
||||
|
||||
We're starting with dashboard layouts and authentication pages, with plans to add more blocks in the coming weeks.
|
||||
|
||||
### Open Source
|
||||
|
||||
Blocks are open source. You can find the source on GitHub. Use them in your projects, customize them and contribute back.
|
||||
|
||||
<a href="/blocks">
|
||||
<Image
|
||||
src="/images/dashboard-2.jpg"
|
||||
width="716"
|
||||
height="420"
|
||||
alt="AI Playground"
|
||||
className="mt-6 w-full overflow-hidden rounded-lg border dark:hidden"
|
||||
/>
|
||||
<Image
|
||||
src="/images/dashboard-2-dark.jpg"
|
||||
width="716"
|
||||
height="420"
|
||||
alt="AI Playground"
|
||||
className="mt-6 hidden w-full overflow-hidden rounded-lg border shadow-sm dark:block"
|
||||
/>
|
||||
<span className="sr-only">View the blocks library</span>
|
||||
</a>
|
||||
|
||||
### Request a Block
|
||||
|
||||
We're also introducing a "Request a Block" feature. If there's a specific block you'd like to see, simply create a request on GitHub and the community can upvote and build it.
|
||||
|
||||
<a href="/blocks">
|
||||
<Image
|
||||
src="/images/dashboard-3.jpg"
|
||||
width="716"
|
||||
height="420"
|
||||
alt="Settings Page"
|
||||
className="mt-6 w-full overflow-hidden rounded-lg border dark:hidden"
|
||||
/>
|
||||
<Image
|
||||
src="/images/dashboard-3-dark.jpg"
|
||||
width="716"
|
||||
height="420"
|
||||
alt="Settings Page"
|
||||
className="mt-6 hidden w-full overflow-hidden rounded-lg border shadow-sm dark:block"
|
||||
/>
|
||||
<span className="sr-only">View the blocks library</span>
|
||||
</a>
|
||||
|
||||
### v0
|
||||
|
||||
If you have a [v0](https://v0.dev) account, you can use the **Edit in v0** feature to open the code on v0 for prompting and further generation.
|
||||
|
||||
<div className="bg-background mt-6 flex aspect-video w-full items-center justify-center overflow-hidden rounded-lg border shadow-sm">
|
||||
<svg
|
||||
viewBox="0 0 40 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="text-foreground h-40 w-40"
|
||||
>
|
||||
<path
|
||||
d="M23.3919 0H32.9188C36.7819 0 39.9136 3.13165 39.9136 6.99475V16.0805H36.0006V6.99475C36.0006 6.90167 35.9969 6.80925 35.9898 6.71766L26.4628 16.079C26.4949 16.08 26.5272 16.0805 26.5595 16.0805H36.0006V19.7762H26.5595C22.6964 19.7762 19.4788 16.6139 19.4788 12.7508V3.68923H23.3919V12.7508C23.3919 12.9253 23.4054 13.0977 23.4316 13.2668L33.1682 3.6995C33.0861 3.6927 33.003 3.68923 32.9188 3.68923H23.3919V0Z"
|
||||
fill="currentColor"
|
||||
></path>
|
||||
<path
|
||||
d="M13.7688 19.0956L0 3.68759H5.53933L13.6231 12.7337V3.68759H17.7535V17.5746C17.7535 19.6705 15.1654 20.6584 13.7688 19.0956Z"
|
||||
fill="currentColor"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
That's it. _Looking forward to seeing what you build with Blocks_.
|
||||
25
apps/v4/content/docs/changelog/2024-03-breadcrumb-otp.mdx
Normal file
25
apps/v4/content/docs/changelog/2024-03-breadcrumb-otp.mdx
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: March 2024 - Breadcrumb and Input OTP
|
||||
description: New Breadcrumb and Input OTP components.
|
||||
date: 2024-03-08
|
||||
---
|
||||
|
||||
We've added a new Breadcrumb component and an Input OTP component.
|
||||
|
||||
### Breadcrumb
|
||||
|
||||
An accessible and flexible breadcrumb component. It has support for collapsed items, custom separators, bring-your-own routing `<Link />` and composable with other shadcn/ui components.
|
||||
|
||||
<ComponentPreview name="breadcrumb-demo" />
|
||||
|
||||
[See more examples](/docs/components/breadcrumb)
|
||||
|
||||
### Input OTP
|
||||
|
||||
A fully featured input OTP component. It has support for numeric and alphanumeric codes, custom length, copy-paste and accessible. Input OTP is built on top of [input-otp](https://github.com/guilhermerodz/input-otp) by [@guilherme_rodz](https://twitter.com/guilherme_rodz).
|
||||
|
||||
<ComponentPreview name="input-otp-demo" />
|
||||
|
||||
[Read the docs](/docs/components/input-otp)
|
||||
|
||||
If you have a [v0](https://v0.dev), the new components are available for generation.
|
||||
31
apps/v4/content/docs/changelog/2024-04-lift-mode.mdx
Normal file
31
apps/v4/content/docs/changelog/2024-04-lift-mode.mdx
Normal file
@@ -0,0 +1,31 @@
|
||||
---
|
||||
title: April 2024 - Lift Mode
|
||||
description: A new mode for Blocks to lift smaller components for copy and paste.
|
||||
date: 2024-04-05
|
||||
---
|
||||
|
||||
We're introducing a new mode for [Blocks](/blocks) called **Lift Mode**.
|
||||
|
||||
Enable Lift Mode to automatically "lift" smaller components from a block template for copy and paste.
|
||||
|
||||
<a href="/blocks">
|
||||
<Image
|
||||
src="/images/lift-mode-light.png"
|
||||
width="1432"
|
||||
height="1050"
|
||||
alt="Lift Mode"
|
||||
className="mt-6 w-full overflow-hidden rounded-lg border dark:hidden"
|
||||
/>
|
||||
<Image
|
||||
src="/images/lift-mode-dark.png"
|
||||
width="1432"
|
||||
height="1069"
|
||||
alt="Lift Mode"
|
||||
className="mt-6 hidden w-full overflow-hidden rounded-lg border shadow-sm dark:block"
|
||||
/>
|
||||
<span className="sr-only">View the blocks library</span>
|
||||
</a>
|
||||
|
||||
With Lift Mode, you'll be able to copy the smaller components that make up a block template, like cards, buttons, and forms, and paste them directly into your project.
|
||||
|
||||
Visit the [Blocks](/blocks) page to try it out.
|
||||
45
apps/v4/content/docs/changelog/2024-08-npx-shadcn-init.mdx
Normal file
45
apps/v4/content/docs/changelog/2024-08-npx-shadcn-init.mdx
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
title: August 2024 - npx shadcn init
|
||||
description: Complete CLI rewrite with support for all major React frameworks.
|
||||
date: 2024-08-31
|
||||
---
|
||||
|
||||
The new CLI is now available. It's a complete rewrite with a lot of new features and improvements. You can now install components, themes, hooks, utils and more using `npx shadcn add`.
|
||||
|
||||
This is a major step towards distributing code that you and your LLMs can access and use.
|
||||
|
||||
1. First up, the cli now has support for all major React framework out of the box. Next.js, Remix, Vite and Laravel. And when you init into a new app, we update your existing Tailwind files instead of overriding.
|
||||
2. A component now ship its own dependencies. Take the accordion for example, it can define its Tailwind keyframes. When you add it to your project, we'll update your tailwind.config.ts file accordingly.
|
||||
3. You can also install remote components using url. `npx shadcn add https://acme.com/registry/navbar.json`.
|
||||
4. We have also improve the init command. It does framework detection and can even init a brand new Next.js app in one command. `npx shadcn init`.
|
||||
5. We have created a new schema that you can use to ship your own component registry. And since it has support for urls, you can even use it to distribute private components.
|
||||
6. And a few more updates like better error handling and monorepo support.
|
||||
|
||||
You can try the new cli today.
|
||||
|
||||
```bash
|
||||
npx shadcn init sidebar-01 login-01
|
||||
```
|
||||
|
||||
### Update Your Project
|
||||
|
||||
To update an existing project to use the new CLI, update your `components.json` file to include import aliases for your **components**, **utils**, **ui**, **lib** and **hooks**.
|
||||
|
||||
```json showLineNumbers {7-13} title="components.json"
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema.json",
|
||||
"style": "new-york",
|
||||
"tailwind": {
|
||||
// ...
|
||||
},
|
||||
"aliases": {
|
||||
"components": "@/components",
|
||||
"utils": "@/lib/utils",
|
||||
"ui": "@/components/ui",
|
||||
"lib": "@/lib",
|
||||
"hooks": "@/hooks"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you're using a different import alias prefix eg `~`, replace `@` with your prefix.
|
||||
11
apps/v4/content/docs/changelog/2024-10-react-19.mdx
Normal file
11
apps/v4/content/docs/changelog/2024-10-react-19.mdx
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
title: October 2024 - React 19
|
||||
description: shadcn/ui is now compatible with React 19 and Next.js 15.
|
||||
date: 2024-10-29
|
||||
---
|
||||
|
||||
shadcn/ui is now compatible with React 19 and Next.js 15.
|
||||
|
||||
We published a guide to help you upgrade your project to React 19.
|
||||
|
||||
Read more [here](/docs/react-19).
|
||||
13
apps/v4/content/docs/changelog/2024-10-sidebar.mdx
Normal file
13
apps/v4/content/docs/changelog/2024-10-sidebar.mdx
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
title: October 2024 - Sidebar
|
||||
description: 25 components to help you build all kinds of sidebars.
|
||||
date: 2024-10-18
|
||||
---
|
||||
|
||||
Introducing sidebar.tsx: 25 components to help you build all kinds of sidebars.
|
||||
|
||||
I don't like building sidebars. So I built 30+ of them. All types. Then simplified the core into sidebar.tsx: a strong foundation to build on top of.
|
||||
|
||||
It works with Next.js, Remix, Vite & Laravel.
|
||||
|
||||
See the announcement [here](https://x.com/shadcn/status/1847359896557408461).
|
||||
13
apps/v4/content/docs/changelog/2024-11-icons.mdx
Normal file
13
apps/v4/content/docs/changelog/2024-11-icons.mdx
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
title: November 2024 - Icons
|
||||
description: The new-york style now uses Lucide as the default icon set.
|
||||
date: 2024-11-06
|
||||
---
|
||||
|
||||
An update on icons. The new-york style now uses Lucide as the default icon set.
|
||||
|
||||
- New projects will use Lucide by default
|
||||
- No breaking changes for existing projects
|
||||
- Use the CLI to (optionally) migrate primitives to Lucide
|
||||
|
||||
For more info on why we're doing this, see the [thread](https://x.com/shadcn/status/1853902179041702169).
|
||||
18
apps/v4/content/docs/changelog/2024-12-monorepo.mdx
Normal file
18
apps/v4/content/docs/changelog/2024-12-monorepo.mdx
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
title: December 2024 - Monorepo Support
|
||||
description: New monorepo support in the CLI.
|
||||
date: 2024-12-20
|
||||
---
|
||||
|
||||
Until now, using shadcn/ui in a monorepo was a bit of a pain. You could add
|
||||
components using the CLI, but you had to manage where the components
|
||||
were installed and manually fix import paths.
|
||||
|
||||
With the new monorepo support in the CLI, we've made it a lot easier to use
|
||||
shadcn/ui in a monorepo.
|
||||
|
||||
The CLI now understands the monorepo structure and will install the components,
|
||||
dependencies and registry dependencies to the correct paths and handle imports
|
||||
for you.
|
||||
|
||||
Read more in the [docs](/docs/monorepo).
|
||||
11
apps/v4/content/docs/changelog/2025-01-blocks.mdx
Normal file
11
apps/v4/content/docs/changelog/2025-01-blocks.mdx
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
title: January 2025 - Blocks Community
|
||||
description: Inviting the community to contribute to the blocks library.
|
||||
date: 2025-01-14
|
||||
---
|
||||
|
||||
We are inviting the community to contribute to the blocks library. Share your components and blocks with other developers and help build a library of high-quality, reusable components.
|
||||
|
||||
We'd love to see all types of blocks: applications, marketing, products, and more.
|
||||
|
||||
See the [docs](/docs/blocks) page to get started.
|
||||
13
apps/v4/content/docs/changelog/2025-02-registry-schema.mdx
Normal file
13
apps/v4/content/docs/changelog/2025-02-registry-schema.mdx
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
title: February 2025 - Updated Registry Schema
|
||||
description: Updated registry schema to support more features.
|
||||
date: 2025-02-06
|
||||
---
|
||||
|
||||
We're updating the registry schema to support more features.
|
||||
|
||||
Define code as a flat JSON file and distribute it via the CLI.
|
||||
|
||||
- Custom styles: bring your own design system, components & tokens
|
||||
- Extend, override, mix & match components from third-party registries and LLMs
|
||||
- Install themes, CSS vars, hooks, animations, and Tailwind layers & utilities
|
||||
22
apps/v4/content/docs/changelog/2025-02-tailwind-v4.mdx
Normal file
22
apps/v4/content/docs/changelog/2025-02-tailwind-v4.mdx
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
title: February 2025 - Tailwind v4
|
||||
description: First preview of Tailwind v4 and React 19 support.
|
||||
date: 2025-02-19
|
||||
---
|
||||
|
||||
We shipped the first preview of Tailwind v4 and React 19. Ready for you to try out. You can start using it today.
|
||||
|
||||
What's New:
|
||||
|
||||
- The CLI can now initialize projects with Tailwind v4.
|
||||
- Full support for the new @theme directive and @theme inline option.
|
||||
- All components are updated for Tailwind v4 and React 19.
|
||||
- We've removed the forwardRefs and adjusted the types.
|
||||
- Every primitive now has a data-slot attribute for styling.
|
||||
- We've fixed and cleaned up the style of the components.
|
||||
- We're deprecating the toast component in favor of sonner.
|
||||
- Buttons now use the default cursor.
|
||||
- We're deprecating the default style. New projects will use new-york.
|
||||
- HSL colors are now converted to OKLCH.
|
||||
|
||||
Read more in the [docs](/docs/tailwind-v4).
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: March 2025 - Cross-framework Route Support
|
||||
description: The shadcn CLI can now auto-detect your framework and adapts routes for you.
|
||||
date: 2025-04-09
|
||||
---
|
||||
|
||||
The shadcn CLI can now auto-detect your framework and adapts routes for you.
|
||||
|
||||
Works with all frameworks including Laravel, Vite and React Router.
|
||||
17
apps/v4/content/docs/changelog/2025-04-mcp.mdx
Normal file
17
apps/v4/content/docs/changelog/2025-04-mcp.mdx
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
title: April 2025 - MCP
|
||||
description: Zero-config MCP support for shadcn/ui registry.
|
||||
date: 2025-04-30
|
||||
---
|
||||
|
||||
We're working on zero-config MCP support for shadcn/ui registry. One command `npx shadcn registry:mcp` to make any registry mcp-compatible.
|
||||
|
||||
<Image
|
||||
src="/images/mcp.jpeg"
|
||||
width="1432"
|
||||
height="1050"
|
||||
alt="Lift Mode"
|
||||
className="mt-6 w-full overflow-hidden rounded-lg border"
|
||||
/>
|
||||
|
||||
Learn more in the [thread here](https://x.com/shadcn/status/1917597228513853603).
|
||||
11
apps/v4/content/docs/changelog/2025-04-shadcn-2-5.mdx
Normal file
11
apps/v4/content/docs/changelog/2025-04-shadcn-2-5.mdx
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
title: March 2025 - shadcn 2.5.0
|
||||
description: Resolve anywhere - registries can now place files anywhere in an app.
|
||||
date: 2025-04-26
|
||||
---
|
||||
|
||||
We tagged shadcn 2.5.0 earlier this week. It comes with a pretty cool feature: **resolve anywhere**.
|
||||
|
||||
Registries can now place files anywhere in an app and we'll properly resolve imports. No need to stick to a fixed file structure. It can even add files outside the registry itself.
|
||||
|
||||
On install, we track all files and perform a multi-pass resolution to correctly handle imports and aliases. It's fast.
|
||||
11
apps/v4/content/docs/changelog/2025-05-new-site.mdx
Normal file
11
apps/v4/content/docs/changelog/2025-05-new-site.mdx
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
title: May 2025 - New Site
|
||||
description: Upgraded ui.shadcn.com to Next.js 15.3 and Tailwind v4.
|
||||
date: 2025-05-30
|
||||
---
|
||||
|
||||
We've upgraded [ui.shadcn.com](https://ui.shadcn.com) to Next.js 15.3 and Tailwind v4. The site now uses the upgraded `new-york` components.
|
||||
|
||||
We've also made some minor design updates to make the site faster and easier to navigate.
|
||||
|
||||
This upgrade unlocks a lot of new features that we're working on. More to come.
|
||||
15
apps/v4/content/docs/changelog/2025-06-calendar.mdx
Normal file
15
apps/v4/content/docs/changelog/2025-06-calendar.mdx
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
title: June 2025 - Calendar Component
|
||||
description: Upgraded Calendar component with React DayPicker and 30+ calendar blocks.
|
||||
date: 2025-06-06
|
||||
---
|
||||
|
||||
We've upgraded the `Calendar` component to the latest version of [React DayPicker](https://daypicker.dev).
|
||||
|
||||
This is a major upgrade and includes a lot of new features and improvements. We've also built a collection of 30+ calendar blocks that you can use to build your own calendar components.
|
||||
|
||||
See all calendar blocks in the [Blocks Library](/blocks/calendar) page.
|
||||
|
||||
<Image src="/images/calendar-2.png" alt="Calendar" width={676} height={895} />
|
||||
|
||||
To upgrade your project to the latest version of the `Calendar` component, see the [upgrade guide](/docs/components/calendar#upgrade-guide).
|
||||
22
apps/v4/content/docs/changelog/2025-06-radix-ui.mdx
Normal file
22
apps/v4/content/docs/changelog/2025-06-radix-ui.mdx
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
title: June 2025 - radix-ui Migration
|
||||
description: A new command to migrate to the new radix-ui package.
|
||||
date: 2025-06-11
|
||||
---
|
||||
|
||||
We've added a new command to migrate to the new `radix-ui` package. This command will replace all `@radix-ui/react-*` imports with `radix-ui`.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest migrate radix
|
||||
```
|
||||
|
||||
It will automatically update all imports in your `ui` components and install `radix-ui` as a dependency.
|
||||
|
||||
```diff showLineNumbers title="components/ui/alert-dialog.tsx"
|
||||
- import * as AlertDialogPrimitive from "@radix-ui/react-dialog"
|
||||
+ import { AlertDialog as AlertDialogPrimitive } from "radix-ui"
|
||||
```
|
||||
|
||||
Make sure to test your components and project after running the command.
|
||||
|
||||
**Note:** To update imports for newly added components, run the migration command again.
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
title: July 2025 - Local File Support
|
||||
description: Initialize projects and add components from local JSON files.
|
||||
date: 2025-07-07
|
||||
---
|
||||
|
||||
The shadcn CLI now supports local files. Initialize projects and add components, themes, hooks, utils and more from local JSON files.
|
||||
|
||||
```bash
|
||||
# Initialize a project from a local file
|
||||
npx shadcn init ./template.json
|
||||
|
||||
# Add a component from a local file
|
||||
npx shadcn add ./block.json
|
||||
```
|
||||
|
||||
This feature enables powerful new workflows:
|
||||
|
||||
- **Zero setup** - No remote registries required
|
||||
- **Faster development** - Test registry items locally before publishing
|
||||
- **Enhanced workflow for agents and MCP** - Generate and run registry items locally
|
||||
- **Private components** - Keep proprietary components local and private.
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
title: July 2025 - Universal Registry Items
|
||||
description: Create registry items that can be distributed to any project.
|
||||
date: 2025-07-11
|
||||
---
|
||||
|
||||
We've added support for universal registry items. This allows you to create registry items that can be distributed to any project i.e. no framework, no components.json, no tailwind, no react required.
|
||||
|
||||
This new registry item type unlocks a lot of new workflows. You can now distribute code, config, rules, docs, anything to any code project.
|
||||
|
||||
See the [docs](/docs/registry/examples) for more details and examples.
|
||||
206
apps/v4/content/docs/changelog/2025-08-cli-3-mcp.mdx
Normal file
206
apps/v4/content/docs/changelog/2025-08-cli-3-mcp.mdx
Normal file
@@ -0,0 +1,206 @@
|
||||
---
|
||||
title: August 2025 - shadcn CLI 3.0 and MCP Server
|
||||
description: Namespaced registries, advanced authentication, new commands and a completely rewritten registry engine.
|
||||
date: 2025-08-27
|
||||
---
|
||||
|
||||
We just shipped shadcn CLI 3.0 with support for namespaced registries, advanced authentication, new commands and a completely rewritten registry engine.
|
||||
|
||||
### What's New
|
||||
|
||||
- [Namespaced Registries](#namespaced-registries) - Install components using `@registry/name` format.
|
||||
- [Private Registries](#private-registries) - Secure your registry with advanced authentication.
|
||||
- [Search & Discovery](#search--discovery) - New commands to find and view code before installing.
|
||||
- [MCP Server](#mcp-server) - MCP server for all registries.
|
||||
- [Faster Everything](#faster-everything) - Completely rewritten registry resolution.
|
||||
- [Improved Error Handling](#improved-error-handling) - Better error messages for users and LLMs.
|
||||
- [Upgrade Guide](#upgrade-guide) - Migration notes for existing users.
|
||||
|
||||
### Namespaced Registries
|
||||
|
||||
The biggest change in 3.0 is namespaced registries. You can now install components from registries: a community registry, your company's private registry or internal registry, using the `@registry/name` format.
|
||||
|
||||
This makes it easier to distribute code across teams and projects.
|
||||
|
||||
Configure registries in your `components.json`:
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"registries": {
|
||||
"@acme": "https://acme.com/r/{name}.json",
|
||||
"@internal": {
|
||||
"url": "https://registry.company.com/{name}",
|
||||
"headers": {
|
||||
"Authorization": "Bearer ${REGISTRY_TOKEN}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Then use the `@registry/name` format to install components:
|
||||
|
||||
```bash
|
||||
npx shadcn add @acme/button @internal/auth-system
|
||||
```
|
||||
|
||||
It's completely decentralized. There's no central registrar. Create any namespace you want and organize components however makes sense for your team.
|
||||
|
||||
```json title="components.json" showLineNumbers
|
||||
{
|
||||
"registries": {
|
||||
"@design": "https://registry.company.com/create/{name}.json",
|
||||
"@engineering": "https://registry.company.com/eng/{name}.json",
|
||||
"@marketing": "https://registry.company.com/marketing/{name}.json"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Components can even depend on resources from different registries. Everything gets resolved and installed automatically from the right sources.
|
||||
|
||||
```json title="registry-item.json" showLineNumbers
|
||||
{
|
||||
"name": "dashboard",
|
||||
"type": "registry:block",
|
||||
"registryDependencies": [
|
||||
"@shadcn/card", // From default registry
|
||||
"@v0/chart", // From v0 registry
|
||||
"@acme/data-table", // From acme registry
|
||||
"@lib/data-fetcher", // Utility library
|
||||
"@ai/analytics-prompt" // AI prompt resource
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Private Registries
|
||||
|
||||
Need to keep your components private? We've got you covered. Configure authentication with tokens, API keys, or custom headers:
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"registries": {
|
||||
"@private": {
|
||||
"url": "https://registry.company.com/{name}.json",
|
||||
"headers": {
|
||||
"Authorization": "Bearer ${REGISTRY_TOKEN}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Your private components stay private. Perfect for enterprise teams with proprietary UI libraries.
|
||||
|
||||
We support all major authentication methods: basic auth, bearer token, api key query params and custom headers.
|
||||
|
||||
See the [authentication docs](/docs/registry/authentication) for more details.
|
||||
|
||||
### Search & Discovery
|
||||
|
||||
Three new commands make it easy to find exactly what you need:
|
||||
|
||||
1. View items from the registry before installing
|
||||
|
||||
```bash
|
||||
npx shadcn view @acme/auth-system
|
||||
```
|
||||
|
||||
2. Search items from registries
|
||||
|
||||
```bash
|
||||
npx shadcn search @tweakcn -q "dark"
|
||||
```
|
||||
|
||||
3. List all items from a registry
|
||||
|
||||
```bash
|
||||
npx shadcn list @acme
|
||||
```
|
||||
|
||||
Preview components before installing them. Search across multiple registries. See the code and all dependencies upfront.
|
||||
|
||||
### MCP Server
|
||||
|
||||
<Image
|
||||
src="/images/mcp.jpeg"
|
||||
width="1432"
|
||||
height="1050"
|
||||
alt="Lift Mode"
|
||||
className="mt-6 w-full overflow-hidden rounded-lg border"
|
||||
/>
|
||||
|
||||
Back in April, we [introduced](https://x.com/shadcn/status/1917597228513853603) the first version of the MCP server. Since then, we've taken everything we learned and built a better MCP server.
|
||||
|
||||
Here's what's new:
|
||||
|
||||
- Works with all registries. Zero config
|
||||
- One command to add to your favorite MCP clients
|
||||
- We improved the underlying tools
|
||||
- Better integration with the CLI and registries
|
||||
- Support for multiple registries in the same project
|
||||
|
||||
Add the MCP server to your project:
|
||||
|
||||
```bash
|
||||
npx shadcn@latest mcp init
|
||||
```
|
||||
|
||||
See the [docs](/docs/mcp) for more details.
|
||||
|
||||
### Faster Everything
|
||||
|
||||
We completely rewrote the registry resolution engine from scratch. It's faster, smarter, and handles even the trickiest dependency trees.
|
||||
|
||||
- Up to 3x faster dependency resolution
|
||||
- Smarter file deduplication and merging
|
||||
- Better monorepo support out of the box
|
||||
- Updated `build` command for registry authors
|
||||
|
||||
### Improved Error Handling
|
||||
|
||||
Registry developers can now provide custom error messages to help guide users (and LLMs) when things go wrong. The CLI displays helpful, actionable errors for common issues:
|
||||
|
||||
```txt
|
||||
Unknown registry "@acme". Make sure it is defined in components.json as follows:
|
||||
{
|
||||
"registries": {
|
||||
"@acme": "[URL_TO_REGISTRY]"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Missing environment variables? The CLI tells you exactly what's needed:
|
||||
|
||||
```txt
|
||||
Registry "@private" requires the following environment variables:
|
||||
• REGISTRY_TOKEN
|
||||
|
||||
Set the required environment variables to your .env or .env.local file.
|
||||
```
|
||||
|
||||
Registry authors can provide custom error messages in their responses to help users and AI agents understand and fix issues quickly.
|
||||
|
||||
```txt
|
||||
Error:
|
||||
You are not authorized to access the item at http://example.com/r/component.
|
||||
|
||||
Message:
|
||||
[Unauthorized] Your API key has expired. Renew it at https://example.com/api/renew-key.
|
||||
```
|
||||
|
||||
### Upgrade Guide
|
||||
|
||||
Here's the best part: there are no breaking changes for users. Your existing `components.json` works exactly the same. All your installed components work exactly the same.
|
||||
|
||||
For developers, if you're using the programmatic APIs directly, we've deprecated a few functions in favor of better ones:
|
||||
|
||||
- `fetchRegistry` → `getRegistry`
|
||||
- `resolveRegistryTree` → `resolveRegistryItems`
|
||||
- Schema moved from `shadcn/registry` to `shadcn/schema` package
|
||||
|
||||
```diff
|
||||
- import { registryItemSchema } from "shadcn/registry"
|
||||
+ import { registryItemSchema } from "shadcn/schema"
|
||||
```
|
||||
|
||||
That's it. Seriously. Everything else just works.
|
||||
19
apps/v4/content/docs/changelog/2025-09-registry-index.mdx
Normal file
19
apps/v4/content/docs/changelog/2025-09-registry-index.mdx
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
title: September 2025 - Registry Index
|
||||
description: An index of open source registries that you can install items from.
|
||||
date: 2025-09-02
|
||||
---
|
||||
|
||||
We've created an index of open source registries that you can install items from.
|
||||
|
||||
You can search, view and add items from the registry index without configuring the `.components.json` file.
|
||||
|
||||
They'll be automatically added to your `components.json` file for you.
|
||||
|
||||
```bash
|
||||
npx shadcn add @ai-elements/prompt-input
|
||||
```
|
||||
|
||||
The full list of registries is available at [https://ui.shadcn.com/r/registries.json](https://ui.shadcn.com/r/registries.json).
|
||||
|
||||
To add a registry to the index, submit a PR to the `shadcn/ui` repository. See the [registry index documentation](/docs/registry/registry-index) for more details.
|
||||
399
apps/v4/content/docs/changelog/2025-10-new-components.mdx
Normal file
399
apps/v4/content/docs/changelog/2025-10-new-components.mdx
Normal file
@@ -0,0 +1,399 @@
|
||||
---
|
||||
title: October 2025 - New Components
|
||||
description: Spinner, Kbd, Button Group, Input Group, Field, Item, and Empty components.
|
||||
date: 2025-10-03
|
||||
---
|
||||
|
||||
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.
|
||||
|
||||
**These components work with every component library, Radix, Base UI, React Aria, you name it. Copy and paste to your projects.**
|
||||
|
||||
- [Spinner](#spinner): An indicator to show a loading state.
|
||||
- [Kbd](#kbd): Display a keyboard key or group of keys.
|
||||
- [Button Group](#button-group): A group of buttons for actions and split buttons.
|
||||
- [Input Group](#input-group): Input with icons, buttons, labels and more.
|
||||
- [Field](#field): One component. All your forms.
|
||||
- [Item](#item): Display lists of items, cards, and more.
|
||||
- [Empty](#empty): Use this one for empty states.
|
||||
|
||||
### Spinner
|
||||
|
||||
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:
|
||||
|
||||
```tsx
|
||||
import { Spinner } from "@/components/ui/spinner"
|
||||
```
|
||||
|
||||
```tsx
|
||||
<Spinner />
|
||||
```
|
||||
|
||||
Here's what it looks like:
|
||||
|
||||
<ComponentPreview
|
||||
name="spinner-basic"
|
||||
className="[&_.preview]:h-[250px] [&_pre]:!h-[250px]"
|
||||
/>
|
||||
|
||||
Here's what it looks like in a button:
|
||||
|
||||
<ComponentPreview
|
||||
name="spinner-button"
|
||||
className="[&_.preview]:h-[250px] [&_pre]:!h-[250px]"
|
||||
/>
|
||||
|
||||
You can edit the code and replace it with your own spinner.
|
||||
|
||||
<ComponentPreview
|
||||
name="spinner-custom"
|
||||
className="[&_.preview]:h-[250px] [&_pre]:!h-[250px]"
|
||||
/>
|
||||
|
||||
### Kbd
|
||||
|
||||
Kbd is a component that renders a keyboard key.
|
||||
|
||||
```tsx
|
||||
import { Kbd, KbdGroup } from "@/components/ui/kbd"
|
||||
```
|
||||
|
||||
```tsx
|
||||
<Kbd>Ctrl</Kbd>
|
||||
```
|
||||
|
||||
Use `KbdGroup` to group keyboard keys together.
|
||||
|
||||
```tsx showLineNumbers
|
||||
<KbdGroup>
|
||||
<Kbd>Ctrl</Kbd>
|
||||
<Kbd>B</Kbd>
|
||||
</KbdGroup>
|
||||
```
|
||||
|
||||
<ComponentPreview
|
||||
name="kbd-demo"
|
||||
className="[&_.preview]:h-[250px] [&_pre]:!h-[250px]"
|
||||
/>
|
||||
|
||||
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.
|
||||
|
||||
<ComponentPreview
|
||||
name="button-group-demo"
|
||||
className="[&_.preview]:h-[250px] [&_pre]:!h-[250px]"
|
||||
/>
|
||||
|
||||
Here's the code:
|
||||
|
||||
```tsx
|
||||
import { ButtonGroup } from "@/components/ui/button-group"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<ButtonGroup>
|
||||
<Button>Button 1</Button>
|
||||
<Button>Button 2</Button>
|
||||
</ButtonGroup>
|
||||
```
|
||||
|
||||
You can nest button groups to create more complex layouts with spacing.
|
||||
|
||||
```tsx showLineNumbers
|
||||
<ButtonGroup>
|
||||
<ButtonGroup>
|
||||
<Button>Button 1</Button>
|
||||
<Button>Button 2</Button>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup>
|
||||
<Button>Button 3</Button>
|
||||
<Button>Button 4</Button>
|
||||
</ButtonGroup>
|
||||
</ButtonGroup>
|
||||
```
|
||||
|
||||
Use `ButtonGroupSeparator` to create split buttons. Classic dropdown pattern.
|
||||
|
||||
<ComponentPreview
|
||||
name="button-group-dropdown"
|
||||
className="[&_.preview]:h-[250px] [&_pre]:!h-[250px]"
|
||||
/>
|
||||
|
||||
You can also use it to add prefix or suffix buttons and text to inputs.
|
||||
|
||||
<ComponentPreview
|
||||
name="button-group-select"
|
||||
className="[&_.preview]:h-[250px] [&_pre]:!h-[250px]"
|
||||
/>
|
||||
|
||||
```tsx showLineNumbers
|
||||
<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.
|
||||
|
||||
```tsx
|
||||
import {
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupInput,
|
||||
} from "@/components/ui/input-group"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<InputGroup>
|
||||
<InputGroupInput placeholder="Search..." />
|
||||
<InputGroupAddon>
|
||||
<SearchIcon />
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
```
|
||||
|
||||
Here's a preview with icons:
|
||||
|
||||
<ComponentPreview
|
||||
name="input-group-icon"
|
||||
className="[&_.preview]:h-[300px] [&_pre]:!h-[300px]"
|
||||
/>
|
||||
|
||||
You can also add buttons to the input group.
|
||||
|
||||
<ComponentPreview
|
||||
name="input-group-button"
|
||||
className="[&_.preview]:h-[300px] [&_pre]:!h-[300px]"
|
||||
/>
|
||||
|
||||
Or text, labels, tooltips,...
|
||||
|
||||
<ComponentPreview
|
||||
name="input-group-text"
|
||||
className="[&_.preview]:h-[350px] [&_pre]:!h-[350px]"
|
||||
/>
|
||||
|
||||
It also works with textareas so you can build really complex components with lots of knobs and dials or yet another prompt form.
|
||||
|
||||
<ComponentPreview
|
||||
name="input-group-textarea"
|
||||
className="[&_.preview]:h-[450px] [&_pre]:!h-[450px]"
|
||||
/>
|
||||
|
||||
Oh here are some cool ones with spinners:
|
||||
|
||||
<ComponentPreview
|
||||
name="input-group-spinner"
|
||||
className="[&_.preview]:h-[350px] [&_pre]:!h-[350px]"
|
||||
/>
|
||||
|
||||
### Field
|
||||
|
||||
Introducing **Field**, a component for building really complex forms. The abstraction here is beautiful.
|
||||
|
||||
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.
|
||||
|
||||
```tsx
|
||||
import {
|
||||
Field,
|
||||
FieldDescription,
|
||||
FieldError,
|
||||
FieldLabel,
|
||||
} from "@/components/ui/field"
|
||||
```
|
||||
|
||||
Here's a basic field with an input:
|
||||
|
||||
```tsx showLineNumbers
|
||||
<Field>
|
||||
<FieldLabel htmlFor="username">Username</FieldLabel>
|
||||
<Input id="username" placeholder="Max Leiter" />
|
||||
<FieldDescription>
|
||||
Choose a unique username for your account.
|
||||
</FieldDescription>
|
||||
</Field>
|
||||
```
|
||||
|
||||
<ComponentPreview
|
||||
name="field-input"
|
||||
className="[&_.preview]:h-[350px] [&_pre]:!h-[350px]"
|
||||
/>
|
||||
|
||||
It works with all form controls. Inputs, textareas, selects, checkboxes, radios, switches, sliders, you name it. Here's a full example:
|
||||
|
||||
<ComponentPreview
|
||||
name="field-demo"
|
||||
className="[&_.preview]:h-[850px] [&_pre]:!h-[850px]"
|
||||
/>
|
||||
|
||||
Here are some checkbox fields:
|
||||
|
||||
<ComponentPreview
|
||||
name="field-checkbox"
|
||||
className="[&_.preview]:h-[500px] [&_pre]:!h-[500px]"
|
||||
/>
|
||||
|
||||
You can group fields together using `FieldGroup` and `FieldSet`. Perfect for
|
||||
multi-section forms.
|
||||
|
||||
```tsx showLineNumbers
|
||||
<FieldSet>
|
||||
<FieldLegend />
|
||||
<FieldGroup>
|
||||
<Field />
|
||||
<Field />
|
||||
</FieldGroup>
|
||||
</FieldSet>
|
||||
```
|
||||
|
||||
<ComponentPreview
|
||||
name="field-fieldset"
|
||||
className="[&_.preview]:h-[500px] [&_pre]:!h-[500px]"
|
||||
/>
|
||||
|
||||
Making it responsive is easy. Use `orientation="responsive"` and it switches
|
||||
between vertical and horizontal layouts based on container width. Done.
|
||||
|
||||
<ComponentPreview
|
||||
name="field-responsive"
|
||||
className="[&_.preview]:h-[600px] [&_pre]:!h-[600px]"
|
||||
/>
|
||||
|
||||
Wait here's more. Wrap your fields in `FieldLabel` to create a selectable field group. Really easy. And it looks great.
|
||||
|
||||
<ComponentPreview
|
||||
name="field-choice-card"
|
||||
className="[&_.preview]:h-[600px] [&_pre]:!h-[600px]"
|
||||
/>
|
||||
|
||||
### 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.
|
||||
|
||||
```tsx
|
||||
import {
|
||||
Item,
|
||||
ItemContent,
|
||||
ItemDescription,
|
||||
ItemMedia,
|
||||
ItemTitle,
|
||||
} from "@/components/ui/item"
|
||||
```
|
||||
|
||||
Here's a basic item:
|
||||
|
||||
```tsx showLineNumbers
|
||||
<Item>
|
||||
<ItemMedia variant="icon">
|
||||
<HomeIcon />
|
||||
</ItemMedia>
|
||||
<ItemContent>
|
||||
<ItemTitle>Dashboard</ItemTitle>
|
||||
<ItemDescription>Overview of your account and activity.</ItemDescription>
|
||||
</ItemContent>
|
||||
</Item>
|
||||
```
|
||||
|
||||
<ComponentPreview
|
||||
name="item-demo"
|
||||
className="[&_.preview]:h-[300px] [&_.preview]:p-4 [&_pre]:!h-[300px]"
|
||||
/>
|
||||
|
||||
You can add icons, avatars, or images to the item.
|
||||
|
||||
<ComponentPreview
|
||||
name="item-icon"
|
||||
className="[&_.preview]:h-[300px] [&_.preview]:p-4 [&_pre]:!h-[300px]"
|
||||
/>
|
||||
|
||||
<ComponentPreview
|
||||
name="item-avatar"
|
||||
className="[&_.preview]:h-[300px] [&_.preview]:p-4 [&_pre]:!h-[300px]"
|
||||
/>
|
||||
|
||||
And here's what a list of items looks like with `ItemGroup`:
|
||||
|
||||
<ComponentPreview
|
||||
name="item-group"
|
||||
className="[&_.preview]:h-[500px] [&_.preview]:p-4 [&_pre]:!h-[500px]"
|
||||
/>
|
||||
|
||||
Need it as a link? Use the `asChild` prop:
|
||||
|
||||
```tsx showLineNumbers
|
||||
<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>
|
||||
```
|
||||
|
||||
<ComponentPreview
|
||||
name="item-link"
|
||||
className="[&_.preview]:h-[400px] [&_.preview]:p-4 [&_pre]:!h-[400px]"
|
||||
/>
|
||||
|
||||
### Empty
|
||||
|
||||
Okay last one: **Empty**. Use this to display empty states in your app.
|
||||
|
||||
```tsx
|
||||
import {
|
||||
Empty,
|
||||
EmptyContent,
|
||||
EmptyDescription,
|
||||
EmptyMedia,
|
||||
EmptyTitle,
|
||||
} from "@/components/ui/empty"
|
||||
```
|
||||
|
||||
Here's how you use it:
|
||||
|
||||
```tsx showLineNumbers
|
||||
<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>
|
||||
```
|
||||
|
||||
<ComponentPreview
|
||||
name="empty-demo"
|
||||
className="[&_.preview]:h-[400px] [&_.preview]:p-4 [&_pre]:!h-[400px]"
|
||||
/>
|
||||
|
||||
You can use it with avatars:
|
||||
|
||||
<ComponentPreview
|
||||
name="empty-avatar"
|
||||
className="[&_.preview]:h-[400px] [&_pre]:!h-[400px]"
|
||||
/>
|
||||
|
||||
Or with input groups for things like search results or email subscriptions:
|
||||
|
||||
<ComponentPreview
|
||||
name="empty-input-group"
|
||||
className="[&_.preview]:h-[450px] [&_pre]:!h-[450px]"
|
||||
/>
|
||||
|
||||
That's it. Seven new components. Works with all your libraries. Ready for your projects.
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
title: October 2025 - Registry Directory
|
||||
description: A list of code registries you can browse and pull code and components from.
|
||||
date: 2025-10-28
|
||||
---
|
||||
|
||||
We just published the Registry Directory: a list of code registries you can browse and pull code and components from.
|
||||
|
||||
https://ui.shadcn.com/docs/directory
|
||||
|
||||
Built into the CLI. No config required.
|
||||
46
apps/v4/content/docs/changelog/2025-12-shadcn-create.mdx
Normal file
46
apps/v4/content/docs/changelog/2025-12-shadcn-create.mdx
Normal file
@@ -0,0 +1,46 @@
|
||||
---
|
||||
title: December 2025 - npx shadcn create
|
||||
description: Customize everything. Pick your component library, icons, base color, theme, fonts and create your own version of shadcn/ui.
|
||||
date: 2025-12-12
|
||||
---
|
||||
|
||||
From the very first commit, the goal of shadcn/ui was to make it customizable.
|
||||
|
||||
The idea is to give you solid defaults, spacing, color tokens, animations, accessibility, and then let you take it from there. Tweak the code. Add new components. Change the colors. Build your own version.
|
||||
|
||||
But somewhere along the way, all apps started looking the same. I guess the defaults were a little _too_ good. My bad.
|
||||
|
||||
Today, we're changing that: **npx shadcn create**.
|
||||
|
||||
Customize Everything. Pick your component library, icons, base color, theme, fonts and create your own version of shadcn/ui.
|
||||
|
||||
We're starting with **5 new visual styles,** designed to help your UI actually feel like _your_ UI.
|
||||
|
||||
- **Vega** – The classic shadcn/ui look.
|
||||
- **Nova** – Reduced padding and margins for compact layouts.
|
||||
- **Maia** – Soft and rounded, with generous spacing.
|
||||
- **Lyra** – Boxy and sharp. Pairs well with mono fonts.
|
||||
- **Mira** – Compact. Made for dense interfaces.
|
||||
|
||||
**This goes beyond theming**.
|
||||
|
||||
Your config doesn't just change colors, it rewrites the component code to match your setup. Fonts, spacing, structure, even the libraries you use, everything adapts to your preferences.
|
||||
|
||||
The new CLI takes care of it all.
|
||||
|
||||
Start with a component library. Choose between Radix or Base UI.
|
||||
|
||||
We rebuilt every component for Base UI, keeping the same abstraction.
|
||||
They are fully compatible with your existing components, even those pulled from remote registries.
|
||||
|
||||
When you pull down components, we auto-detect your library and apply the right transformations.
|
||||
|
||||
**It's time to build something that doesn't look like everything else.**
|
||||
|
||||
Now available for Next.js, Vite, TanStack Start and v0.
|
||||
|
||||
<Button asChild>
|
||||
<Link href="/create" className="mt-6 no-underline!">
|
||||
Get Started
|
||||
</Link>
|
||||
</Button>
|
||||
45
apps/v4/content/docs/changelog/2026-01-base-ui.mdx
Normal file
45
apps/v4/content/docs/changelog/2026-01-base-ui.mdx
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
title: January 2026 - Base UI Documentation
|
||||
description: Full documentation for Base UI components.
|
||||
date: 2026-01-20
|
||||
---
|
||||
|
||||
We've shipped full documentation for Base UI components.
|
||||
|
||||
<div className="bg-muted/50 mt-6 flex w-full items-center justify-center rounded-lg border py-32">
|
||||
<svg width="17" height="24" viewBox="0 0 17 24" className="size-12">
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M9.5001 7.01537C9.2245 6.99837 9 7.22385 9 7.49999V23C13.4183 23 17 19.4183 17 15C17 10.7497 13.6854 7.27351 9.5001 7.01537Z"
|
||||
/>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M8 9.8V12V23C3.58172 23 0 19.0601 0 14.2V12V1C4.41828 1 8 4.93989 8 9.8Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
When we launched `npx shadcn create` in December, we introduced the ability to choose between Radix and Base UI as your component library. Today, we're following up with complete documentation for all Base UI components.
|
||||
|
||||
### What's New
|
||||
|
||||
- **Full Base UI docs** - Every component now has dedicated documentation for Base UI, covering usage, props, and examples.
|
||||
- **Rebuilt examples** - All component examples have been rebuilt for both Radix and Base UI. Switch between them to see the implementation differences.
|
||||
- **Side-by-side comparison** - The docs make it easy to compare how components work across both libraries.
|
||||
|
||||
### Same Abstraction, Different Primitives
|
||||
|
||||
The goal remains the same: give you a consistent API regardless of which primitive library you choose. The components look and behave the same way. Only the underlying implementation changes.
|
||||
|
||||
```tsx
|
||||
// Works the same whether you're using Radix or Base UI.
|
||||
import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog"
|
||||
```
|
||||
|
||||
If you're starting a new project, run `npx shadcn create` and pick your preferred library. The CLI handles the rest.
|
||||
|
||||
<Button asChild size="sm">
|
||||
<Link href="/create" className="mt-6 no-underline!">
|
||||
Try shadcn/create
|
||||
</Link>
|
||||
</Button>
|
||||
6
apps/v4/content/docs/changelog/index.mdx
Normal file
6
apps/v4/content/docs/changelog/index.mdx
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
title: Changelog
|
||||
description: Latest updates and announcements.
|
||||
---
|
||||
|
||||
Latest updates and announcements for shadcn/ui.
|
||||
4
apps/v4/content/docs/changelog/meta.json
Normal file
4
apps/v4/content/docs/changelog/meta.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"title": "Changelog",
|
||||
"pages": []
|
||||
}
|
||||
50
apps/v4/lib/changelog.ts
Normal file
50
apps/v4/lib/changelog.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import fs from "fs"
|
||||
import path from "path"
|
||||
import fm from "front-matter"
|
||||
|
||||
import { source } from "@/lib/source"
|
||||
|
||||
export type ChangelogPageData = {
|
||||
title: string
|
||||
description?: string
|
||||
}
|
||||
|
||||
export type ChangelogPage = ReturnType<typeof source.getPages>[number] & {
|
||||
date: Date | null
|
||||
}
|
||||
|
||||
// Reads the date from the frontmatter of a changelog file.
|
||||
export function getDateFromFile(slugs: string[]) {
|
||||
const filePath = path.join(
|
||||
process.cwd(),
|
||||
"content/docs",
|
||||
...slugs.slice(0, -1),
|
||||
`${slugs[slugs.length - 1]}.mdx`
|
||||
)
|
||||
try {
|
||||
const content = fs.readFileSync(filePath, "utf-8")
|
||||
const { attributes } = fm<{ date?: string | Date }>(content)
|
||||
if (attributes.date) {
|
||||
return new Date(attributes.date)
|
||||
}
|
||||
} catch {
|
||||
// File not found or parse error.
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
// Gets all changelog pages sorted by date descending.
|
||||
export function getChangelogPages() {
|
||||
return source
|
||||
.getPages()
|
||||
.filter((page) => page.slugs[0] === "changelog" && page.slugs.length > 1)
|
||||
.map((page) => ({
|
||||
...page,
|
||||
date: getDateFromFile(page.slugs),
|
||||
}))
|
||||
.sort((a, b) => {
|
||||
const dateA = a.date?.getTime() ?? 0
|
||||
const dateB = b.date?.getTime() ?? 0
|
||||
return dateB - dateA
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user