snapshot of https://github.com/shadcn-ui/ui.git (main, 2026-09-15; blobs > 131072B omitted)
This commit is contained in:
238
apps/v4/content/docs/(root)/_blocks.mdx
Normal file
238
apps/v4/content/docs/(root)/_blocks.mdx
Normal file
@@ -0,0 +1,238 @@
|
||||
---
|
||||
title: Blocks
|
||||
description: Contribute components to the blocks library.
|
||||
---
|
||||
|
||||
We are inviting the community to contribute to the [blocks library](/blocks). 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.
|
||||
|
||||
## Setup your workspace
|
||||
|
||||
<Steps>
|
||||
|
||||
### Fork the repository
|
||||
|
||||
```bash
|
||||
git clone https://github.com/shadcn-ui/ui.git
|
||||
```
|
||||
|
||||
### Create a new branch
|
||||
|
||||
```bash
|
||||
git checkout -b username/my-new-block
|
||||
```
|
||||
|
||||
### Install dependencies
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
```
|
||||
|
||||
### Start the dev server
|
||||
|
||||
```bash
|
||||
pnpm www:dev
|
||||
```
|
||||
|
||||
</Steps>
|
||||
|
||||
## Add a block
|
||||
|
||||
A block can be a single component (eg. a variation of a ui component) or a complex component (eg. a dashboard) with multiple components, hooks, and utils.
|
||||
|
||||
<Steps>
|
||||
|
||||
### Create a new block
|
||||
|
||||
Create a new folder in the `apps/www/registry/new-york/blocks` directory. Make sure the folder is named in kebab-case and under `new-york`.
|
||||
|
||||
```txt
|
||||
apps
|
||||
└── www
|
||||
└── registry
|
||||
└── new-york
|
||||
└── blocks
|
||||
└── dashboard-01
|
||||
```
|
||||
|
||||
<Callout className="mt-6">
|
||||
|
||||
**Note:** The build script will take care of building the block for the `default` style.
|
||||
|
||||
</Callout>
|
||||
|
||||
### Add your block files
|
||||
|
||||
Add your files to the block folder. Here is an example of a block with a page, components, hooks, and utils.
|
||||
|
||||
```txt
|
||||
dashboard-01
|
||||
└── page.tsx
|
||||
└── components
|
||||
└── hello-world.tsx
|
||||
└── example-card.tsx
|
||||
└── hooks
|
||||
└── use-hello-world.ts
|
||||
└── lib
|
||||
└── format-date.ts
|
||||
```
|
||||
|
||||
<Callout className="mt-6">
|
||||
|
||||
**Note:** You can start with one file and add more files later.
|
||||
|
||||
</Callout>
|
||||
|
||||
</Steps>
|
||||
|
||||
## Add your block to the registry
|
||||
|
||||
<Steps>
|
||||
|
||||
### Add your block definition to `registry-blocks.tsx`
|
||||
|
||||
To add your block to the registry, you need to add your block definition to `registry-blocks.ts`.
|
||||
|
||||
This follows the registry schema at [https://ui.shadcn.com/schema/registry-item.json](https://ui.shadcn.com/schema/registry-item.json).
|
||||
|
||||
```tsx title="apps/www/registry/registry-blocks.tsx" showLineNumbers
|
||||
export const blocks = [
|
||||
// ...
|
||||
{
|
||||
name: "dashboard-01",
|
||||
author: "shadcn (https://ui.shadcn.com)",
|
||||
title: "Dashboard",
|
||||
description: "A simple dashboard with a hello world component.",
|
||||
type: "registry:block",
|
||||
registryDependencies: ["input", "button", "card"],
|
||||
dependencies: ["zod"],
|
||||
files: [
|
||||
{
|
||||
path: "blocks/dashboard-01/page.tsx",
|
||||
type: "registry:page",
|
||||
target: "app/dashboard/page.tsx",
|
||||
},
|
||||
{
|
||||
path: "blocks/dashboard-01/components/hello-world.tsx",
|
||||
type: "registry:component",
|
||||
},
|
||||
{
|
||||
path: "blocks/dashboard-01/components/example-card.tsx",
|
||||
type: "registry:component",
|
||||
},
|
||||
{
|
||||
path: "blocks/dashboard-01/hooks/use-hello-world.ts",
|
||||
type: "registry:hook",
|
||||
},
|
||||
{
|
||||
path: "blocks/dashboard-01/lib/format-date.ts",
|
||||
type: "registry:lib",
|
||||
},
|
||||
],
|
||||
categories: ["dashboard"],
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
Make sure you add a name, description, type, registryDependencies, dependencies, files, and categories. We'll go over each of these in more detail in the schema docs (coming soon).
|
||||
|
||||
### Run the build script
|
||||
|
||||
```bash
|
||||
pnpm registry:build
|
||||
```
|
||||
|
||||
<Callout className="mt-6">
|
||||
|
||||
**Note:** you do not need to run this script for every change. You only need to run it when you update the block definition.
|
||||
|
||||
</Callout>
|
||||
|
||||
### View your block
|
||||
|
||||
Once the build script is finished, you can view your block at `http://localhost:3333/blocks/[CATEGORY]` or a full screen preview at `http://localhost:3333/view/styles/new-york/dashboard-01`.
|
||||
|
||||
<Image
|
||||
src="/images/block-preview-light.png"
|
||||
width="1432"
|
||||
height="960"
|
||||
alt="Block preview"
|
||||
className="mt-6 w-full overflow-hidden rounded-2xl border dark:hidden"
|
||||
/>
|
||||
<Image
|
||||
src="/images/block-preview-dark.png"
|
||||
width="1432"
|
||||
height="960"
|
||||
alt="Block preview"
|
||||
className="mt-6 hidden w-full overflow-hidden rounded-2xl border shadow-sm dark:block"
|
||||
/>
|
||||
|
||||
### Build your block
|
||||
|
||||
You can now build your block by editing the files in the block folder and viewing the changes in the browser.
|
||||
|
||||
If you add more files, make sure to add them to the `files` array in the block definition.
|
||||
|
||||
</Steps>
|
||||
|
||||
## Publish your block
|
||||
|
||||
Once you're ready to publish your block, you can submit a pull request to the main repository.
|
||||
|
||||
<Steps>
|
||||
|
||||
### Run the build script
|
||||
|
||||
```bash
|
||||
pnpm registry:build
|
||||
```
|
||||
|
||||
### Capture a screenshot
|
||||
|
||||
```bash
|
||||
pnpm registry:capture
|
||||
```
|
||||
|
||||
<Callout className="mt-6">
|
||||
|
||||
**Note:** If you've run the capture script before, you might need to delete the existing screenshots (both light and dark) at `apps/www/public/r/styles/new-york` and run the script again.
|
||||
|
||||
</Callout>
|
||||
|
||||
### Submit a pull request
|
||||
|
||||
Commit your changes and submit a pull request to the main repository.
|
||||
|
||||
Your block will be reviewed and merged. Once merged it will be published to the website and available to be installed via the CLI.
|
||||
|
||||
</Steps>
|
||||
|
||||
## Categories
|
||||
|
||||
The `categories` property is used to organize your block in the registry.
|
||||
|
||||
### Add a category
|
||||
|
||||
If you need to add a new category, you can do so by adding it to the `registryCategories` array in `apps/www/registry/registry-categories.ts`.
|
||||
|
||||
```tsx title="apps/www/registry/registry-categories.ts" showLineNumbers
|
||||
export const registryCategories = [
|
||||
// ...
|
||||
{
|
||||
name: "Input",
|
||||
slug: "input",
|
||||
hidden: false,
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
## Guidelines
|
||||
|
||||
Here are some guidelines to follow when contributing to the blocks library.
|
||||
|
||||
- The following properties are required for the block definition: `name`, `description`, `type`, `files`, and `categories`.
|
||||
- Make sure to list all registry dependencies in `registryDependencies`. A registry dependency is the name of the component in the registry eg. `input`, `button`, `card`, etc.
|
||||
- Make sure to list all dependencies in `dependencies`. A dependency is the name of the package in the registry eg. `zod`, `sonner`, etc.
|
||||
- If your block has a page (optional), it should be the first entry in the `files` array and it should have a `target` property. This helps the CLI place the page in the correct location for file-based routing.
|
||||
- **Imports should always use the `@/registry` path.** eg. `import { Input } from "@/registry/new-york/input"`
|
||||
30
apps/v4/content/docs/(root)/_v0.mdx
Normal file
30
apps/v4/content/docs/(root)/_v0.mdx
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
title: Open in v0
|
||||
description: Open components in v0 for customization.
|
||||
---
|
||||
|
||||
Every component on ui.shadcn.com is editable on [v0 by Vercel](https://v0.dev). This allows you to easily customize the components in natural language and paste into your app.
|
||||
|
||||
<a href="https://vercel.com/signup?utm_source=shad&utm_medium=web&utm_campaign=docs_cta_signup">
|
||||
<Image
|
||||
src="/images/open-in-v0.png"
|
||||
width="716"
|
||||
height="420"
|
||||
alt="Open in v0"
|
||||
className="mt-6 w-full overflow-hidden rounded-2xl border dark:hidden"
|
||||
/>
|
||||
<Image
|
||||
src="/images/open-in-v0-dark.png"
|
||||
width="716"
|
||||
height="420"
|
||||
alt="Open in v0"
|
||||
className="mt-6 hidden w-full overflow-hidden rounded-2xl border shadow-sm dark:block"
|
||||
/>
|
||||
<span className="sr-only">Open in v0</span>
|
||||
</a>
|
||||
|
||||
To use v0, sign-up for a free [Vercel account here](https://vercel.com/signup?utm_source=shad&utm_medium=web&utm_campaign=docs_cta_signup). In addition to v0, this gives you free access to Vercel's frontend cloud platform by the creators of Next.js, where you can deploy and host your project for free.
|
||||
|
||||
Learn more about getting started with [Vercel here](https://vercel.com/docs/getting-started-with-vercel?utm_source=shadcn_site&utm_medium=web&utm_campaign=docs_cta_about_vercel).
|
||||
|
||||
Learn more about getting started with [v0 here](https://v0.dev/faq).
|
||||
738
apps/v4/content/docs/(root)/cli.mdx
Normal file
738
apps/v4/content/docs/(root)/cli.mdx
Normal file
@@ -0,0 +1,738 @@
|
||||
---
|
||||
title: shadcn
|
||||
description: Use the shadcn CLI to add components to your project.
|
||||
---
|
||||
|
||||
import { TriangleAlertIcon } from "lucide-react"
|
||||
|
||||
## init
|
||||
|
||||
Use the `init` command to initialize configuration and dependencies for an existing project, or create a new project with `--name`.
|
||||
|
||||
The `init` command installs dependencies, adds the `cn` util and configures CSS variables for the project.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest init
|
||||
```
|
||||
|
||||
**Options**
|
||||
|
||||
```bash
|
||||
Usage: shadcn init [options] [components...]
|
||||
|
||||
initialize your project and install dependencies
|
||||
|
||||
Arguments:
|
||||
components names, url or local path to component
|
||||
|
||||
Options:
|
||||
-t, --template <template> the template to use. (next, vite, start, react-router, laravel, astro)
|
||||
-b, --base <base> the component library to use. (base, radix, aria)
|
||||
-p, --preset [name] use a preset configuration
|
||||
-y, --yes skip confirmation prompt. (default: true)
|
||||
-d, --defaults use default configuration: --template=next --preset=nova (default: false)
|
||||
-f, --force force overwrite of existing configuration. (default: false)
|
||||
-c, --cwd <cwd> the working directory. defaults to the current directory.
|
||||
-n, --name <name> the name for the new project.
|
||||
-s, --silent mute output. (default: false)
|
||||
--css-variables use css variables for theming. (default: true)
|
||||
--no-css-variables do not use css variables for theming.
|
||||
--monorepo scaffold a monorepo project.
|
||||
--no-monorepo skip the monorepo prompt.
|
||||
--rtl enable RTL support.
|
||||
--no-rtl disable RTL support.
|
||||
--pointer enable pointer cursor for buttons.
|
||||
--no-pointer disable pointer cursor for buttons.
|
||||
--reinstall re-install existing UI components.
|
||||
--no-reinstall do not re-install existing UI components.
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
The `create` command is an alias for `init`:
|
||||
|
||||
```bash
|
||||
npx shadcn@latest create
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## add
|
||||
|
||||
Use the `add` command to add components and dependencies to your project.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add [component]
|
||||
```
|
||||
|
||||
**Options**
|
||||
|
||||
```bash
|
||||
Usage: shadcn add [options] [components...]
|
||||
|
||||
add a component to your project
|
||||
|
||||
Arguments:
|
||||
components name, url or local path to component
|
||||
|
||||
Options:
|
||||
-y, --yes skip confirmation prompt. (default: false)
|
||||
-o, --overwrite overwrite existing files. (default: false)
|
||||
-c, --cwd <cwd> the working directory. defaults to the current directory.
|
||||
-a, --all add all available components (default: false)
|
||||
-p, --path <path> the path to add the component to.
|
||||
-s, --silent mute output. (default: false)
|
||||
--dry-run preview changes without writing files. (default: false)
|
||||
--diff [path] show diff for a file.
|
||||
--view [path] show file contents.
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## apply
|
||||
|
||||
Use the `apply` command to apply a preset to an existing project.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest apply a2r6bw
|
||||
```
|
||||
|
||||
You can apply only the theme or fonts from a preset without reinstalling UI components:
|
||||
|
||||
```bash
|
||||
npx shadcn@latest apply a2r6bw --only theme
|
||||
```
|
||||
|
||||
Supported values for `--only` are `theme` and `font`.
|
||||
|
||||
**Options**
|
||||
|
||||
```bash
|
||||
Usage: shadcn apply [options] [preset]
|
||||
|
||||
apply a preset to an existing project
|
||||
|
||||
Arguments:
|
||||
preset the preset to apply
|
||||
|
||||
Options:
|
||||
--preset <preset> preset configuration to apply
|
||||
--only [parts] apply only parts of a preset: theme, font
|
||||
-y, --yes skip confirmation prompt. (default: false)
|
||||
-c, --cwd <cwd> the working directory. defaults to the current directory.
|
||||
-s, --silent mute output. (default: false)
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## preset
|
||||
|
||||
Use the `preset` command to inspect preset codes and resolve the preset for an existing project.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest preset decode a2r6bw
|
||||
```
|
||||
|
||||
### preset decode
|
||||
|
||||
Use `preset decode` to decode a preset code.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest preset decode a2r6bw
|
||||
```
|
||||
|
||||
**Options**
|
||||
|
||||
```bash
|
||||
Usage: shadcn preset decode [options] <code>
|
||||
|
||||
decode a preset code
|
||||
|
||||
Arguments:
|
||||
code the preset code to decode
|
||||
|
||||
Options:
|
||||
--json output as JSON. (default: false)
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
### preset resolve
|
||||
|
||||
Use `preset resolve` to resolve the preset from the current project.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest preset resolve
|
||||
```
|
||||
|
||||
The `preset info` command is an alias for `preset resolve`:
|
||||
|
||||
```bash
|
||||
npx shadcn@latest preset info
|
||||
```
|
||||
|
||||
**Options**
|
||||
|
||||
```bash
|
||||
Usage: shadcn preset resolve|info [options]
|
||||
|
||||
resolve a preset from your project
|
||||
|
||||
Options:
|
||||
-c, --cwd <cwd> the working directory. defaults to the current directory.
|
||||
--json output as JSON. (default: false)
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
### preset url
|
||||
|
||||
Use `preset url` to print the create URL for a preset code.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest preset url a2r6bw
|
||||
```
|
||||
|
||||
**Options**
|
||||
|
||||
```bash
|
||||
Usage: shadcn preset url [options] <code>
|
||||
|
||||
get the create URL for a preset code
|
||||
|
||||
Arguments:
|
||||
code the preset code
|
||||
|
||||
Options:
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
### preset open
|
||||
|
||||
Use `preset open` to open a preset code in the browser.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest preset open a2r6bw
|
||||
```
|
||||
|
||||
**Options**
|
||||
|
||||
```bash
|
||||
Usage: shadcn preset open [options] <code>
|
||||
|
||||
open a preset code in the browser
|
||||
|
||||
Arguments:
|
||||
code the preset code
|
||||
|
||||
Options:
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## view
|
||||
|
||||
Use the `view` command to view items from the registry before installing them.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest view [item]
|
||||
```
|
||||
|
||||
You can view multiple items at once:
|
||||
|
||||
```bash
|
||||
npx shadcn@latest view button card dialog
|
||||
```
|
||||
|
||||
Or view items from namespaced registries:
|
||||
|
||||
```bash
|
||||
npx shadcn@latest view @acme/auth @v0/dashboard
|
||||
```
|
||||
|
||||
**Options**
|
||||
|
||||
```bash
|
||||
Usage: shadcn view [options] <items...>
|
||||
|
||||
view items from the registry
|
||||
|
||||
Arguments:
|
||||
items the item names or URLs to view
|
||||
|
||||
Options:
|
||||
-c, --cwd <cwd> the working directory. defaults to the current directory.
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## search
|
||||
|
||||
Use the `search` command to search for items from registries.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest search [registry]
|
||||
```
|
||||
|
||||
You can search with a query:
|
||||
|
||||
```bash
|
||||
npx shadcn@latest search @shadcn -q "button"
|
||||
```
|
||||
|
||||
Or search multiple registries at once:
|
||||
|
||||
```bash
|
||||
npx shadcn@latest search @shadcn @v0 @acme
|
||||
```
|
||||
|
||||
The `list` command is an alias for `search`:
|
||||
|
||||
```bash
|
||||
npx shadcn@latest list @acme
|
||||
```
|
||||
|
||||
**Options**
|
||||
|
||||
```bash
|
||||
Usage: shadcn search|list [options] <registries...>
|
||||
|
||||
search items from registries
|
||||
|
||||
Arguments:
|
||||
registries the registry names or urls to search items from. Names
|
||||
must be prefixed with @.
|
||||
|
||||
Options:
|
||||
-c, --cwd <cwd> the working directory. defaults to the current directory.
|
||||
-q, --query <query> query string
|
||||
-l, --limit <number> maximum number of items to display per registry (default: "100")
|
||||
-o, --offset <number> number of items to skip (default: "0")
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## build
|
||||
|
||||
Use the `build` command to generate the registry JSON files.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest build
|
||||
```
|
||||
|
||||
This command reads the `registry.json` file and generates the registry JSON files in the `public/r` directory.
|
||||
|
||||
**Options**
|
||||
|
||||
```bash
|
||||
Usage: shadcn build [options] [registry]
|
||||
|
||||
build components for a shadcn registry
|
||||
|
||||
Arguments:
|
||||
registry path to registry.json file (default: "./registry.json")
|
||||
|
||||
Options:
|
||||
-o, --output <path> destination directory for json files (default: "./public/r")
|
||||
-c, --cwd <cwd> the working directory. defaults to the current directory.
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
To customize the output directory, use the `--output` option.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest build --output ./public/registry
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## docs
|
||||
|
||||
Use the `docs` command to fetch documentation and API references for components.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest docs [component]
|
||||
```
|
||||
|
||||
**Options**
|
||||
|
||||
```bash
|
||||
Usage: shadcn docs [options] [component]
|
||||
|
||||
fetch documentation and API references for components
|
||||
|
||||
Arguments:
|
||||
component the component to get docs for
|
||||
|
||||
Options:
|
||||
-c, --cwd <cwd> the working directory. defaults to the current directory.
|
||||
-b, --base <base> the base to use: base, radix, or aria. defaults to project base.
|
||||
--json output as JSON. (default: false)
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## info
|
||||
|
||||
Use the `info` command to get information about your project.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest info
|
||||
```
|
||||
|
||||
**Options**
|
||||
|
||||
```bash
|
||||
Usage: shadcn info [options]
|
||||
|
||||
get information about your project
|
||||
|
||||
Options:
|
||||
-c, --cwd <cwd> the working directory. defaults to the current directory.
|
||||
--json output as JSON. (default: false)
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## migrate
|
||||
|
||||
Use the `migrate` command to run migrations on your project.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest migrate [migration]
|
||||
```
|
||||
|
||||
**Available Migrations**
|
||||
|
||||
| Migration | Description |
|
||||
| ------------ | ------------------------------------------------------- |
|
||||
| `cn` | Migrate `clsx` and `tailwind-merge` to `cn`. |
|
||||
| `icons` | Migrate your UI components to a different icon library. |
|
||||
| `base-color` | Migrate your theme to a different base color. |
|
||||
| `radix` | Migrate to radix-ui. |
|
||||
| `rtl` | Migrate your components to support RTL (right-to-left). |
|
||||
|
||||
**Options**
|
||||
|
||||
```bash
|
||||
Usage: shadcn migrate [options] [migration] [path]
|
||||
|
||||
run a migration.
|
||||
|
||||
Arguments:
|
||||
migration the migration to run.
|
||||
path optional path or glob pattern to migrate.
|
||||
|
||||
Options:
|
||||
-c, --cwd <cwd> the working directory. defaults to the current directory.
|
||||
-l, --list list all migrations. (default: false)
|
||||
-y, --yes skip confirmation prompt. (default: false)
|
||||
-f, --from <name> the base color or icon library to migrate from.
|
||||
-t, --to <name> the base color or icon library to migrate to.
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### migrate cn
|
||||
|
||||
The `cn` migration replaces `clsx`, `tailwind-merge` and `cnfast` with [`cn`](https://github.com/shadcn-ui/cn).
|
||||
|
||||
```bash
|
||||
npx shadcn@latest migrate cn
|
||||
```
|
||||
|
||||
Unlike the other migrations, `migrate cn` does not require a `components.json` file. You can run it in any JavaScript or TypeScript package project using Tailwind CSS v4.
|
||||
|
||||
This will:
|
||||
|
||||
1. Rewrite imports from `clsx`, `clsx/lite`, `tailwind-merge` and `cnfast`.
|
||||
2. Replace `twMerge(clsx(...))` compositions with direct `cn(...)` calls.
|
||||
3. Replace the standard shadcn utility with a direct re-export.
|
||||
4. Install `cn` and remove the old packages when no references remain.
|
||||
|
||||
**Before**
|
||||
|
||||
```tsx
|
||||
import { clsx, type ClassValue } from "clsx"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs))
|
||||
}
|
||||
```
|
||||
|
||||
**After**
|
||||
|
||||
```tsx
|
||||
export { cn } from "cn"
|
||||
```
|
||||
|
||||
The migration also preserves separate APIs when they are used independently:
|
||||
|
||||
```diff
|
||||
- import { clsx } from "clsx"
|
||||
- import { twMerge } from "tailwind-merge"
|
||||
+ import { clsx, twMerge } from "cn"
|
||||
```
|
||||
|
||||
Because `cnfast` has the same root API, its module specifiers are replaced directly:
|
||||
|
||||
```diff
|
||||
- import { cn } from "cnfast"
|
||||
+ import { cn } from "cn"
|
||||
```
|
||||
|
||||
Custom configuration APIs are moved to `cn/config`. Existing local names are preserved when an export was renamed:
|
||||
|
||||
```diff
|
||||
- import { createTailwindMerge, getDefaultConfig } from "tailwind-merge"
|
||||
+ import {
|
||||
+ createTwMerge as createTailwindMerge,
|
||||
+ defaultConfig as getDefaultConfig,
|
||||
+ } from "cn/config"
|
||||
```
|
||||
|
||||
<Callout icon={<TriangleAlertIcon />}>
|
||||
The `cn` merge engine supports Tailwind CSS v4, like `tailwind-merge` v3.
|
||||
Projects using Tailwind CSS v3 should continue using `tailwind-merge` v2. A
|
||||
`clsx`-only migration is safe in a Tailwind CSS v3 project.
|
||||
</Callout>
|
||||
|
||||
**Migrate specific files**
|
||||
|
||||
You can migrate a file, directory or glob pattern:
|
||||
|
||||
```bash
|
||||
# Migrate a specific file.
|
||||
npx shadcn@latest migrate cn src/lib/utils.ts
|
||||
|
||||
# Migrate files matching a glob pattern.
|
||||
npx shadcn@latest migrate cn "src/**/*.{ts,tsx}"
|
||||
```
|
||||
|
||||
Scoped migrations install `cn` but keep `clsx`, `tailwind-merge` and `cnfast` in `package.json`, because files outside the selected path may still use them.
|
||||
|
||||
The command leaves unsupported imports unchanged and reports them for manual review. This includes `experimentalParseClassName`, namespace imports, dynamic import shapes, direct calls to `validators` and variadic `createTailwindMerge` calls that cannot be migrated safely. An old dependency is retained whenever one of its references remains.
|
||||
|
||||
---
|
||||
|
||||
### migrate icons
|
||||
|
||||
The `icons` migration moves your components from one icon library to another.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest migrate icons
|
||||
```
|
||||
|
||||
This will prompt you for the source and target libraries, rewrite icon imports and JSX usage in your `ui` directory, install the target library and update `iconLibrary` in your `components.json` so future `npx shadcn add` installs use the new library.
|
||||
|
||||
The following libraries are supported: `lucide`, `tabler`, `hugeicons`, `phosphor`, `remixicon` and `radix` (legacy).
|
||||
|
||||
**Non-interactive**
|
||||
|
||||
Use `--from` and `--to` to skip the prompts:
|
||||
|
||||
```bash
|
||||
npx shadcn@latest migrate icons --from lucide --to phosphor --yes
|
||||
```
|
||||
|
||||
**Migrate specific files**
|
||||
|
||||
You can migrate specific files or use glob patterns. Scoped runs do not update `components.json`.
|
||||
|
||||
```bash
|
||||
# Migrate a specific file.
|
||||
npx shadcn@latest migrate icons src/components/ui/button.tsx --from lucide --to tabler
|
||||
|
||||
# Migrate files matching a glob pattern.
|
||||
npx shadcn@latest migrate icons "src/components/**" --from lucide --to tabler
|
||||
```
|
||||
|
||||
Icons without an equivalent in the target library are left untouched and reported at the end of the migration.
|
||||
|
||||
---
|
||||
|
||||
### migrate base-color
|
||||
|
||||
The `base-color` migration switches your theme from one base color to another.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest migrate base-color
|
||||
```
|
||||
|
||||
This will prompt you for the source and target base colors, rewrite the theme CSS variables (the CSS file configured by `tailwind.css` in your `components.json`) and update `baseColor` so future `npx shadcn add` installs use the new base color.
|
||||
|
||||
The following base colors are supported: `neutral`, `zinc`, `stone`, `mauve`, `olive`, `mist` and `taupe`.
|
||||
|
||||
**Non-interactive**
|
||||
|
||||
Use `--to` to migrate from the current `baseColor` in your `components.json`, or pass both `--from` and `--to` explicitly.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest migrate base-color --to zinc --yes
|
||||
```
|
||||
|
||||
Theme tokens that no longer match the source base color are left untouched and reported at the end of the migration.
|
||||
|
||||
---
|
||||
|
||||
### migrate rtl
|
||||
|
||||
The `rtl` migration transforms your components to support RTL (right-to-left) languages.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest migrate rtl
|
||||
```
|
||||
|
||||
This will:
|
||||
|
||||
1. Update `components.json` to set `rtl: true`
|
||||
2. Transform physical CSS properties to logical equivalents (e.g., `ml-4` → `ms-4`, `text-left` → `text-start`)
|
||||
3. Add `rtl:` variants where needed (e.g., `space-x-4` → `space-x-4 rtl:space-x-reverse`)
|
||||
|
||||
**Migrate specific files**
|
||||
|
||||
You can migrate specific files or use glob patterns:
|
||||
|
||||
```bash
|
||||
# Migrate a specific file
|
||||
npx shadcn@latest migrate rtl src/components/ui/button.tsx
|
||||
|
||||
# Migrate files matching a glob pattern
|
||||
npx shadcn@latest migrate rtl "src/components/ui/**"
|
||||
```
|
||||
|
||||
If no path is provided, the migration will transform all files in your `ui` directory (from `components.json`).
|
||||
|
||||
---
|
||||
|
||||
### migrate radix
|
||||
|
||||
The `radix` migration updates your imports from individual `@radix-ui/react-*` packages to the unified `radix-ui` package.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest migrate radix
|
||||
```
|
||||
|
||||
This will:
|
||||
|
||||
1. Transform imports from `@radix-ui/react-*` to `radix-ui`
|
||||
2. Add the `radix-ui` package to your `package.json`
|
||||
|
||||
**Before**
|
||||
|
||||
```tsx
|
||||
import * as DialogPrimitive from "@radix-ui/react-dialog"
|
||||
import * as SelectPrimitive from "@radix-ui/react-select"
|
||||
```
|
||||
|
||||
**After**
|
||||
|
||||
```tsx
|
||||
import { Dialog as DialogPrimitive, Select as SelectPrimitive } from "radix-ui"
|
||||
```
|
||||
|
||||
**Migrate specific files**
|
||||
|
||||
You can migrate specific files or use glob patterns:
|
||||
|
||||
```bash
|
||||
# Migrate a specific file.
|
||||
npx shadcn@latest migrate radix src/components/ui/dialog.tsx
|
||||
|
||||
# Migrate files matching a glob pattern.
|
||||
npx shadcn@latest migrate radix "src/components/ui/**"
|
||||
```
|
||||
|
||||
If no path is provided, the migration will transform all files in your `ui` directory (from `components.json`).
|
||||
|
||||
Once complete, you can remove any unused `@radix-ui/react-*` packages from your `package.json`.
|
||||
|
||||
---
|
||||
|
||||
## eject
|
||||
|
||||
When you run `init`, shadcn adds `@import "shadcn/tailwind.css"` to your global CSS file. This import provides shared Tailwind v4 utilities such as custom variants (`data-open:`, `data-closed:`, etc.) and accordion animations.
|
||||
|
||||
Use the `eject` command to inline `shadcn/tailwind.css` into your global CSS file and remove the `shadcn` dependency from your project.
|
||||
|
||||
<Callout icon={<TriangleAlertIcon />}>
|
||||
**Note: This action is irreversible.** After ejecting, future shadcn CLI
|
||||
updates to `shadcn/tailwind.css` will not apply automatically.
|
||||
</Callout>
|
||||
|
||||
```bash
|
||||
npx shadcn@latest eject
|
||||
```
|
||||
|
||||
**Before**
|
||||
|
||||
```css
|
||||
@import "tailwindcss";
|
||||
@import "tw-animate-css";
|
||||
@import "shadcn/tailwind.css";
|
||||
```
|
||||
|
||||
**After**
|
||||
|
||||
```css
|
||||
@import "tailwindcss";
|
||||
@import "tw-animate-css";
|
||||
/* ejected from shadcn@4.8.3 */
|
||||
@theme inline {
|
||||
@keyframes accordion-down {
|
||||
from {
|
||||
height: 0;
|
||||
}
|
||||
to {
|
||||
height: var(
|
||||
--radix-accordion-content-height,
|
||||
var(--accordion-panel-height, auto)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@custom-variant data-open {
|
||||
&:where([data-state="open"]),
|
||||
&:where([data-open]:not([data-open="false"])) {
|
||||
@slot;
|
||||
}
|
||||
}
|
||||
|
||||
@utility no-scrollbar {
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Monorepo**
|
||||
|
||||
In a monorepo, run the command from the workspace that contains your `components.json` and global CSS file:
|
||||
|
||||
```bash
|
||||
npx shadcn@latest eject -c packages/ui
|
||||
```
|
||||
|
||||
**Options**
|
||||
|
||||
```bash
|
||||
Usage: shadcn eject [options]
|
||||
|
||||
inline shadcn/tailwind.css and remove the shadcn dependency
|
||||
|
||||
Options:
|
||||
-c, --cwd <cwd> the working directory. defaults to the current directory.
|
||||
-y, --yes skip confirmation prompt. (default: false)
|
||||
-s, --silent mute output. (default: false)
|
||||
-h, --help display help for command
|
||||
```
|
||||
379
apps/v4/content/docs/(root)/components-json.mdx
Normal file
379
apps/v4/content/docs/(root)/components-json.mdx
Normal file
@@ -0,0 +1,379 @@
|
||||
---
|
||||
title: components.json
|
||||
description: Configuration for your project.
|
||||
---
|
||||
|
||||
The `components.json` file holds configuration for your project.
|
||||
|
||||
We use it to understand how your project is set up and how to generate components customized for your project.
|
||||
|
||||
<Callout className="mt-6" title="Note: The `components.json` file is optional">
|
||||
It is **only required if you're using the CLI** to add components to your
|
||||
project. If you're using the copy and paste method, you don't need this file.
|
||||
</Callout>
|
||||
|
||||
You can create a `components.json` file in your project by running the following command:
|
||||
|
||||
```bash
|
||||
npx shadcn@latest init
|
||||
```
|
||||
|
||||
See the <Link href="/docs/cli">CLI section</Link> for more information.
|
||||
|
||||
## $schema
|
||||
|
||||
You can see the JSON Schema for `components.json` [here](https://ui.shadcn.com/schema.json).
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema.json"
|
||||
}
|
||||
```
|
||||
|
||||
## style
|
||||
|
||||
The style for your components. **This cannot be changed after initialization.**
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"style": "new-york"
|
||||
}
|
||||
```
|
||||
|
||||
The `default` style has been deprecated. Use the `new-york` style instead.
|
||||
|
||||
## tailwind
|
||||
|
||||
Configuration to help the CLI understand how Tailwind CSS is set up in your project.
|
||||
|
||||
See the <Link href="/docs/installation">installation section</Link> for how to set up Tailwind CSS.
|
||||
|
||||
### tailwind.config
|
||||
|
||||
Path to where your `tailwind.config.js` file is located. **For Tailwind CSS v4, leave this blank.**
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"tailwind": {
|
||||
"config": "tailwind.config.js" | "tailwind.config.ts"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### tailwind.css
|
||||
|
||||
Path to the CSS file that imports Tailwind CSS into your project.
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"tailwind": {
|
||||
"css": "styles/global.css"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### tailwind.baseColor
|
||||
|
||||
This is used to generate the default theme tokens for your components. **This cannot be changed after initialization.**
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"tailwind": {
|
||||
"baseColor": "neutral" | "stone" | "zinc" | "mauve" | "olive" | "mist" | "taupe"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### tailwind.cssVariables
|
||||
|
||||
We use and recommend CSS variables for theming.
|
||||
|
||||
Set `tailwind.cssVariables` to `true` to generate semantic theme tokens like `background`, `foreground`, and `primary`. Set it to `false` to generate inline Tailwind color utilities instead.
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"tailwind": {
|
||||
"cssVariables": `true` | `false`
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
For more information, see the <Link href="/docs/theming">theming docs</Link>.
|
||||
|
||||
**This cannot be changed after initialization.** To switch between CSS variables and utility classes, you'll have to delete and re-install your components.
|
||||
|
||||
### tailwind.prefix
|
||||
|
||||
The prefix to use for your Tailwind CSS utility classes. Components will be added with this prefix.
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"tailwind": {
|
||||
"prefix": "tw-"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## rsc
|
||||
|
||||
Whether or not to enable support for React Server Components.
|
||||
|
||||
The CLI automatically adds a `use client` directive to client components when set to `true`.
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"rsc": `true` | `false`
|
||||
}
|
||||
```
|
||||
|
||||
## tsx
|
||||
|
||||
Choose between TypeScript or JavaScript components.
|
||||
|
||||
Setting this option to `false` allows components to be added as JavaScript with the `.jsx` file extension.
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"tsx": `true` | `false`
|
||||
}
|
||||
```
|
||||
|
||||
## aliases
|
||||
|
||||
The CLI uses these values to place generated components in the correct location and rewrite imports.
|
||||
|
||||
You can back these aliases with either:
|
||||
|
||||
1. `compilerOptions.paths` in your `tsconfig.json` or `jsconfig.json`
|
||||
2. `package.json#imports` with TypeScript package import resolution enabled
|
||||
|
||||
The aliases in `components.json` are still required when using the CLI. They tell the CLI which import roots map to `components`, `ui`, `lib`, `hooks`, and `utils`.
|
||||
|
||||
<Callout className="mt-6">
|
||||
**Important:** If you're using package imports, enable
|
||||
`resolvePackageJsonImports` and use `moduleResolution: "bundler"` in your
|
||||
`tsconfig.json`. If you're using `paths`, make sure your aliases include the
|
||||
`src` directory when applicable.
|
||||
</Callout>
|
||||
|
||||
### Using `tsconfig` or `jsconfig` paths
|
||||
|
||||
```json title="tsconfig.json"
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Using `package.json#imports`
|
||||
|
||||
Recommended setup for a single-package app:
|
||||
|
||||
```json title="package.json"
|
||||
{
|
||||
"imports": {
|
||||
"#components/*": "./src/components/*.tsx",
|
||||
"#lib/*": "./src/lib/*.ts",
|
||||
"#hooks/*": "./src/hooks/*.ts"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json title="tsconfig.json"
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "bundler",
|
||||
"resolvePackageJsonImports": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"aliases": {
|
||||
"components": "#components",
|
||||
"ui": "#components/ui",
|
||||
"lib": "#lib",
|
||||
"hooks": "#hooks",
|
||||
"utils": "#lib/utils"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The aliases in `components.json` still tell the CLI where to place
|
||||
`components`, `ui`, `lib`, `hooks`, and `utils`. `package.json#imports`
|
||||
provides the runtime and TypeScript resolution for those `#...` specifiers.
|
||||
|
||||
The matched `imports` target also controls whether generated `#...` imports keep
|
||||
file extensions:
|
||||
|
||||
- `"#components/*": "./src/components/*"` preserves source extensions and can
|
||||
generate imports like
|
||||
`#components/button.tsx`
|
||||
- `"#components/*": "./src/components/*.tsx"` strips source extensions and
|
||||
generates imports like
|
||||
`#components/button`
|
||||
|
||||
For monorepos, see the <Link href="/docs/monorepo">monorepo docs</Link>. Local
|
||||
workspace aliases can use `package.json#imports`, while shared workspace
|
||||
imports such as `@workspace/ui/components` are resolved from the target
|
||||
package's `exports`.
|
||||
|
||||
For framework-specific setup, see the [package imports guide](/docs/package-imports).
|
||||
|
||||
### aliases.utils
|
||||
|
||||
Import alias for your utility functions.
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"aliases": {
|
||||
"utils": "@/lib/utils"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### aliases.components
|
||||
|
||||
Import alias for your components.
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"aliases": {
|
||||
"components": "@/components"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### aliases.ui
|
||||
|
||||
Import alias for `ui` components.
|
||||
|
||||
The CLI will use the `aliases.ui` value to determine where to place your `ui` components. Use this config if you want to customize the installation directory for your `ui` components.
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"aliases": {
|
||||
"ui": "@/app/ui"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### aliases.lib
|
||||
|
||||
Import alias for `lib` functions such as `format-date` or `generate-id`.
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"aliases": {
|
||||
"lib": "@/lib"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### aliases.hooks
|
||||
|
||||
Import alias for `hooks` such as `use-media-query` or `use-toast`.
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"aliases": {
|
||||
"hooks": "@/hooks"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## registries
|
||||
|
||||
Configure multiple resource registries for your project. This allows you to install components, libraries, utilities, and other resources from various sources including private registries.
|
||||
|
||||
See the <Link href="/docs/registry/namespace">Namespaced Registries</Link> documentation for detailed information.
|
||||
|
||||
### Basic Configuration
|
||||
|
||||
Configure registries with URL templates:
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"registries": {
|
||||
"@v0": "https://v0.dev/chat/b/{name}",
|
||||
"@acme": "https://registry.acme.com/{name}.json",
|
||||
"@internal": "https://internal.company.com/{name}.json"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The `{name}` placeholder is replaced with the resource name when installing.
|
||||
|
||||
### Advanced Configuration with Authentication
|
||||
|
||||
For private registries that require authentication:
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"registries": {
|
||||
"@private": {
|
||||
"url": "https://api.company.com/registry/{name}.json",
|
||||
"headers": {
|
||||
"Authorization": "Bearer ${REGISTRY_TOKEN}",
|
||||
"X-API-Key": "${API_KEY}"
|
||||
},
|
||||
"params": {
|
||||
"version": "latest"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Environment variables in the format `${VAR_NAME}` are automatically expanded from your environment.
|
||||
|
||||
### Using Namespaced Registries
|
||||
|
||||
Once configured, install resources using the namespace syntax:
|
||||
|
||||
```bash
|
||||
# Install from a configured registry
|
||||
npx shadcn@latest add @v0/dashboard
|
||||
|
||||
# Install from private registry
|
||||
npx shadcn@latest add @private/button
|
||||
|
||||
# Install multiple resources
|
||||
npx shadcn@latest add @acme/header @internal/auth-utils
|
||||
```
|
||||
|
||||
### Example: Multiple Registry Setup
|
||||
|
||||
```json title="components.json"
|
||||
{
|
||||
"registries": {
|
||||
"@shadcn": "https://ui.shadcn.com/r/{name}.json",
|
||||
"@company-ui": {
|
||||
"url": "https://registry.company.com/ui/{name}.json",
|
||||
"headers": {
|
||||
"Authorization": "Bearer ${COMPANY_TOKEN}"
|
||||
}
|
||||
},
|
||||
"@team": {
|
||||
"url": "https://team.company.com/{name}.json",
|
||||
"params": {
|
||||
"team": "frontend",
|
||||
"version": "${REGISTRY_VERSION}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This configuration allows you to:
|
||||
|
||||
- Install public components from shadcn/ui
|
||||
- Access private company UI components with authentication
|
||||
- Use team-specific resources with versioning
|
||||
|
||||
For more information about authentication, see the <Link href="/docs/registry/authentication">Authentication</Link> documentation.
|
||||
74
apps/v4/content/docs/(root)/directory.mdx
Normal file
74
apps/v4/content/docs/(root)/directory.mdx
Normal file
@@ -0,0 +1,74 @@
|
||||
---
|
||||
title: Registry Directory
|
||||
description: Discover community registries for shadcn/ui components and blocks.
|
||||
---
|
||||
|
||||
These registries are built into the CLI with no additional configuration required. To add a component, run: `npx shadcn add @<registry>/<component>`.
|
||||
|
||||
<Callout className="bg-muted font-semibold">
|
||||
Community registries are maintained by third-party developers. Always review
|
||||
code on installation to ensure it meets your security and quality standards.
|
||||
</Callout>
|
||||
|
||||
Don't see a registry? Learn how to [add it here](/docs/registry/registry-index).
|
||||
|
||||
<DirectoryList />
|
||||
|
||||
## Documentation
|
||||
|
||||
You can use the `shadcn` CLI to run your own code registry. Running your own registry allows you to distribute your custom components, hooks, pages, config, rules and other files to any project.
|
||||
|
||||
<div className="mt-6 grid gap-4 sm:grid-cols-2">
|
||||
<LinkedCard href="/docs/registry/getting-started" className="items-start text-sm md:p-6">
|
||||
<div className="font-medium">Getting Started</div>
|
||||
<div className="text-muted-foreground">
|
||||
Set up and build your own registry
|
||||
</div>
|
||||
</LinkedCard>
|
||||
|
||||
<LinkedCard
|
||||
href="/docs/registry/authentication"
|
||||
className="items-start text-sm md:p-6"
|
||||
>
|
||||
<div className="font-medium">Authentication</div>
|
||||
<div className="text-muted-foreground">
|
||||
Secure your registry with authentication
|
||||
</div>
|
||||
</LinkedCard>
|
||||
<LinkedCard
|
||||
href="/docs/registry/namespace"
|
||||
className="items-start text-sm md:p-6"
|
||||
>
|
||||
<div className="font-medium">Namespaces</div>
|
||||
<div className="text-muted-foreground">
|
||||
Configure registries with namespaces
|
||||
</div>
|
||||
</LinkedCard>
|
||||
<LinkedCard
|
||||
href="/docs/registry/registry-index"
|
||||
className="items-start text-sm md:p-6"
|
||||
>
|
||||
<div className="font-medium">Add a Registry</div>
|
||||
<div className="text-muted-foreground">
|
||||
Learn how to add a registry to the directory
|
||||
</div>
|
||||
</LinkedCard>
|
||||
<LinkedCard
|
||||
href="/docs/registry/examples"
|
||||
className="items-start text-sm md:p-6"
|
||||
>
|
||||
<div className="font-medium">Examples</div>
|
||||
<div className="text-muted-foreground">
|
||||
Registry item examples and configurations
|
||||
</div>
|
||||
</LinkedCard>
|
||||
<LinkedCard
|
||||
href="/docs/registry/registry-json"
|
||||
className="items-start text-sm md:p-6"
|
||||
>
|
||||
<div className="font-medium">Schema</div>
|
||||
<div className="text-muted-foreground">
|
||||
Schema specification for registry.json
|
||||
</div>
|
||||
</LinkedCard>
|
||||
</div>
|
||||
26
apps/v4/content/docs/(root)/figma.mdx
Normal file
26
apps/v4/content/docs/(root)/figma.mdx
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
title: Figma
|
||||
description: Every component recreated in Figma. With customizable props, typography and icons.
|
||||
---
|
||||
|
||||
<Callout>
|
||||
**Note:** The Figma files are contributed by the community. If you have any
|
||||
questions or feedback, please reach out to the Figma file maintainers.
|
||||
</Callout>
|
||||
|
||||
## Free
|
||||
|
||||
- [shadcn/ui components](https://www.figma.com/community/file/1342715840824755935) by [Sitsiilia Bergmann](https://x.com/sitsiilia) - A well-structured component library aligned with the shadcn component system, regularly maintained.
|
||||
- [shadcn/ui design system](https://www.figma.com/community/file/1203061493325953101) by [Pietro Schirano](https://twitter.com/skirano) - A design companion for shadcn/ui. Each component was painstakingly crafted to perfectly match the code implementation.
|
||||
- [Obra shadcn/ui Community Edition](https://www.figma.com/community/file/1514746685758799870/) by [Obra Studio](https://obra.studio/) - The most complete free shadcn/ui kit for Figma, with all components and an easy theming system. Maintained by a team of designers.
|
||||
- [shadcncraft Free Starter Kit](https://www.figma.com/community/file/1534076420225325960) by [shadcncraft](https://shadcncraft.com) - Native Figma variables for all eight shadcn/ui styles, import themes from tweakcn and shadcn/ui Create, icon switching, and matching React components. Actively maintained.
|
||||
|
||||
## Paid
|
||||
|
||||
- [shadcn/ui kit](https://shadcndesign.com) by [Matt Wierzbicki](https://x.com/matsugfx) - A premium, always up-to-date UI kit for Figma - shadcn/ui compatible and optimized for smooth design-to-dev handoff.
|
||||
- [shadcncraft – shadcn/ui Figma kit](https://shadcncraft.com/figma) - All eight shadcn styles and hundreds of Pro components and blocks with matching React code. The plugin builds new styles, loads custom shadcn presets and tweakcn themes, and exports frames to React; agent skills turn designs into code through the Figma MCP.
|
||||
- [shadcn/studio UI Kit](https://shadcnstudio.com/figma) - Accelerate design & development with a shadcn/ui compatible Figma kit with updated components, 550+ blocks, 10+ templates, 20+ themes, and an AI tool that converts designs into shadcn/ui code.
|
||||
- [Shadcnblocks.com](https://www.shadcnblocks.com) - A Premium Shadcn Figma UI Kit with components, 500+ pro blocks, shadcn theme variables, light/dark mode and Figma MCP ready.
|
||||
- [Obra shadcn/ui Pro](https://shadcn.obra.studio/products/obra-shadcn-ui-pro) by [Obra Studio](https://obra.studio/) - The best designer experience for shadcn/ui within Figma. All 8 styles, consistency with shadcn, Pro blocks, and a design-to-code plugin.
|
||||
- [Shadcn Space](https://shadcnspace.com/figma) - A collection of beautifully designed 320+ blocks, 9+ templates, and 250+ components with a shadcn/ui-compatible Figma kit built for modern React and Next.js workflows. Design, prototype, and ship faster using Figma components that mirror real code architecture and production-ready implementation patterns.
|
||||
- [Shadcn Design System](https://shadcnstore.com/) by [ShadcnStore](https://x.com/shadcnstore) - A complete Figma UI kit for shadcn/ui with components, variants, design tokens, production-ready blocks and templates. Built for fast workflows and pixel-perfect designer-to-developer handoff.
|
||||
77
apps/v4/content/docs/(root)/index.mdx
Normal file
77
apps/v4/content/docs/(root)/index.mdx
Normal file
@@ -0,0 +1,77 @@
|
||||
---
|
||||
title: Introduction
|
||||
description: shadcn/ui is a set of beautifully-designed, accessible components and a code distribution platform. Works with your favorite frameworks and AI models. Open Source. Open Code.
|
||||
---
|
||||
|
||||
**This is not a component library. It is how you build your component library.**
|
||||
|
||||
You know how most traditional component libraries work: you install a package from NPM, import the components, and use them in your app.
|
||||
|
||||
This approach works well until you need to customize a component to fit your design system or require one that isn’t included in the library. **Often, you end up wrapping library components, writing workarounds to override styles, or mixing components from different libraries with incompatible APIs.**
|
||||
|
||||
This is what shadcn/ui aims to solve. It is built around the following principles:
|
||||
|
||||
- **Open Code:** The top layer of your component code is open for modification.
|
||||
- **Composition:** Every component uses a common, composable interface, making them predictable.
|
||||
- **Distribution:** A flat-file schema and command-line tool make it easy to distribute components.
|
||||
- **Beautiful Defaults:** Carefully chosen default styles, so you get great design out-of-the-box.
|
||||
- **AI-Ready:** Open code for LLMs to read, understand, and improve.
|
||||
|
||||
## Open Code
|
||||
|
||||
shadcn/ui hands you the actual component code. You have full control to customize and extend the components to your needs. This means:
|
||||
|
||||
- **Full Transparency:** You see exactly how each component is built.
|
||||
- **Easy Customization:** Modify any part of a component to fit your design and functionality requirements.
|
||||
- **AI Integration:** Access to the code makes it straightforward for LLMs to read, understand, and even improve your components.
|
||||
|
||||
_In a typical library, if you need to change a button’s behavior, you have to override styles or wrap the component. With shadcn/ui, you simply edit the button code directly._
|
||||
|
||||
<Accordion type="single" collapsible>
|
||||
<AccordionItem value="faq-1" className="border-none">
|
||||
<AccordionTrigger>
|
||||
How do I pull upstream updates in an Open Code approach?
|
||||
</AccordionTrigger>
|
||||
<AccordionContent className="flex flex-col gap-4">
|
||||
<p>
|
||||
shadcn/ui follows a headless component architecture. This means the core
|
||||
of your app can receive fixes by updating your dependencies, for
|
||||
instance, @base-ui/react or input-otp.
|
||||
</p>
|
||||
<p>
|
||||
The topmost layer, i.e., the one closest to your design system, is not
|
||||
coupled with the implementation of the library. It stays open for
|
||||
modification.
|
||||
</p>
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
|
||||
## Composition
|
||||
|
||||
Every component in shadcn/ui shares a common, composable interface. **If a component does not exist, we bring it in, make it composable, and adjust its style to match and work with the rest of the design system.**
|
||||
|
||||
_A shared, composable interface means it's predictable for both your team and LLMs. You are not learning different APIs for every new component. Even for third-party ones._
|
||||
|
||||
## Distribution
|
||||
|
||||
shadcn/ui is also a code distribution system. It defines a schema for components and a CLI to distribute them.
|
||||
|
||||
- **Schema:** A flat-file structure that defines the components, their dependencies, and properties.
|
||||
- **CLI:** A command-line tool to distribute and install components across projects with cross-framework support.
|
||||
|
||||
_You can use the schema to distribute your components to other projects or have AI generate completely new components based on existing schema._
|
||||
|
||||
## Beautiful Defaults
|
||||
|
||||
shadcn/ui comes with a large collection of components that have carefully chosen default styles. They are designed to look good on their own and to work well together as a consistent system:
|
||||
|
||||
- **Good Out-of-the-Box:** Your UI has a clean and minimal look without extra work.
|
||||
- **Unified Design:** Components naturally fit with one another. Each component is built to match the others, keeping your UI consistent.
|
||||
- **Easily Customizable:** If you want to change something, it's simple to override and extend the defaults.
|
||||
|
||||
## AI-Ready
|
||||
|
||||
The design of shadcn/ui makes it easy for AI tools to work with your code. Its open code and consistent API allow AI models to read, understand, and even generate new components.
|
||||
|
||||
_An AI model can learn how your components work and suggest improvements or even create new components that integrate with your existing design._
|
||||
44
apps/v4/content/docs/(root)/javascript.mdx
Normal file
44
apps/v4/content/docs/(root)/javascript.mdx
Normal file
@@ -0,0 +1,44 @@
|
||||
---
|
||||
title: JavaScript
|
||||
description: How to use shadcn/ui with JavaScript
|
||||
---
|
||||
|
||||
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 as well. The JavaScript version is available via the [cli](/docs/cli).
|
||||
|
||||
To opt-out of TypeScript, you can use the `tsx` flag in your `components.json` file.
|
||||
|
||||
```json {4} title="components.json" showLineNumbers
|
||||
{
|
||||
"style": "new-york",
|
||||
"rsc": false,
|
||||
"tsx": false,
|
||||
"tailwind": {
|
||||
"config": "",
|
||||
"css": "src/app/globals.css",
|
||||
"baseColor": "zinc",
|
||||
"cssVariables": true
|
||||
},
|
||||
"iconLibrary": "lucide",
|
||||
"aliases": {
|
||||
"components": "@/components",
|
||||
"utils": "@/lib/utils",
|
||||
"ui": "@/components/ui",
|
||||
"lib": "@/lib",
|
||||
"hooks": "@/hooks"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To configure import aliases, you can use the following `jsconfig.json`:
|
||||
|
||||
```json {4} title="jsconfig.json" showLineNumbers
|
||||
{
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"@/*": ["./*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
12
apps/v4/content/docs/(root)/legacy.mdx
Normal file
12
apps/v4/content/docs/(root)/legacy.mdx
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
title: Legacy Docs
|
||||
description: View the legacy docs for shadcn/ui and Tailwind v3.
|
||||
---
|
||||
|
||||
You're looking at the docs for shadcn/ui + Tailwind v4. If you're looking for the docs for shadcn/ui + Tailwind v3, you can find them [here](https://v3.shadcn.com).
|
||||
|
||||
<Button asChild className="mt-6 no-underline" size="sm">
|
||||
<Link href="https://v3.shadcn.com" target="_blank">
|
||||
View the legacy docs
|
||||
</Link>
|
||||
</Button>
|
||||
338
apps/v4/content/docs/(root)/mcp.mdx
Normal file
338
apps/v4/content/docs/(root)/mcp.mdx
Normal file
@@ -0,0 +1,338 @@
|
||||
---
|
||||
title: MCP Server
|
||||
description: Use the shadcn MCP server to browse, search, and install components from registries.
|
||||
---
|
||||
|
||||
The shadcn MCP Server allows AI assistants to interact with items from registries. You can browse available components, search for specific ones, and install them directly into your project using natural language.
|
||||
|
||||
For example, you can ask an AI assistant to "Build a landing page using components from the acme registry" or "Find me a login form from the shadcn registry".
|
||||
|
||||
Registries are configured in your project's `components.json` file.
|
||||
|
||||
```json title="components.json" showLineNumbers
|
||||
{
|
||||
"registries": {
|
||||
"@acme": "https://acme.com/r/{name}.json"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
Select your MCP client and follow the instructions to configure the shadcn MCP server. If you'd like to do it manually, see the [Configuration](#configuration) section.
|
||||
|
||||
<Tabs defaultValue="claude">
|
||||
<TabsList>
|
||||
<TabsTrigger value="claude">Claude Code</TabsTrigger>
|
||||
<TabsTrigger value="cursor">Cursor</TabsTrigger>
|
||||
<TabsTrigger value="vscode">VS Code</TabsTrigger>
|
||||
<TabsTrigger value="codex">Codex</TabsTrigger>
|
||||
<TabsTrigger value="opencode">OpenCode</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="claude" className="mt-4">
|
||||
**Run the following command** in your project:
|
||||
```bash
|
||||
npx shadcn@latest mcp init --client claude
|
||||
```
|
||||
|
||||
**Restart Claude Code** and try the following prompts:
|
||||
- Show me all available components in the shadcn registry
|
||||
- Add the button, dialog and card components to my project
|
||||
- Create a contact form using components from the shadcn registry
|
||||
|
||||
**Note:** You can use `/mcp` command in Claude Code to debug the MCP server.
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="cursor" className="mt-4">
|
||||
**Run the following command** in your project:
|
||||
```bash
|
||||
npx shadcn@latest mcp init --client cursor
|
||||
```
|
||||
|
||||
Open **Cursor Settings** and **Enable the MCP server** for shadcn. Then try the following prompts:
|
||||
- Show me all available components in the shadcn registry
|
||||
- Add the button, dialog and card components to my project
|
||||
- Create a contact form using components from the shadcn registry
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="vscode" className="mt-4">
|
||||
**Run the following command** in your project:
|
||||
```bash
|
||||
npx shadcn@latest mcp init --client vscode
|
||||
```
|
||||
|
||||
Open `.vscode/mcp.json` and click **Start** next to the shadcn server. Then try the following prompts with GitHub Copilot:
|
||||
- Show me all available components in the shadcn registry
|
||||
- Add the button, dialog and card components to my project
|
||||
- Create a contact form using components from the shadcn registry
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="codex" className="mt-4">
|
||||
<Callout className="mt-0">
|
||||
**Note:** The `shadcn` CLI cannot automatically update `~/.codex/config.toml`.
|
||||
You'll need to add the configuration manually for Codex.
|
||||
</Callout>
|
||||
|
||||
**Run the following command** in your project:
|
||||
```bash
|
||||
npx shadcn@latest mcp init --client codex
|
||||
```
|
||||
|
||||
**Then, add the following configuration** to `~/.codex/config.toml`:
|
||||
```toml
|
||||
[mcp_servers.shadcn]
|
||||
command = "npx"
|
||||
args = ["shadcn@latest", "mcp"]
|
||||
```
|
||||
|
||||
**Restart Codex** and try the following prompts:
|
||||
- Show me all available components in the shadcn registry
|
||||
- Add the button, dialog and card components to my project
|
||||
- Create a contact form using components from the shadcn registry
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="opencode" className="mt-4">
|
||||
**Run the following command** in your project:
|
||||
```bash
|
||||
npx shadcn@latest mcp init --client opencode
|
||||
```
|
||||
|
||||
**Restart OpenCode** and try the following prompts:
|
||||
- Show me all available components in the shadcn registry
|
||||
- Add the button, dialog and card components to my project
|
||||
- Create a contact form using components from the shadcn registry
|
||||
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
|
||||
---
|
||||
|
||||
## What is MCP?
|
||||
|
||||
[Model Context Protocol (MCP)](https://modelcontextprotocol.io) is an open protocol that enables AI assistants to securely connect to external data sources and tools. With the shadcn MCP server, your AI assistant gains direct access to:
|
||||
|
||||
- **Browse Components** - List all available components, blocks, and templates from any configured registry
|
||||
- **Search Across Registries** - Find specific components by name or functionality across multiple sources
|
||||
- **Install with Natural Language** - Add components using simple conversational prompts like "add a login form"
|
||||
- **Support for Multiple Registries** - Access public registries, private company libraries, and third-party sources
|
||||
|
||||
---
|
||||
|
||||
## How It Works
|
||||
|
||||
The MCP server acts as a bridge between your AI assistant, component registries and the shadcn CLI.
|
||||
|
||||
1. **Registry Connection** - MCP connects to configured registries (shadcn/ui, private registries, third-party sources)
|
||||
2. **Natural Language** - You describe what you need in plain English
|
||||
3. **AI Processing** - The assistant translates your request into registry commands
|
||||
4. **Component Delivery** - Resources are fetched and installed in your project
|
||||
|
||||
---
|
||||
|
||||
## Supported Registries
|
||||
|
||||
The shadcn MCP server works out of the box with any shadcn-compatible registry.
|
||||
|
||||
- **shadcn/ui Registry** - The default registry with all shadcn/ui components
|
||||
- **Third-Party Registries** - Any registry following the shadcn registry specification
|
||||
- **Private Registries** - Your company's internal component libraries
|
||||
- **Namespaced Registries** - Multiple registries configured with `@namespace` syntax
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
You can use any MCP client to interact with the shadcn MCP server. Here are the instructions for the most popular ones.
|
||||
|
||||
### Claude Code
|
||||
|
||||
To use the shadcn MCP server with Claude Code, add the following configuration to your project's `.mcp.json` file:
|
||||
|
||||
```json title=".mcp.json" showLineNumbers
|
||||
{
|
||||
"mcpServers": {
|
||||
"shadcn": {
|
||||
"command": "npx",
|
||||
"args": ["shadcn@latest", "mcp"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
After adding the configuration, restart Claude Code and run `/mcp` to see the shadcn MCP server in the list. If you see `Connected`, you're good to go.
|
||||
|
||||
See the [Claude Code MCP documentation](https://code.claude.com/docs/en/mcp) for more details.
|
||||
|
||||
### Cursor
|
||||
|
||||
To configure MCP in Cursor, add the shadcn server to your project's `.cursor/mcp.json` configuration file:
|
||||
|
||||
```json title=".cursor/mcp.json" showLineNumbers
|
||||
{
|
||||
"mcpServers": {
|
||||
"shadcn": {
|
||||
"command": "npx",
|
||||
"args": ["shadcn@latest", "mcp"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
After adding the configuration, enable the shadcn MCP server in Cursor Settings.
|
||||
|
||||
Once enabled, you should see a green dot next to the shadcn server in the MCP server list and a list of available tools.
|
||||
|
||||
See the [Cursor MCP documentation](https://docs.cursor.com/en/context/mcp#using-mcp-json) for more details.
|
||||
|
||||
### VS Code
|
||||
|
||||
To configure MCP in VS Code with GitHub Copilot, add the shadcn server to your project's `.vscode/mcp.json` configuration file:
|
||||
|
||||
```json title=".vscode/mcp.json" showLineNumbers
|
||||
{
|
||||
"servers": {
|
||||
"shadcn": {
|
||||
"command": "npx",
|
||||
"args": ["shadcn@latest", "mcp"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
After adding the configuration, open `.vscode/mcp.json` and click **Start** next to the shadcn server.
|
||||
|
||||
See the [VS Code MCP documentation](https://code.visualstudio.com/docs/copilot/chat/mcp-servers) for more details.
|
||||
|
||||
### Codex
|
||||
|
||||
<Callout>
|
||||
**Note:** The `shadcn` CLI cannot automatically update `~/.codex/config.toml`.
|
||||
You'll need to add the configuration manually.
|
||||
</Callout>
|
||||
|
||||
To configure MCP in Codex, add the shadcn server to `~/.codex/config.toml`:
|
||||
|
||||
```toml title="~/.codex/config.toml" showLineNumbers
|
||||
[mcp_servers.shadcn]
|
||||
command = "npx"
|
||||
args = ["shadcn@latest", "mcp"]
|
||||
```
|
||||
|
||||
After adding the configuration, restart Codex to load the MCP server.
|
||||
|
||||
---
|
||||
|
||||
## Configuring Registries
|
||||
|
||||
The MCP server supports multiple registries through your project's `components.json` configuration. This allows you to access components from various sources including private registries and third-party providers.
|
||||
|
||||
Configure additional registries in your `components.json`:
|
||||
|
||||
```json title="components.json" showLineNumbers
|
||||
{
|
||||
"registries": {
|
||||
"@acme": "https://registry.acme.com/{name}.json",
|
||||
"@internal": {
|
||||
"url": "https://internal.company.com/{name}.json",
|
||||
"headers": {
|
||||
"Authorization": "Bearer ${REGISTRY_TOKEN}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<Callout>
|
||||
**Note:** No configuration is needed to access the standard shadcn/ui
|
||||
registry.
|
||||
</Callout>
|
||||
|
||||
---
|
||||
|
||||
## Authentication
|
||||
|
||||
For private registries requiring authentication, set environment variables in your `.env.local`:
|
||||
|
||||
```bash title=".env.local"
|
||||
REGISTRY_TOKEN=your_token_here
|
||||
API_KEY=your_api_key_here
|
||||
```
|
||||
|
||||
For more details on registry authentication, see the [Authentication documentation](/docs/registry/authentication).
|
||||
|
||||
---
|
||||
|
||||
## Example Prompts
|
||||
|
||||
Once the MCP server is configured, you can use natural language to interact with registries. Try one of the following prompts:
|
||||
|
||||
### Browse & Search
|
||||
|
||||
- Show me all available components in the shadcn registry
|
||||
- Find me a login form from the shadcn registry
|
||||
|
||||
### Install Items
|
||||
|
||||
- Add the button component to my project
|
||||
- Create a login form using shadcn components
|
||||
- Install the Cursor rules from the acme registry
|
||||
|
||||
### Work with Namespaces
|
||||
|
||||
- Show me components from acme registry
|
||||
- Install @internal/auth-form
|
||||
- Build me a landing page using hero, features and testimonials sections from the acme registry
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### MCP Not Responding
|
||||
|
||||
If the MCP server isn't responding to prompts:
|
||||
|
||||
1. **Check Configuration** - Verify the MCP server is properly configured and enabled in your MCP client
|
||||
2. **Restart MCP Client** - Restart your MCP client after configuration changes
|
||||
3. **Verify Installation** - Ensure `shadcn` is installed in your project
|
||||
4. **Check Network** - Confirm you can access the configured registries
|
||||
|
||||
### Registry Access Issues
|
||||
|
||||
If components aren't loading from registries:
|
||||
|
||||
1. **Check components.json** - Verify registry URLs are correct
|
||||
2. **Test Authentication** - Ensure environment variables are set for private registries
|
||||
3. **Verify Registry** - Confirm the registry is online and accessible
|
||||
4. **Check Namespace** - Ensure namespace syntax is correct (`@namespace/component`)
|
||||
|
||||
### Installation Failures
|
||||
|
||||
If components fail to install:
|
||||
|
||||
1. **Check Project Setup** - Ensure you have a valid `components.json` file
|
||||
2. **Verify Paths** - Confirm the target directories exist
|
||||
3. **Check Permissions** - Ensure write permissions for component directories
|
||||
4. **Review Dependencies** - Check that required dependencies are installed
|
||||
|
||||
### No Tools or Prompts
|
||||
|
||||
If you see the `No tools or prompts` message, try the following:
|
||||
|
||||
1. **Clear the npx cache** - Run `npx clear-npx-cache`
|
||||
2. **Re-enable the MCP server** - Try to re-enable the MCP server in your MCP client
|
||||
3. **Check Logs** - In Cursor, you can see the logs under View -> Output and select `MCP: project-*` in the dropdown.
|
||||
|
||||
---
|
||||
|
||||
## Learn More
|
||||
|
||||
- [Registry Documentation](/docs/registry) - Complete guide to shadcn registries
|
||||
- [Namespaces](/docs/registry/namespace) - Configure multiple registry sources
|
||||
- [Authentication](/docs/registry/authentication) - Secure your private registries
|
||||
- [MCP Specification](https://modelcontextprotocol.io) - Learn about Model Context Protocol
|
||||
24
apps/v4/content/docs/(root)/meta.json
Normal file
24
apps/v4/content/docs/(root)/meta.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"title": "Get Started",
|
||||
"pages": [
|
||||
"index",
|
||||
"[Installation](/docs/installation)",
|
||||
"components-json",
|
||||
"package-imports",
|
||||
"theming",
|
||||
"typeset",
|
||||
"[Dark Mode](/docs/dark-mode)",
|
||||
"[RTL](/docs/rtl)",
|
||||
"[CLI](/docs/cli)",
|
||||
"monorepo",
|
||||
"skills",
|
||||
"javascript",
|
||||
"blocks",
|
||||
"figma",
|
||||
"[Changelog](/docs/changelog)",
|
||||
"[llms.txt](/llms.txt)",
|
||||
"legacy",
|
||||
"!official",
|
||||
"!new"
|
||||
]
|
||||
}
|
||||
254
apps/v4/content/docs/(root)/monorepo.mdx
Normal file
254
apps/v4/content/docs/(root)/monorepo.mdx
Normal file
@@ -0,0 +1,254 @@
|
||||
---
|
||||
title: Monorepo
|
||||
description: Using shadcn/ui components and CLI in a monorepo.
|
||||
---
|
||||
|
||||
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.
|
||||
|
||||
## Getting started
|
||||
|
||||
<Steps>
|
||||
|
||||
### Create a new monorepo project
|
||||
|
||||
To create a new monorepo project, run the `init` command with the `--monorepo` flag.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest init --monorepo
|
||||
```
|
||||
|
||||
Then select the template you want to use.
|
||||
|
||||
```bash
|
||||
? Select a template ›
|
||||
❯ Next.js
|
||||
Vite
|
||||
TanStack Start
|
||||
React Router
|
||||
Astro
|
||||
```
|
||||
|
||||
This will create a new monorepo project with two workspaces: `web` and `ui`,
|
||||
and [Turborepo](https://turbo.build/repo/docs) as the build system.
|
||||
|
||||
Everything is set up for you, so you can start adding components to your project.
|
||||
|
||||
### Add components to your project
|
||||
|
||||
To add components to your project, run the `add` command **in the path of your app**.
|
||||
|
||||
```bash
|
||||
cd apps/web
|
||||
```
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add [COMPONENT]
|
||||
```
|
||||
|
||||
The CLI will figure out what type of component you are adding and install the
|
||||
correct files to the correct path.
|
||||
|
||||
For example, if you run `npx shadcn@latest add button`, the CLI will install the button component under `packages/ui` and update the import path for components in `apps/web`.
|
||||
|
||||
If you run `npx shadcn@latest add login-01`, the CLI will install the `button`, `label`, `input` and `card` components under `packages/ui` and the `login-form` component under `apps/web/components`.
|
||||
|
||||
### Importing components
|
||||
|
||||
You can import components from the `@workspace/ui` package as follows:
|
||||
|
||||
```tsx
|
||||
import { Button } from "@workspace/ui/components/button"
|
||||
```
|
||||
|
||||
You can also import hooks and utilities from the `@workspace/ui` package.
|
||||
|
||||
```tsx
|
||||
import { useTheme } from "@workspace/ui/hooks/use-theme"
|
||||
import { cn } from "@workspace/ui/lib/utils"
|
||||
```
|
||||
|
||||
</Steps>
|
||||
|
||||
## File Structure
|
||||
|
||||
When you create a new monorepo project, the CLI will create the following file structure:
|
||||
|
||||
```txt
|
||||
apps
|
||||
└── web # Your app goes here.
|
||||
├── app
|
||||
│ └── page.tsx
|
||||
├── components
|
||||
│ └── login-form.tsx
|
||||
├── components.json
|
||||
└── package.json
|
||||
packages
|
||||
└── ui # Your components and dependencies are installed here.
|
||||
├── src
|
||||
│ ├── components
|
||||
│ │ └── button.tsx
|
||||
│ ├── hooks
|
||||
│ ├── lib
|
||||
│ │ └── utils.ts
|
||||
│ └── styles
|
||||
│ └── globals.css
|
||||
├── components.json
|
||||
└── package.json
|
||||
package.json
|
||||
turbo.json
|
||||
```
|
||||
|
||||
## Requirements
|
||||
|
||||
1. Every workspace must have a `components.json` file. A `package.json` file tells npm how to install the dependencies. A `components.json` file tells the CLI how and where to install components.
|
||||
|
||||
2. The `components.json` file must properly define aliases for the workspace. This tells the CLI how to import components, hooks, utilities, etc.
|
||||
|
||||
```json showLineNumbers title="apps/web/components.json"
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema.json",
|
||||
"style": "base-nova",
|
||||
"rsc": true,
|
||||
"tsx": true,
|
||||
"tailwind": {
|
||||
"config": "",
|
||||
"css": "../../packages/ui/src/styles/globals.css",
|
||||
"baseColor": "neutral",
|
||||
"cssVariables": true
|
||||
},
|
||||
"iconLibrary": "lucide",
|
||||
"aliases": {
|
||||
"components": "@/components",
|
||||
"hooks": "@/hooks",
|
||||
"lib": "@/lib",
|
||||
"utils": "@workspace/ui/lib/utils",
|
||||
"ui": "@workspace/ui/components"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json showLineNumbers title="packages/ui/components.json"
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema.json",
|
||||
"style": "base-nova",
|
||||
"rsc": true,
|
||||
"tsx": true,
|
||||
"tailwind": {
|
||||
"config": "",
|
||||
"css": "src/styles/globals.css",
|
||||
"baseColor": "neutral",
|
||||
"cssVariables": true
|
||||
},
|
||||
"iconLibrary": "lucide",
|
||||
"aliases": {
|
||||
"components": "@workspace/ui/components",
|
||||
"utils": "@workspace/ui/lib/utils",
|
||||
"hooks": "@workspace/ui/hooks",
|
||||
"lib": "@workspace/ui/lib",
|
||||
"ui": "@workspace/ui/components"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. Ensure you have the same `style`, `iconLibrary` and `baseColor` in both `components.json` files.
|
||||
|
||||
4. **For Tailwind CSS v4, leave the `tailwind` config empty in the `components.json` file.**
|
||||
|
||||
By following these requirements, the CLI will be able to install ui components, blocks, libs and hooks to the correct paths and handle imports for you.
|
||||
|
||||
<Callout className="mt-6">
|
||||
`package.json#imports` works well for package-local aliases inside a
|
||||
workspace, for example inside `packages/ui`. For shared workspace imports such
|
||||
as `@workspace/ui/components`, keep explicit aliases in `components.json`. The
|
||||
CLI uses those aliases to route files across workspace boundaries.
|
||||
</Callout>
|
||||
|
||||
## Using `package.json#imports`
|
||||
|
||||
For a monorepo that uses package imports and does not rely on
|
||||
`tsconfig.json` `paths`, use:
|
||||
|
||||
- local `#...` aliases for files inside each workspace
|
||||
- workspace package `exports` for shared imports such as
|
||||
`@workspace/ui/components`
|
||||
|
||||
For example, an app workspace can use local package imports:
|
||||
|
||||
```json showLineNumbers title="apps/web/package.json"
|
||||
{
|
||||
"name": "web",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"imports": {
|
||||
"#components/*": "./src/components/*.tsx",
|
||||
"#lib/*": "./src/lib/*.ts",
|
||||
"#hooks/*": "./src/hooks/*.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@workspace/ui": "workspace:*"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json showLineNumbers title="apps/web/components.json"
|
||||
{
|
||||
"aliases": {
|
||||
"components": "#components",
|
||||
"ui": "@workspace/ui/components",
|
||||
"lib": "#lib",
|
||||
"hooks": "#hooks",
|
||||
"utils": "@workspace/ui/lib/utils"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
And the shared UI package can expose its install targets with `exports`:
|
||||
|
||||
```json showLineNumbers title="packages/ui/package.json"
|
||||
{
|
||||
"name": "@workspace/ui",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"imports": {
|
||||
"#components/*": "./src/components/*.tsx",
|
||||
"#lib/*": "./src/lib/*.ts",
|
||||
"#hooks/*": "./src/hooks/*.ts"
|
||||
},
|
||||
"exports": {
|
||||
"./globals.css": "./src/styles/globals.css",
|
||||
"./components/*": "./src/components/*.tsx",
|
||||
"./lib/*": "./src/lib/*.ts",
|
||||
"./hooks/*": "./src/hooks/*.ts"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json showLineNumbers title="packages/ui/components.json"
|
||||
{
|
||||
"aliases": {
|
||||
"components": "#components",
|
||||
"ui": "#components",
|
||||
"lib": "#lib",
|
||||
"hooks": "#hooks",
|
||||
"utils": "#lib/utils"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In this setup:
|
||||
|
||||
- files added from the app to the shared UI package are routed through
|
||||
`@workspace/ui/...`
|
||||
- files added inside `packages/ui` use the package-local `#...` aliases
|
||||
- the shared package must export any path referenced by another workspace
|
||||
|
||||
For framework-specific package import setup, see the [package imports guide](/docs/package-imports).
|
||||
106
apps/v4/content/docs/(root)/new.mdx
Normal file
106
apps/v4/content/docs/(root)/new.mdx
Normal file
@@ -0,0 +1,106 @@
|
||||
---
|
||||
title: Your project is ready!
|
||||
description: You've created a new project with shadcn/ui.
|
||||
---
|
||||
|
||||
Here are a few things you can do to get started building with shadcn/ui.
|
||||
|
||||
## Add Components
|
||||
|
||||
Use the CLI to add components to your project.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add button
|
||||
```
|
||||
|
||||
Then import and use it in your code.
|
||||
|
||||
```tsx title="app/page.tsx"
|
||||
import { Button } from "@/components/ui/button"
|
||||
|
||||
export default function Home() {
|
||||
return <Button>Click me</Button>
|
||||
}
|
||||
```
|
||||
|
||||
Unlike traditional component libraries, shadcn/ui adds the component source code directly to your project under `components/ui/`. You own the code and can customize it however you want.
|
||||
|
||||
You can add multiple components at once or add all available components.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add button card input label
|
||||
```
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add --all
|
||||
```
|
||||
|
||||
Browse all components on the [Components](/docs/components) page.
|
||||
|
||||
## Customize Your Theme
|
||||
|
||||
You can edit your theme directly in your CSS file. Learn more about [Theming](/docs/theming) and how to use CSS variables or utility classes.
|
||||
|
||||
If you want to try a new preset, you can create a custom theme visually on [ui.shadcn.com](https://ui.shadcn.com) and apply it to your project using a preset code.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest init --preset [CODE]
|
||||
```
|
||||
|
||||
## Add a block
|
||||
|
||||
You can add a block to your project using the CLI.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add login-03
|
||||
```
|
||||
|
||||
This will add the `login-03` block to your project. Import and use it in your code.
|
||||
|
||||
```tsx title="app/page.tsx"
|
||||
import { Login03 } from "@/components/login-03"
|
||||
|
||||
export default function Home() {
|
||||
return <Login03 />
|
||||
}
|
||||
```
|
||||
|
||||
## Install from Registries
|
||||
|
||||
shadcn/ui has a growing ecosystem of community registries. You can install components from any registry URL using the CLI.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add @[registry]/[name]
|
||||
```
|
||||
|
||||
Browse the [Registry Directory](/docs/directory) for a list of available registries.
|
||||
|
||||
## Use AI to Build
|
||||
|
||||
shadcn/ui is designed to work with AI. Your AI assistant can read the component source code in your project, understand the APIs, and compose them together to build pages and features.
|
||||
|
||||
Here are some example prompts to try:
|
||||
|
||||
- _"Create a signup page with a form for entering name, email and password."_
|
||||
- _"Create a settings page with a form for updating profile information."_
|
||||
- _"Build a dashboard with a header, stats cards, and a data table."_
|
||||
|
||||
## Install the shadcn Skills
|
||||
|
||||
Install the shadcn skill in your AI assistant. This will give your AI assistant access to the full component registry, documentation, and search.
|
||||
|
||||
```bash
|
||||
npx skills add shadcn/ui
|
||||
```
|
||||
|
||||
Learn more about [skills](/docs/skills).
|
||||
|
||||
## Connect the MCP Server
|
||||
|
||||
The shadcn MCP server gives your AI assistant access to the full component registry, documentation, and search. Connect it in your editor for the best experience.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest mcp init
|
||||
```
|
||||
|
||||
Learn more on the [MCP Server](/docs/mcp) page.
|
||||
19
apps/v4/content/docs/(root)/official.mdx
Normal file
19
apps/v4/content/docs/(root)/official.mdx
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
title: Official shadcn/ui Website
|
||||
description: The official website for shadcn/ui is ui.shadcn.com. Verify the documentation, source code, CLI, packages, and social accounts maintained by the project.
|
||||
---
|
||||
|
||||
The official website for shadcn/ui is [ui.shadcn.com](https://ui.shadcn.com).
|
||||
|
||||
## Official resources
|
||||
|
||||
- **Website:** [ui.shadcn.com](https://ui.shadcn.com) is the official website and component documentation.
|
||||
- **Source code:** [github.com/shadcn-ui/ui](https://github.com/shadcn-ui/ui) is the official source repository for shadcn/ui and the CLI.
|
||||
- **CLI package:** [npmjs.com/package/shadcn](https://www.npmjs.com/package/shadcn) is the official `shadcn` package published on npm.
|
||||
- **Project updates:** [@shadcn](https://twitter.com/shadcn) publishes official announcements and project updates.
|
||||
|
||||
## Third-party resources
|
||||
|
||||
Community websites and registries may use shadcn/ui components or the shadcn CLI, but they are independent unless they are explicitly identified as maintained by shadcn/ui on this page.
|
||||
|
||||
Review third-party code before installing it in your project. Browse community-maintained registries in the official [Registry Directory](/docs/directory).
|
||||
234
apps/v4/content/docs/(root)/package-imports.mdx
Normal file
234
apps/v4/content/docs/(root)/package-imports.mdx
Normal file
@@ -0,0 +1,234 @@
|
||||
---
|
||||
title: Package Imports
|
||||
description: Configure shadcn/ui with package.json imports.
|
||||
---
|
||||
|
||||
The `shadcn` CLI supports [package imports](https://nodejs.org/api/packages.html#imports)
|
||||
for installing components, rewriting imports, and resolving third-party
|
||||
registries.
|
||||
|
||||
Package imports let you use private `#...` import aliases from your
|
||||
`package.json` instead of `compilerOptions.paths` in `tsconfig.json`.
|
||||
|
||||
## Example
|
||||
|
||||
You configure `imports` in your `package.json`:
|
||||
|
||||
```json title="package.json" showLineNumbers
|
||||
{
|
||||
"imports": {
|
||||
"#components/*": "./src/components/*.tsx",
|
||||
"#lib/*": "./src/lib/*.ts",
|
||||
"#hooks/*": "./src/hooks/*.ts"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Then import generated components using `#...` specifiers:
|
||||
|
||||
```tsx
|
||||
import { Button } from "#components/ui/button"
|
||||
import { cn } from "#lib/utils"
|
||||
```
|
||||
|
||||
<Callout className="mt-6">
|
||||
Package import specifiers must start with `#`. Use TypeScript 5 or later with
|
||||
`moduleResolution: "bundler"` and `resolvePackageJsonImports: true`.
|
||||
</Callout>
|
||||
|
||||
## App
|
||||
|
||||
For Next.js, Vite, and TanStack Start apps that install
|
||||
components into the same workspace.
|
||||
|
||||
<Steps>
|
||||
|
||||
### Configure `package.json`
|
||||
|
||||
Add imports for the shadcn/ui install targets.
|
||||
|
||||
```json title="package.json" showLineNumbers
|
||||
{
|
||||
"imports": {
|
||||
"#components/*": "./src/components/*.tsx",
|
||||
"#lib/*": "./src/lib/*.ts",
|
||||
"#hooks/*": "./src/hooks/*.ts"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If your app does not use a `src` directory, remove `src/` from the targets. For
|
||||
example:
|
||||
|
||||
```json title="package.json" showLineNumbers
|
||||
{
|
||||
"imports": {
|
||||
"#components/*": "./components/*.tsx",
|
||||
"#lib/*": "./lib/*.ts",
|
||||
"#hooks/*": "./hooks/*.ts"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Configure TypeScript
|
||||
|
||||
Enable package import resolution.
|
||||
|
||||
```json title="tsconfig.json" showLineNumbers
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "bundler",
|
||||
"resolvePackageJsonImports": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You do not need `compilerOptions.paths` for these aliases.
|
||||
|
||||
### Configure `components.json`
|
||||
|
||||
Use the same `#...` roots in `components.json`.
|
||||
|
||||
```json title="components.json" showLineNumbers
|
||||
{
|
||||
"aliases": {
|
||||
"components": "#components",
|
||||
"ui": "#components/ui",
|
||||
"lib": "#lib",
|
||||
"hooks": "#hooks",
|
||||
"utils": "#lib/utils"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The `ui` alias uses `#components/ui`. It is still covered by the
|
||||
`#components/*` import in `package.json`.
|
||||
|
||||
The `utils` alias uses `#lib/utils`. It is covered by `#lib/*`, so you do not
|
||||
need a separate `#utils` import.
|
||||
|
||||
</Steps>
|
||||
|
||||
## Monorepo
|
||||
|
||||
In a monorepo, use package imports for files inside each package and package
|
||||
exports for files shared across workspaces.
|
||||
|
||||
For an app workspace:
|
||||
|
||||
```json title="apps/web/package.json" showLineNumbers
|
||||
{
|
||||
"name": "web",
|
||||
"private": true,
|
||||
"imports": {
|
||||
"#components/*": "./src/components/*.tsx",
|
||||
"#lib/*": "./src/lib/*.ts",
|
||||
"#hooks/*": "./src/hooks/*.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@workspace/ui": "workspace:*"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json title="apps/web/components.json" showLineNumbers
|
||||
{
|
||||
"aliases": {
|
||||
"components": "#components",
|
||||
"ui": "@workspace/ui/components",
|
||||
"lib": "#lib",
|
||||
"hooks": "#hooks",
|
||||
"utils": "@workspace/ui/lib/utils"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
For the shared UI package:
|
||||
|
||||
```json title="packages/ui/package.json" showLineNumbers
|
||||
{
|
||||
"name": "@workspace/ui",
|
||||
"private": true,
|
||||
"imports": {
|
||||
"#components/*": "./src/components/*.tsx",
|
||||
"#lib/*": "./src/lib/*.ts",
|
||||
"#hooks/*": "./src/hooks/*.ts"
|
||||
},
|
||||
"exports": {
|
||||
"./globals.css": "./src/styles/globals.css",
|
||||
"./components/*": "./src/components/*.tsx",
|
||||
"./lib/*": "./src/lib/*.ts",
|
||||
"./hooks/*": "./src/hooks/*.ts"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json title="packages/ui/components.json" showLineNumbers
|
||||
{
|
||||
"aliases": {
|
||||
"components": "#components",
|
||||
"ui": "#components",
|
||||
"lib": "#lib",
|
||||
"hooks": "#hooks",
|
||||
"utils": "#lib/utils"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
When you run `add` from `apps/web`, app-local files use `#...` imports and
|
||||
shared UI files are imported from `@workspace/ui`.
|
||||
|
||||
```tsx
|
||||
import { Button } from "@workspace/ui/components/button"
|
||||
import { LoginForm } from "#components/login-form"
|
||||
```
|
||||
|
||||
## File extensions
|
||||
|
||||
The target pattern in `package.json#imports` controls whether generated imports
|
||||
include file extensions.
|
||||
|
||||
```json title="package.json" showLineNumbers
|
||||
{
|
||||
"imports": {
|
||||
"#components/*": "./src/components/*.tsx"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This generates imports without extensions:
|
||||
|
||||
```tsx
|
||||
import { Button } from "#components/ui/button"
|
||||
```
|
||||
|
||||
If you use a target without the extension:
|
||||
|
||||
```json title="package.json" showLineNumbers
|
||||
{
|
||||
"imports": {
|
||||
"#components/*": "./src/components/*"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The generated import keeps the source extension:
|
||||
|
||||
```tsx
|
||||
import { Button } from "#components/ui/button.tsx"
|
||||
```
|
||||
|
||||
For most apps, use the extension in the target pattern.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If TypeScript cannot resolve a `#...` import, check that:
|
||||
|
||||
- the specifier starts with `#`
|
||||
- the `imports` entry is in the nearest `package.json`
|
||||
- `moduleResolution` is set to `bundler`
|
||||
- `resolvePackageJsonImports` is enabled
|
||||
- the matching target exists after components are added
|
||||
|
||||
If a component is installed but imports still point to `@/...`, check that
|
||||
`components.json` uses the same `#...` aliases as your package imports.
|
||||
166
apps/v4/content/docs/(root)/react-19.mdx
Normal file
166
apps/v4/content/docs/(root)/react-19.mdx
Normal file
@@ -0,0 +1,166 @@
|
||||
---
|
||||
title: Next.js 15 + React 19
|
||||
description: Using shadcn/ui with Next.js 15 and React 19.
|
||||
---
|
||||
|
||||
<Callout className="">
|
||||
**Update:** We have added full support for React 19 and Tailwind v4 in the
|
||||
`latest` release. **This guide might be outdated. Proceed with caution.**
|
||||
</Callout>
|
||||
|
||||
## TL;DR
|
||||
|
||||
If you're using `npm`, you can install shadcn/ui dependencies with a flag. The `shadcn` CLI will prompt you to select a flag when you run it. No flags required for pnpm, bun, or yarn.
|
||||
|
||||
See [Upgrade Status](#upgrade-status) for the status of React 19 support for each package.
|
||||
|
||||
## What's happening?
|
||||
|
||||
React 19 is now [rc](https://www.npmjs.com/package/react?activeTab=versions) and is [tested and supported in the latest Next.js 15 release](https://nextjs.org/blog/next-15#react-19).
|
||||
|
||||
To support React 19, package maintainers will need to test and update their packages to include React 19 as a peer dependency. This is [already](https://github.com/radix-ui/primitives/pull/2952) [in](https://github.com/pacocoursey/cmdk/pull/318) [progress](https://github.com/emilkowalski/vaul/pull/498).
|
||||
|
||||
```diff /^19.0/
|
||||
"peerDependencies": {
|
||||
- "react": "^16.8 || ^17.0 || ^18.0",
|
||||
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0",
|
||||
- "react-dom": "^16.8 || ^17.0 || ^18.0"
|
||||
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0"
|
||||
},
|
||||
```
|
||||
|
||||
<Callout>
|
||||
You can check if a package lists React 19 as a peer dependency by running
|
||||
`npm info <package> peerDependencies`.
|
||||
</Callout>
|
||||
|
||||
In the meantime, if you are installing a package that **does not** list React 19 as a peer dependency, you will see an error message like this:
|
||||
|
||||
```bash
|
||||
npm error code ERESOLVE
|
||||
npm error ERESOLVE unable to resolve dependency tree
|
||||
npm error
|
||||
npm error While resolving: my-app@0.1.0
|
||||
npm error Found: react@19.0.0-rc-69d4b800-20241021
|
||||
npm error node_modules/react
|
||||
npm error react@"19.0.0-rc-69d4b800-20241021" from the root project
|
||||
```
|
||||
|
||||
<Callout>
|
||||
**Note:** This is npm only. PNPM and Bun will only show a silent warning.
|
||||
</Callout>
|
||||
|
||||
## How to fix this
|
||||
|
||||
### Solution 1: `--force` or `--legacy-peer-deps`
|
||||
|
||||
You can force install a package with the `--force` or the `--legacy-peer-deps` flag.
|
||||
|
||||
```bash
|
||||
npm i <package> --force
|
||||
|
||||
npm i <package> --legacy-peer-deps
|
||||
```
|
||||
|
||||
This will install the package and ignore the peer dependency warnings.
|
||||
|
||||
<Accordion type="multiple">
|
||||
<AccordionItem value="flags">
|
||||
<AccordionTrigger className="font-medium">
|
||||
What do the `--force` and `--legacy-peer-deps` flag do?
|
||||
</AccordionTrigger>
|
||||
<AccordionContent className="[&_ul]:mt-0">
|
||||
|
||||
- `--force`: Ignores and overrides any dependency conflicts, forcing the
|
||||
installation of packages.
|
||||
- `--legacy-peer-deps`: Skips strict peer dependency checks, allowing
|
||||
installation of packages with unmet peer dependencies to avoid errors.
|
||||
|
||||
</AccordionContent>
|
||||
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
|
||||
### Solution 2: Use React 18
|
||||
|
||||
You can downgrade `react` and `react-dom` to version 18, which is compatible with the package you are installing and upgrade when the dependency is updated.
|
||||
|
||||
```bash
|
||||
npm i react@18 react-dom@18
|
||||
```
|
||||
|
||||
Whichever solution you choose, make sure you test your app thoroughly to ensure
|
||||
there are no regressions.
|
||||
|
||||
## Using shadcn/ui on Next.js 15
|
||||
|
||||
### Using pnpm, bun, or yarn
|
||||
|
||||
Follow the instructions in the [installation guide](/docs/installation/next) to install shadcn/ui. No flags are needed.
|
||||
|
||||
### Using npm
|
||||
|
||||
When you run `npx shadcn@latest init -d`, you will be prompted to select an option to resolve the peer dependency issues.
|
||||
|
||||
```bash
|
||||
It looks like you are using React 19.
|
||||
Some packages may fail to install due to peer dependency issues (see https://ui.shadcn.com/react-19).
|
||||
|
||||
? How would you like to proceed? › - Use arrow-keys. Return to submit.
|
||||
❯ Use --force
|
||||
Use --legacy-peer-deps
|
||||
```
|
||||
|
||||
You can then run the command with the flag you choose.
|
||||
|
||||
## Adding components
|
||||
|
||||
The process for adding components is the same as above. Select a flag to resolve the peer dependency issues.
|
||||
|
||||
**Remember to always test your app after installing new dependencies.**
|
||||
|
||||
## Upgrade Status
|
||||
|
||||
To make it easy for you to track the progress of the upgrade, here is a table with the React 19 support status for the shadcn/ui dependencies.
|
||||
|
||||
- ✅ - Works with React 19 using npm, pnpm, and bun.
|
||||
- 🚧 - Works with React 19 using pnpm and bun. Requires flag for npm. PR is in progress.
|
||||
|
||||
| Package | Status | Note |
|
||||
| ---------------------------------------------------------------------------------- | ------ | ----------------------------------------------------------- |
|
||||
| [radix-ui](https://www.npmjs.com/package/@radix-ui/react-icons) | ✅ | |
|
||||
| [lucide-react](https://www.npmjs.com/package/lucide-react) | ✅ | |
|
||||
| [class-variance-authority](https://www.npmjs.com/package/class-variance-authority) | ✅ | Does not list React 19 as a peer dependency. |
|
||||
| [tailwindcss-animate](https://www.npmjs.com/package/tailwindcss-animate) | ✅ | Does not list React 19 as a peer dependency. |
|
||||
| [embla-carousel-react](https://www.npmjs.com/package/embla-carousel-react) | ✅ | |
|
||||
| [recharts](https://www.npmjs.com/package/recharts) | ✅ | See note [below](#recharts) |
|
||||
| [react-hook-form](https://www.npmjs.com/package/react-hook-form) | ✅ | |
|
||||
| [react-resizable-panels](https://www.npmjs.com/package/react-resizable-panels) | ✅ | |
|
||||
| [sonner](https://www.npmjs.com/package/sonner) | ✅ | |
|
||||
| [react-day-picker](https://www.npmjs.com/package/react-day-picker) | ✅ | Works with flag for npm. Work to upgrade to v9 in progress. |
|
||||
| [input-otp](https://www.npmjs.com/package/input-otp) | ✅ | |
|
||||
| [vaul](https://www.npmjs.com/package/vaul) | ✅ | |
|
||||
| [@radix-ui/react-icons](https://www.npmjs.com/package/@radix-ui/react-icons) | ✅ | See [PR #194](https://github.com/radix-ui/icons/pull/194) |
|
||||
| [cmdk](https://www.npmjs.com/package/cmdk) | ✅ | |
|
||||
|
||||
If you have any questions, please [open an issue](https://github.com/shadcn/ui/issues) on GitHub.
|
||||
|
||||
## Recharts
|
||||
|
||||
To use recharts with React 19, you will need to override the `react-is` dependency.
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>Add the following to your `package.json`</Step>
|
||||
|
||||
```json title="package.json"
|
||||
"overrides": {
|
||||
"react-is": "^19.0.0-rc-69d4b800-20241021"
|
||||
}
|
||||
```
|
||||
|
||||
Note: the `react-is` version needs to match the version of React 19 you are using. The above is an example.
|
||||
|
||||
<Step>Run `npm install --legacy-peer-deps`</Step>
|
||||
|
||||
</Steps>
|
||||
71
apps/v4/content/docs/(root)/skills.mdx
Normal file
71
apps/v4/content/docs/(root)/skills.mdx
Normal file
@@ -0,0 +1,71 @@
|
||||
---
|
||||
title: Skills
|
||||
description: Give your AI assistant deep knowledge of shadcn/ui components, patterns, and best practices.
|
||||
---
|
||||
|
||||
Skills give AI assistants like Claude Code project-aware context about shadcn/ui. When installed, your AI assistant knows how to find, install, compose, and customize components using the correct APIs and patterns for your project.
|
||||
|
||||
For example, you can ask your AI assistant to:
|
||||
|
||||
- _"Add a login form with email and password fields."_
|
||||
- _"Create a settings page with a form for updating profile information."_
|
||||
- _"Build a dashboard with a sidebar, stats cards, and a data table."_
|
||||
- _"Switch to --preset [CODE]"_
|
||||
- _"Can you add a hero from @tailark?"_
|
||||
|
||||
The skill reads your project's `components.json` and provides the assistant with your framework, aliases, installed components, icon library, and base library so it can generate correct code on the first try.
|
||||
|
||||
---
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npx skills add shadcn/ui
|
||||
```
|
||||
|
||||
This installs the shadcn skill into your project. Once installed, your AI assistant automatically loads it when working with shadcn/ui components.
|
||||
|
||||
Learn more about skills at [skills.sh](https://skills.sh).
|
||||
|
||||
---
|
||||
|
||||
## What's Included
|
||||
|
||||
The skill provides your AI assistant with the following knowledge:
|
||||
|
||||
### Project Context
|
||||
|
||||
On every interaction, the skill runs `shadcn info --json` to get your project's configuration: framework, Tailwind version, aliases, base library (`base`, `radix`, or `aria`), icon library, installed components, and resolved file paths.
|
||||
|
||||
### CLI Commands
|
||||
|
||||
Full reference for all CLI commands: `init`, `add`, `search`, `view`, `docs`, `diff`, `info`, and `build`. Includes flags, dry-run mode, smart merge workflows, presets, and templates.
|
||||
|
||||
### Theming and Customization
|
||||
|
||||
How CSS variables, OKLCH colors, dark mode, custom colors, border radius, and component variants work. Includes guidance for both Tailwind v3 and v4.
|
||||
|
||||
### Registry Authoring
|
||||
|
||||
How to build and publish custom component registries: `registry.json` format, item types, file objects, dependencies, CSS variables, building, hosting, and user configuration.
|
||||
|
||||
### MCP Server
|
||||
|
||||
Setup and tools for the shadcn MCP server, which lets AI assistants search, browse, and install components from registries.
|
||||
|
||||
---
|
||||
|
||||
## How It Works
|
||||
|
||||
1. **Project detection** — The skill activates when it finds a `components.json` file in your project.
|
||||
2. **Context injection** — It runs `shadcn info --json` to read your project configuration and injects the result into the assistant's context.
|
||||
3. **Pattern enforcement** — The assistant follows shadcn/ui composition rules: using `FieldGroup` for forms, `ToggleGroup` for option sets, semantic colors, and correct base-specific APIs.
|
||||
4. **Component discovery** — The assistant uses `shadcn docs`, `shadcn search`, or MCP tools to find components and their documentation before generating code.
|
||||
|
||||
## Learn More
|
||||
|
||||
- [CLI](/docs/cli) — Full CLI command reference
|
||||
- [MCP Server](/docs/mcp) — Connect the MCP server for registry access
|
||||
- [Theming](/docs/theming) — CSS variables and customization
|
||||
- [Registry](/docs/registry) — Building and publishing custom registries
|
||||
- [skills.sh](https://skills.sh) — Learn more about AI skills
|
||||
333
apps/v4/content/docs/(root)/tailwind-v4.mdx
Normal file
333
apps/v4/content/docs/(root)/tailwind-v4.mdx
Normal file
@@ -0,0 +1,333 @@
|
||||
---
|
||||
title: Tailwind v4
|
||||
description: How to use shadcn/ui with Tailwind v4 and React 19.
|
||||
---
|
||||
|
||||
It’s here! 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.
|
||||
|
||||
**Note: this is non-breaking. Your existing apps with Tailwind v3 and React 18 will still work. When you add new components, they'll still be in v3 and React 18 until you upgrade. Only new projects start with Tailwind v4 and React 19.**
|
||||
|
||||
## Try It Out
|
||||
|
||||
You can start using Tailwind v4 + React 19 today. See the framework specific guides below for how to get started.
|
||||
|
||||
<div className="mt-8 grid gap-4 sm:grid-cols-2 sm:gap-6">
|
||||
<LinkedCard href="/docs/installation/next">
|
||||
<svg
|
||||
role="img"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="h-10 w-10"
|
||||
fill="currentColor"
|
||||
>
|
||||
<title>Next.js</title>
|
||||
<path d="M11.5725 0c-.1763 0-.3098.0013-.3584.0067-.0516.0053-.2159.021-.3636.0328-3.4088.3073-6.6017 2.1463-8.624 4.9728C1.1004 6.584.3802 8.3666.1082 10.255c-.0962.659-.108.8537-.108 1.7474s.012 1.0884.108 1.7476c.652 4.506 3.8591 8.2919 8.2087 9.6945.7789.2511 1.6.4223 2.5337.5255.3636.04 1.9354.04 2.299 0 1.6117-.1783 2.9772-.577 4.3237-1.2643.2065-.1056.2464-.1337.2183-.1573-.0188-.0139-.8987-1.1938-1.9543-2.62l-1.919-2.592-2.4047-3.5583c-1.3231-1.9564-2.4117-3.556-2.4211-3.556-.0094-.0026-.0187 1.5787-.0235 3.509-.0067 3.3802-.0093 3.5162-.0516 3.596-.061.115-.108.1618-.2064.2134-.075.0374-.1408.0445-.495.0445h-.406l-.1078-.068a.4383.4383 0 01-.1572-.1712l-.0493-.1056.0053-4.703.0067-4.7054.0726-.0915c.0376-.0493.1174-.1125.1736-.143.0962-.047.1338-.0517.5396-.0517.4787 0 .5584.0187.6827.1547.0353.0377 1.3373 1.9987 2.895 4.3608a10760.433 10760.433 0 004.7344 7.1706l1.9002 2.8782.096-.0633c.8518-.5536 1.7525-1.3418 2.4657-2.1627 1.5179-1.7429 2.4963-3.868 2.8247-6.134.0961-.6591.1078-.854.1078-1.7475 0-.8937-.012-1.0884-.1078-1.7476-.6522-4.506-3.8592-8.2919-8.2087-9.6945-.7672-.2487-1.5836-.42-2.4985-.5232-.169-.0176-1.0835-.0366-1.6123-.037zm4.0685 7.217c.3473 0 .4082.0053.4857.047.1127.0562.204.1642.237.2767.0186.061.0234 1.3653.0186 4.3044l-.0067 4.2175-.7436-1.14-.7461-1.14v-3.066c0-1.982.0093-3.0963.0234-3.1502.0375-.1313.1196-.2346.2323-.2955.0961-.0494.1313-.054.4997-.054z" />
|
||||
</svg>
|
||||
<p className="mt-2 font-medium">Next.js</p>
|
||||
</LinkedCard>
|
||||
<LinkedCard href="/docs/installation/vite">
|
||||
<svg
|
||||
role="img"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="h-10 w-10"
|
||||
fill="currentColor"
|
||||
>
|
||||
<title>Vite</title>
|
||||
<path d="m8.286 10.578.512-8.657a.306.306 0 0 1 .247-.282L17.377.006a.306.306 0 0 1 .353.385l-1.558 5.403a.306.306 0 0 0 .352.385l2.388-.46a.306.306 0 0 1 .332.438l-6.79 13.55-.123.19a.294.294 0 0 1-.252.14c-.177 0-.35-.152-.305-.369l1.095-5.301a.306.306 0 0 0-.388-.355l-1.433.435a.306.306 0 0 1-.389-.354l.69-3.375a.306.306 0 0 0-.37-.36l-2.32.536a.306.306 0 0 1-.374-.316zm14.976-7.926L17.284 3.74l-.544 1.887 2.077-.4a.8.8 0 0 1 .84.369.8.8 0 0 1 .034.783L12.9 19.93l-.013.025-.015.023-.122.19a.801.801 0 0 1-.672.37.826.826 0 0 1-.634-.302.8.8 0 0 1-.16-.67l1.029-4.981-1.12.34a.81.81 0 0 1-.86-.262.802.802 0 0 1-.165-.67l.63-3.08-2.027.468a.808.808 0 0 1-.768-.233.81.81 0 0 1-.217-.6l.389-6.57-7.44-1.33a.612.612 0 0 0-.64.906L11.58 23.691a.612.612 0 0 0 1.066-.004l11.26-20.135a.612.612 0 0 0-.644-.9z" />
|
||||
</svg>
|
||||
<p className="mt-2 font-medium">Vite</p>
|
||||
</LinkedCard>
|
||||
<LinkedCard href="/docs/installation/laravel">
|
||||
<svg
|
||||
role="img"
|
||||
viewBox="0 0 62 65"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="h-10 w-10"
|
||||
>
|
||||
<path d="M61.8548 14.6253C61.8778 14.7102 61.8895 14.7978 61.8897 14.8858V28.5615C61.8898 28.737 61.8434 28.9095 61.7554 29.0614C61.6675 29.2132 61.5409 29.3392 61.3887 29.4265L49.9104 36.0351V49.1337C49.9104 49.4902 49.7209 49.8192 49.4118 49.9987L25.4519 63.7916C25.3971 63.8227 25.3372 63.8427 25.2774 63.8639C25.255 63.8714 25.2338 63.8851 25.2101 63.8913C25.0426 63.9354 24.8666 63.9354 24.6991 63.8913C24.6716 63.8838 24.6467 63.8689 24.6205 63.8589C24.5657 63.8389 24.5084 63.8215 24.456 63.7916L0.501061 49.9987C0.348882 49.9113 0.222437 49.7853 0.134469 49.6334C0.0465019 49.4816 0.000120578 49.3092 0 49.1337L0 8.10652C0 8.01678 0.0124642 7.92953 0.0348998 7.84477C0.0423783 7.8161 0.0598282 7.78993 0.0697995 7.76126C0.0884958 7.70891 0.105946 7.65531 0.133367 7.6067C0.152063 7.5743 0.179485 7.54812 0.20192 7.51821C0.230588 7.47832 0.256763 7.43719 0.290416 7.40229C0.319084 7.37362 0.356476 7.35243 0.388883 7.32751C0.425029 7.29759 0.457436 7.26518 0.498568 7.2415L12.4779 0.345059C12.6296 0.257786 12.8015 0.211853 12.9765 0.211853C13.1515 0.211853 13.3234 0.257786 13.475 0.345059L25.4531 7.2415H25.4556C25.4955 7.26643 25.5292 7.29759 25.5653 7.32626C25.5977 7.35119 25.6339 7.37362 25.6625 7.40104C25.6974 7.43719 25.7224 7.47832 25.7523 7.51821C25.7735 7.54812 25.8021 7.5743 25.8196 7.6067C25.8483 7.65656 25.8645 7.70891 25.8844 7.76126C25.8944 7.78993 25.9118 7.8161 25.9193 7.84602C25.9423 7.93096 25.954 8.01853 25.9542 8.10652V33.7317L35.9355 27.9844V14.8846C35.9355 14.7973 35.948 14.7088 35.9704 14.6253C35.9792 14.5954 35.9954 14.5692 36.0053 14.5405C36.0253 14.4882 36.0427 14.4346 36.0702 14.386C36.0888 14.3536 36.1163 14.3274 36.1375 14.2975C36.1674 14.2576 36.1923 14.2165 36.2272 14.1816C36.2559 14.1529 36.292 14.1317 36.3244 14.1068C36.3618 14.0769 36.3942 14.0445 36.4341 14.0208L48.4147 7.12434C48.5663 7.03694 48.7383 6.99094 48.9133 6.99094C49.0883 6.99094 49.2602 7.03694 49.4118 7.12434L61.3899 14.0208C61.4323 14.0457 61.4647 14.0769 61.5021 14.1055C61.5333 14.1305 61.5694 14.1529 61.5981 14.1803C61.633 14.2165 61.6579 14.2576 61.6878 14.2975C61.7103 14.3274 61.7377 14.3536 61.7551 14.386C61.7838 14.4346 61.8 14.4882 61.8199 14.5405C61.8312 14.5692 61.8474 14.5954 61.8548 14.6253ZM59.893 27.9844V16.6121L55.7013 19.0252L49.9104 22.3593V33.7317L59.8942 27.9844H59.893ZM47.9149 48.5566V37.1768L42.2187 40.4299L25.953 49.7133V61.2003L47.9149 48.5566ZM1.99677 9.83281V48.5566L23.9562 61.199V49.7145L12.4841 43.2219L12.4804 43.2194L12.4754 43.2169C12.4368 43.1945 12.4044 43.1621 12.3682 43.1347C12.3371 43.1097 12.3009 43.0898 12.2735 43.0624L12.271 43.0586C12.2386 43.0275 12.2162 42.9888 12.1887 42.9539C12.1638 42.9203 12.1339 42.8916 12.114 42.8567L12.1127 42.853C12.0903 42.8156 12.0766 42.7707 12.0604 42.7283C12.0442 42.6909 12.023 42.656 12.013 42.6161C12.0005 42.5688 11.998 42.5177 11.9931 42.4691C11.9881 42.4317 11.9781 42.3943 11.9781 42.3569V15.5801L6.18848 12.2446L1.99677 9.83281ZM12.9777 2.36177L2.99764 8.10652L12.9752 13.8513L22.9541 8.10527L12.9752 2.36177H12.9777ZM18.1678 38.2138L23.9574 34.8809V9.83281L19.7657 12.2459L13.9749 15.5801V40.6281L18.1678 38.2138ZM48.9133 9.14105L38.9344 14.8858L48.9133 20.6305L58.8909 14.8846L48.9133 9.14105ZM47.9149 22.3593L42.124 19.0252L37.9323 16.6121V27.9844L43.7219 31.3174L47.9149 33.7317V22.3593ZM24.9533 47.987L39.59 39.631L46.9065 35.4555L36.9352 29.7145L25.4544 36.3242L14.9907 42.3482L24.9533 47.987Z" />
|
||||
</svg>
|
||||
<p className="mt-2 font-medium">Laravel</p>
|
||||
</LinkedCard>
|
||||
<LinkedCard href="/docs/installation/react-router">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
className="h-10 w-10"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path d="M12.118 5.466a2.306 2.306 0 0 0-.623.08c-.278.067-.702.332-.953.583-.41.423-.49.609-.662 1.469-.08.423.41 1.43.847 1.734.45.317 1.085.502 2.065.608 1.429.16 1.84.636 1.84 2.197 0 1.377-.385 1.747-1.96 1.906-1.707.172-2.58.834-2.765 2.117-.106.781.41 1.76 1.125 2.091 1.627.768 3.15-.198 3.467-2.196.211-1.284.622-1.642 1.998-1.747 1.588-.133 2.409-.675 2.713-1.787.278-1.02-.304-2.157-1.297-2.554-.264-.106-.873-.238-1.35-.291-1.495-.16-1.879-.424-2.038-1.39-.225-1.337-.317-1.562-.794-2.09a2.174 2.174 0 0 0-1.613-.73zm-4.785 4.36a2.145 2.145 0 0 0-.497.048c-1.469.318-2.17 2.051-1.35 3.295 1.178 1.774 3.944.953 3.97-1.177.012-1.193-.98-2.143-2.123-2.166zM2.089 14.19a2.22 2.22 0 0 0-.427.052c-2.158.476-2.237 3.626-.106 4.182.53.145.582.145 1.111.013 1.191-.318 1.866-1.456 1.549-2.607-.278-1.02-1.144-1.664-2.127-1.64zm19.824.008c-.233.002-.477.058-.784.162-1.39.477-1.866 2.092-.98 3.336.557.794 1.96 1.058 2.82.516 1.416-.874 1.363-3.057-.093-3.746-.38-.186-.663-.271-.963-.268z" />
|
||||
</svg>
|
||||
<p className="mt-2 font-medium">React Router</p>
|
||||
</LinkedCard>
|
||||
<LinkedCard href="/docs/installation/astro">
|
||||
<svg
|
||||
role="img"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="h-10 w-10"
|
||||
fill="currentColor"
|
||||
>
|
||||
<title>Astro</title>
|
||||
<path
|
||||
d="M16.074 16.86C15.354 17.476 13.917 17.895 12.262 17.895C10.23 17.895 8.527 17.263 8.075 16.412C7.914 16.9 7.877 17.458 7.877 17.814C7.877 17.814 7.771 19.564 8.988 20.782C8.988 20.15 9.501 19.637 10.133 19.637C11.216 19.637 11.215 20.582 11.214 21.349V21.418C11.214 22.582 11.925 23.579 12.937 24C12.7812 23.6794 12.7005 23.3275 12.701 22.971C12.701 21.861 13.353 21.448 14.111 20.968C14.713 20.585 15.383 20.161 15.844 19.308C16.0926 18.8493 16.2225 18.3357 16.222 17.814C16.2221 17.4903 16.1722 17.1685 16.074 16.86ZM15.551 0.6C15.747 0.844 15.847 1.172 16.047 1.829L20.415 16.176C18.7743 15.3246 17.0134 14.7284 15.193 14.408L12.35 4.8C12.3273 4.72337 12.2803 4.65616 12.2162 4.60844C12.152 4.56072 12.0742 4.53505 11.9943 4.53528C11.9143 4.5355 11.8366 4.56161 11.7727 4.60969C11.7089 4.65777 11.6623 4.72524 11.64 4.802L8.83 14.405C7.00149 14.724 5.23264 15.3213 3.585 16.176L7.974 1.827C8.174 1.171 8.274 0.843 8.471 0.6C8.64406 0.385433 8.86922 0.218799 9.125 0.116C9.415 0 9.757 0 10.443 0H13.578C14.264 0 14.608 0 14.898 0.117C15.1529 0.219851 15.3783 0.386105 15.551 0.6Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
<p className="mt-2 font-medium">Astro</p>
|
||||
</LinkedCard>
|
||||
<LinkedCard href="/docs/installation/tanstack">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
className="h-10 w-10"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path d="M6.93 13.688a.343.343 0 0 1 .468.132l.063.106c.48.851.98 1.66 1.5 2.426a35.65 35.65 0 0 0 2.074 2.742.345.345 0 0 1-.039.484l-.074.066c-2.543 2.223-4.191 2.665-4.953 1.333-.746-1.305-.477-3.672.808-7.11a.344.344 0 0 1 .153-.18ZM17.75 16.3a.34.34 0 0 1 .395.27l.02.1c.628 3.286.187 4.93-1.325 4.93-1.48 0-3.36-1.402-5.649-4.203a.327.327 0 0 1-.074-.222c0-.188.156-.34.344-.34h.121a32.984 32.984 0 0 0 2.809-.098c1.07-.086 2.191-.23 3.359-.437zm.871-6.977a.353.353 0 0 1 .445-.21l.102.034c3.262 1.11 4.504 2.332 3.719 3.664-.766 1.305-2.993 2.254-6.684 2.848a.362.362 0 0 1-.238-.047.343.343 0 0 1-.125-.476l.062-.106a34.07 34.07 0 0 0 1.367-2.523c.477-.989.93-2.051 1.352-3.184zM7.797 8.34a.362.362 0 0 1 .238.047.343.343 0 0 1 .125.476l-.062.106a34.088 34.088 0 0 0-1.367 2.523c-.477.988-.93 2.051-1.352 3.184a.353.353 0 0 1-.445.21l-.102-.034C1.57 13.742.328 12.52 1.113 11.188 1.88 9.883 4.106 8.934 7.797 8.34Zm5.281-3.984c2.543-2.223 4.192-2.664 4.953-1.332.746 1.304.477 3.671-.808 7.109a.344.344 0 0 1-.153.18.343.343 0 0 1-.468-.133l-.063-.106a34.64 34.64 0 0 0-1.5-2.426 35.65 35.65 0 0 0-2.074-2.742.345.345 0 0 1 .039-.484ZM7.285 2.274c1.48 0 3.364 1.402 5.649 4.203a.349.349 0 0 1 .078.218.348.348 0 0 1-.348.344l-.117-.004a34.584 34.584 0 0 0-2.809.102 35.54 35.54 0 0 0-3.363.437.343.343 0 0 1-.394-.273l-.02-.098c-.629-3.285-.188-4.93 1.324-4.93Zm2.871 5.812h3.688a.638.638 0 0 1 .55.316l1.848 3.22a.644.644 0 0 1 0 .628l-1.847 3.223a.638.638 0 0 1-.551.316h-3.688a.627.627 0 0 1-.547-.316L7.758 12.25a.644.644 0 0 1 0-.629L9.61 8.402a.627.627 0 0 1 .546-.316Zm3.23.793a.638.638 0 0 1 .552.316l1.39 2.426a.644.644 0 0 1 0 .629l-1.39 2.43a.638.638 0 0 1-.551.316h-2.774a.627.627 0 0 1-.546-.316l-1.395-2.43a.644.644 0 0 1 0-.629l1.395-2.426a.627.627 0 0 1 .546-.316Zm-.491.867h-1.79a.624.624 0 0 0-.546.316l-.899 1.56a.644.644 0 0 0 0 .628l.899 1.563a.632.632 0 0 0 .547.316h1.789a.632.632 0 0 0 .547-.316l.898-1.563a.644.644 0 0 0 0-.629l-.898-1.558a.624.624 0 0 0-.547-.317Zm-.477.828c.227 0 .438.121.547.317l.422.73a.625.625 0 0 1 0 .629l-.422.734a.627.627 0 0 1-.547.317h-.836a.632.632 0 0 1-.547-.317l-.422-.734a.625.625 0 0 1 0-.629l.422-.73a.632.632 0 0 1 .547-.317zm-.418.817a.548.548 0 0 0-.473.273.547.547 0 0 0 0 .547.544.544 0 0 0 .473.27.544.544 0 0 0 .473-.27.547.547 0 0 0 0-.547.548.548 0 0 0-.473-.273Zm-4.422.546h.98M18.98 7.75c.391-1.895.477-3.344.223-4.398-.148-.63-.422-1.137-.84-1.508-.441-.39-1-.582-1.625-.582-1.035 0-2.12.472-3.281 1.367a14.9 14.9 0 0 0-1.473 1.316 1.206 1.206 0 0 0-.136-.144c-1.446-1.285-2.66-2.082-3.7-2.39-.617-.184-1.195-.2-1.722-.024-.559.187-1.004.574-1.317 1.117-.515.894-.652 2.074-.46 3.527.078.59.214 1.235.402 1.934a1.119 1.119 0 0 0-.215.047C3.008 8.62 1.71 9.269.926 10.015c-.465.442-.77.938-.883 1.481-.113.578 0 1.156.312 1.7.516.894 1.465 1.597 2.817 2.155.543.223 1.156.426 1.844.61a1.023 1.023 0 0 0-.07.226c-.391 1.891-.477 3.344-.223 4.395.148.629.425 1.14.84 1.508.44.39 1 .582 1.625.582 1.035 0 2.12-.473 3.28-1.364.477-.37.973-.816 1.489-1.336a1.2 1.2 0 0 0 .195.227c1.446 1.285 2.66 2.082 3.7 2.39.617.184 1.195.2 1.722.024.559-.187 1.004-.574 1.317-1.117.515-.894.652-2.074.46-3.527a14.941 14.941 0 0 0-.425-2.012 1.225 1.225 0 0 0 .238-.047c1.828-.61 3.125-1.258 3.91-2.004.465-.441.77-.937.883-1.48.113-.578 0-1.157-.313-1.7-.515-.894-1.464-1.597-2.816-2.156a14.576 14.576 0 0 0-1.906-.625.865.865 0 0 0 .059-.195z" />
|
||||
</svg>
|
||||
<p className="mt-2 font-medium">TanStack Start</p>
|
||||
</LinkedCard>
|
||||
<LinkedCard href="/docs/installation/gatsby">
|
||||
<svg
|
||||
role="img"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="h-10 w-10"
|
||||
fill="currentColor"
|
||||
>
|
||||
<title>Gatsby</title>
|
||||
<path d="M12 0C5.4 0 0 5.4 0 12s5.4 12 12 12 12-5.4 12-12S18.6 0 12 0zm0 2.571c3.171 0 5.915 1.543 7.629 3.858l-1.286 1.115C16.886 5.572 14.571 4.286 12 4.286c-3.343 0-6.171 2.143-7.286 5.143l9.857 9.857c2.486-.857 4.373-3 4.973-5.572h-4.115V12h6c0 4.457-3.172 8.228-7.372 9.17L2.83 9.944C3.772 5.743 7.543 2.57 12 2.57zm-9.429 9.6l9.344 9.258c-2.4-.086-4.801-.943-6.601-2.743-1.8-1.8-2.743-4.201-2.743-6.515z" />
|
||||
</svg>
|
||||
<p className="mt-2 font-medium">Gatsby</p>
|
||||
</LinkedCard>
|
||||
<LinkedCard href="/docs/installation/manual">
|
||||
<svg
|
||||
role="img"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="h-10 w-10"
|
||||
fill="currentColor"
|
||||
>
|
||||
<title>React</title>
|
||||
<path d="M14.23 12.004a2.236 2.236 0 0 1-2.235 2.236 2.236 2.236 0 0 1-2.236-2.236 2.236 2.236 0 0 1 2.235-2.236 2.236 2.236 0 0 1 2.236 2.236zm2.648-10.69c-1.346 0-3.107.96-4.888 2.622-1.78-1.653-3.542-2.602-4.887-2.602-.41 0-.783.093-1.106.278-1.375.793-1.683 3.264-.973 6.365C1.98 8.917 0 10.42 0 12.004c0 1.59 1.99 3.097 5.043 4.03-.704 3.113-.39 5.588.988 6.38.32.187.69.275 1.102.275 1.345 0 3.107-.96 4.888-2.624 1.78 1.654 3.542 2.603 4.887 2.603.41 0 .783-.09 1.106-.275 1.374-.792 1.683-3.263.973-6.365C22.02 15.096 24 13.59 24 12.004c0-1.59-1.99-3.097-5.043-4.032.704-3.11.39-5.587-.988-6.38-.318-.184-.688-.277-1.092-.278zm-.005 1.09v.006c.225 0 .406.044.558.127.666.382.955 1.835.73 3.704-.054.46-.142.945-.25 1.44-.96-.236-2.006-.417-3.107-.534-.66-.905-1.345-1.727-2.035-2.447 1.592-1.48 3.087-2.292 4.105-2.295zm-9.77.02c1.012 0 2.514.808 4.11 2.28-.686.72-1.37 1.537-2.02 2.442-1.107.117-2.154.298-3.113.538-.112-.49-.195-.964-.254-1.42-.23-1.868.054-3.32.714-3.707.19-.09.4-.127.563-.132zm4.882 3.05c.455.468.91.992 1.36 1.564-.44-.02-.89-.034-1.345-.034-.46 0-.915.01-1.36.034.44-.572.895-1.096 1.345-1.565zM12 8.1c.74 0 1.477.034 2.202.093.406.582.802 1.203 1.183 1.86.372.64.71 1.29 1.018 1.946-.308.655-.646 1.31-1.013 1.95-.38.66-.773 1.288-1.18 1.87-.728.063-1.466.098-2.21.098-.74 0-1.477-.035-2.202-.093-.406-.582-.802-1.204-1.183-1.86-.372-.64-.71-1.29-1.018-1.946.303-.657.646-1.313 1.013-1.954.38-.66.773-1.286 1.18-1.868.728-.064 1.466-.098 2.21-.098zm-3.635.254c-.24.377-.48.763-.704 1.16-.225.39-.435.782-.635 1.174-.265-.656-.49-1.31-.676-1.947.64-.15 1.315-.283 2.015-.386zm7.26 0c.695.103 1.365.23 2.006.387-.18.632-.405 1.282-.66 1.933-.2-.39-.41-.783-.64-1.174-.225-.392-.465-.774-.705-1.146zm3.063.675c.484.15.944.317 1.375.498 1.732.74 2.852 1.708 2.852 2.476-.005.768-1.125 1.74-2.857 2.475-.42.18-.88.342-1.355.493-.28-.958-.646-1.956-1.1-2.98.45-1.017.81-2.01 1.085-2.964zm-13.395.004c.278.96.645 1.957 1.1 2.98-.45 1.017-.812 2.01-1.086 2.964-.484-.15-.944-.318-1.37-.5-1.732-.737-2.852-1.706-2.852-2.474 0-.768 1.12-1.742 2.852-2.476.42-.18.88-.342 1.356-.494zm11.678 4.28c.265.657.49 1.312.676 1.948-.64.157-1.316.29-2.016.39.24-.375.48-.762.705-1.158.225-.39.435-.788.636-1.18zm-9.945.02c.2.392.41.783.64 1.175.23.39.465.772.705 1.143-.695-.102-1.365-.23-2.006-.386.18-.63.406-1.282.66-1.933zM17.92 16.32c.112.493.2.968.254 1.423.23 1.868-.054 3.32-.714 3.708-.147.09-.338.128-.563.128-1.012 0-2.514-.807-4.11-2.28.686-.72 1.37-1.536 2.02-2.44 1.107-.118 2.154-.3 3.113-.54zm-11.83.01c.96.234 2.006.415 3.107.532.66.905 1.345 1.727 2.035 2.446-1.595 1.483-3.092 2.295-4.11 2.295-.22-.005-.406-.05-.553-.132-.666-.38-.955-1.834-.73-3.703.054-.46.142-.944.25-1.438zm4.56.64c.44.02.89.034 1.345.034.46 0 .915-.01 1.36-.034-.44.572-.895 1.095-1.345 1.565-.455-.47-.91-.993-1.36-1.565z" />
|
||||
</svg>
|
||||
<p className="mt-2 font-medium">Manual</p>
|
||||
</LinkedCard>
|
||||
</div>
|
||||
|
||||
## Upgrade Your Project
|
||||
|
||||
<Callout className="mt-6 mb-6 border-blue-600 bg-blue-50 dark:border-blue-900 dark:bg-blue-950 [&_code]:bg-blue-100 dark:[&_code]:bg-blue-900">
|
||||
**Important:** Before upgrading, please read the [Tailwind v4 Compatibility
|
||||
Docs](https://tailwindcss.com/docs/compatibility) and make sure your project
|
||||
is ready for the upgrade. Tailwind v4 uses bleeding-edge browser features and
|
||||
is designed for modern browsers.
|
||||
</Callout>
|
||||
|
||||
One of the major advantages of using `shadcn/ui` is that the code you end up with is exactly what you'd write yourself. There are no hidden abstractions.
|
||||
|
||||
This means when a dependency has a new release, you can just follow the official upgrade paths.
|
||||
|
||||
Here's how to upgrade your existing projects (full docs are on the way):
|
||||
|
||||
### 1. Follow the Tailwind v4 Upgrade Guide
|
||||
|
||||
- Upgrade to Tailwind v4 by following the official upgrade guide: https://tailwindcss.com/docs/upgrade-guide
|
||||
- Use the `@tailwindcss/upgrade@next` codemod to remove deprecated utility classes and update tailwind config.
|
||||
|
||||
### 2. Update your CSS variables
|
||||
|
||||
The codemod will migrate your CSS variables as references under the `@theme` directive.
|
||||
|
||||
```css showLineNumbers
|
||||
@layer base {
|
||||
:root {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 0 0% 3.9%;
|
||||
}
|
||||
}
|
||||
|
||||
@theme {
|
||||
--color-background: hsl(var(--background));
|
||||
--color-foreground: hsl(var(--foreground));
|
||||
}
|
||||
```
|
||||
|
||||
This works. But to make it easier to work with colors and other variables, we'll need to move the `hsl` wrappers and use `@theme inline`.
|
||||
|
||||
Here's how you do it:
|
||||
|
||||
1. Move `:root` and `.dark` out of the `@layer` base.
|
||||
2. Wrap the color values in `hsl()`
|
||||
3. Add the `inline` option to `@theme` i.e `@theme inline`
|
||||
4. Remove the `hsl()` wrappers from `@theme`
|
||||
|
||||
```css showLineNumbers
|
||||
:root {
|
||||
--background: hsl(0 0% 100%); // <-- Wrap in hsl
|
||||
--foreground: hsl(0 0% 3.9%);
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: hsl(0 0% 3.9%); // <-- Wrap in hsl
|
||||
--foreground: hsl(0 0% 98%);
|
||||
}
|
||||
|
||||
@theme inline {
|
||||
--color-background: var(--background); // <-- Remove hsl
|
||||
--color-foreground: var(--foreground);
|
||||
}
|
||||
```
|
||||
|
||||
This change makes it much simpler to access your theme variables in both utility classes and outside of CSS, e.g. using color values in JavaScript.
|
||||
|
||||
### 3. Update colors for charts
|
||||
|
||||
Now that the theme colors come with `hsl()`, you can remove the wrapper in your `chartConfig`:
|
||||
|
||||
```diff
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: "Desktop",
|
||||
- color: "hsl(var(--chart-1))",
|
||||
+ color: "var(--chart-1)",
|
||||
},
|
||||
mobile: {
|
||||
label: "Mobile",
|
||||
- color: "hsl(var(--chart-2))",
|
||||
+ color: "var(--chart-2)",
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
```
|
||||
|
||||
### 4. Use new `size-*` utility
|
||||
|
||||
The new `size-*` utility (added in Tailwind v3.4), is now fully supported by `tailwind-merge`. You can replace `w-* h-*` with the new `size-*` utility:
|
||||
|
||||
```diff
|
||||
- w-4 h-4
|
||||
+ size-4
|
||||
```
|
||||
|
||||
### 5. Update your dependencies
|
||||
|
||||
```bash
|
||||
pnpm up "@radix-ui/*" cmdk lucide-react recharts tailwind-merge clsx --latest
|
||||
```
|
||||
|
||||
### 6. Remove forwardRef
|
||||
|
||||
You can use the `remove-forward-ref` codemod to migrate your `forwardRef` to props or manually update the primitives.
|
||||
|
||||
For the codemod, see https://github.com/reactjs/react-codemod#remove-forward-ref.
|
||||
|
||||
If you want to do it manually, here's how to do it step by step:
|
||||
|
||||
1. Replace `React.forwardRef<...>` with `React.ComponentProps<...>`
|
||||
2. Remove `ref={ref}` from the component.
|
||||
3. Add a `data-slot` attribute. This will come in handy for styling with Tailwind.
|
||||
4. You can optionally convert to a named function and remove the `displayName`.
|
||||
|
||||
#### Before
|
||||
|
||||
```tsx showLineNumbers
|
||||
const AccordionItem = React.forwardRef<
|
||||
React.ElementRef<typeof AccordionPrimitive.Item>,
|
||||
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<AccordionPrimitive.Item
|
||||
ref={ref}
|
||||
className={cn("border-b last:border-b-0", className)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
AccordionItem.displayName = "AccordionItem"
|
||||
```
|
||||
|
||||
#### After
|
||||
|
||||
```tsx showLineNumbers
|
||||
function AccordionItem({
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof AccordionPrimitive.Item>) {
|
||||
return (
|
||||
<AccordionPrimitive.Item
|
||||
data-slot="accordion-item"
|
||||
className={cn("border-b last:border-b-0", className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## Changelog
|
||||
|
||||
### March 19, 2025 - Deprecate `tailwindcss-animate`
|
||||
|
||||
We've deprecated `tailwindcss-animate` in favor of `tw-animate-css`.
|
||||
|
||||
New projects will have `tw-animate-css` installed by default.
|
||||
|
||||
For existing projects, follow the steps below to migrate.
|
||||
|
||||
1. Remove `tailwindcss-animate` from your dependencies.
|
||||
2. Remove the `@plugin 'tailwindcss-animate'` from your globals.css file.
|
||||
3. Install `tw-animate-css` as a dev dependency.
|
||||
4. Add the `@import "tw-animate-css"` to your globals.css file.
|
||||
|
||||
```diff showLineNumbers
|
||||
- @plugin 'tailwindcss-animate';
|
||||
+ @import "tw-animate-css";
|
||||
```
|
||||
|
||||
### March 12, 2025 - New Dark Mode Colors
|
||||
|
||||
We've revisited the dark mode colors and updated them to be more accessible.
|
||||
|
||||
If you're running an existing Tailwind v4 project (**not an upgraded one**[^1]), you can update your components to use the new dark mode colors by re-adding your components using the CLI[^2].
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>Commit any changes</Step>
|
||||
|
||||
**The CLI will overwrite your existing components.** We recommend committing any changes you've made to your components before running the CLI.
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "..."
|
||||
```
|
||||
|
||||
<Step>Update components</Step>
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add --all --overwrite
|
||||
```
|
||||
|
||||
<Step>Update colors</Step>
|
||||
|
||||
Update the dark mode colors in your `globals.css` file to new OKLCH colors. See the [Base Colors](/docs/theming#base-colors) reference for a list of colors.
|
||||
|
||||
<Step>Review changes</Step>
|
||||
|
||||
Review and re-apply any changes you made to your components.
|
||||
|
||||
</Steps>
|
||||
|
||||
[^1]: Upgraded projects are not affected by this change. You can continue using the old dark mode colors.
|
||||
|
||||
[^2]: Updating your components will overwrite your existing components.
|
||||
304
apps/v4/content/docs/(root)/theming.mdx
Normal file
304
apps/v4/content/docs/(root)/theming.mdx
Normal file
@@ -0,0 +1,304 @@
|
||||
---
|
||||
title: Theming
|
||||
description: Using CSS variables and theme tokens.
|
||||
---
|
||||
|
||||
<Callout>
|
||||
|
||||
Want to build your theme visually? Use [shadcn/create](/create) to preview colors, radius, fonts, and icons, then generate a preset for your project.
|
||||
|
||||
</Callout>
|
||||
|
||||
We use and recommend CSS variables for theming.
|
||||
|
||||
This gives you semantic theme tokens like `background`, `foreground`, and `primary` that components use by default. Override those tokens in your CSS to change the look of your app without rewriting component classes.
|
||||
|
||||
```tsx /bg-background/ /text-foreground/
|
||||
<div className="bg-background text-foreground" />
|
||||
```
|
||||
|
||||
To use CSS variables for theming, set `tailwind.cssVariables` to `true` in your `components.json` file. This is the default.
|
||||
|
||||
```json {8} title="components.json" showLineNumbers
|
||||
{
|
||||
"style": "base-nova",
|
||||
"rsc": true,
|
||||
"tailwind": {
|
||||
"config": "",
|
||||
"css": "app/globals.css",
|
||||
"baseColor": "neutral",
|
||||
"cssVariables": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Tailwind maps these tokens into utilities like `bg-background`, `text-foreground`, `border-border`, and `ring-ring`.
|
||||
|
||||
Dark mode works by overriding the same tokens inside a `.dark` selector. See the [dark mode docs](/docs/dark-mode/next) for adding a theme provider and toggling the `.dark` class.
|
||||
|
||||
## Token Convention
|
||||
|
||||
We use semantic background and foreground pairs. The base token controls the surface color and the `-foreground` token controls the text and icon color that sits on that surface.
|
||||
|
||||
<Callout className="mt-4">
|
||||
|
||||
The background suffix is omitted for the surface token. For example, `primary` pairs with `primary-foreground`.
|
||||
|
||||
</Callout>
|
||||
|
||||
Given the following CSS variables:
|
||||
|
||||
```css
|
||||
--primary: oklch(0.205 0 0);
|
||||
--primary-foreground: oklch(0.985 0 0);
|
||||
```
|
||||
|
||||
The `background` color of the following component will be `var(--primary)` and the `foreground` color will be `var(--primary-foreground)`.
|
||||
|
||||
```tsx
|
||||
<div className="bg-primary text-primary-foreground">Hello</div>
|
||||
```
|
||||
|
||||
## Theme Tokens
|
||||
|
||||
These tokens live in your CSS file under `:root` and `.dark`.
|
||||
|
||||
| Token | What it controls | Used by |
|
||||
| ------------------------------------------------ | ------------------------------------------------------ | ---------------------------------------------------------------------------- |
|
||||
| `background` / `foreground` | The default app background and text color. | The page shell, page sections, and default text. |
|
||||
| `card` / `card-foreground` | Elevated surfaces and the content inside them. | `Card`, dashboard panels, settings panels. |
|
||||
| `popover` / `popover-foreground` | Floating surfaces and the content inside them. | `Popover`, `DropdownMenu`, `ContextMenu`, and other overlays. |
|
||||
| `primary` / `primary-foreground` | High-emphasis actions and brand surfaces. | Default `Button`, selected states, badges, and active accents. |
|
||||
| `secondary` / `secondary-foreground` | Lower-emphasis filled actions and supporting surfaces. | Secondary buttons, secondary badges, and supporting UI. |
|
||||
| `muted` / `muted-foreground` | Subtle surfaces and lower-emphasis content. | Descriptions, placeholders, empty states, helper text, and subdued surfaces. |
|
||||
| `accent` / `accent-foreground` | Interactive hover, focus, and active surfaces. | Ghost buttons, menu highlight states, hovered rows, and selected items. |
|
||||
| `destructive` | Destructive actions and error emphasis. | Destructive buttons, invalid states, and destructive menu items. |
|
||||
| `border` | Default borders and separators. | Cards, menus, tables, separators, and layout dividers. |
|
||||
| `input` | Form control borders and input surface treatment. | `Input`, `Textarea`, `Select`, and outline-style controls. |
|
||||
| `ring` | Focus rings and outlines. | Buttons, inputs, checkboxes, menus, and other focusable controls. |
|
||||
| `chart-1` ... `chart-5` | The default chart palette. | Charts and chart-driven dashboard blocks. |
|
||||
| `sidebar` / `sidebar-foreground` | The base sidebar surface and default sidebar text. | The `Sidebar` container and its default content. |
|
||||
| `sidebar-primary` / `sidebar-primary-foreground` | High-emphasis actions inside the sidebar. | Active items, icon tiles, badges, and sidebar CTAs. |
|
||||
| `sidebar-accent` / `sidebar-accent-foreground` | Hover and selected states inside the sidebar. | Sidebar menu hover states, open items, and interactive rows. |
|
||||
| `sidebar-border` | Sidebar-specific borders and separators. | Sidebar headers, groups, and internal dividers. |
|
||||
| `sidebar-ring` | Sidebar-specific focus rings. | Focused controls inside the sidebar. |
|
||||
| `radius` | The base corner radius scale. | Cards, inputs, buttons, popovers, and the derived `radius-*` tokens. |
|
||||
|
||||
<Callout className="mt-4">
|
||||
|
||||
The chart tokens are covered in more detail in the [Chart theming docs](/docs/components/chart#theming).
|
||||
|
||||
</Callout>
|
||||
|
||||
## Radius Scale
|
||||
|
||||
`--radius` is the base radius token for your theme.
|
||||
|
||||
We derive a small radius scale from it so components can use consistent corner sizes while still sharing a single source of truth.
|
||||
|
||||
```css title="app/globals.css" showLineNumbers
|
||||
@theme inline {
|
||||
--radius-sm: calc(var(--radius) * 0.6);
|
||||
--radius-md: calc(var(--radius) * 0.8);
|
||||
--radius-lg: var(--radius);
|
||||
--radius-xl: calc(var(--radius) * 1.4);
|
||||
--radius-2xl: calc(var(--radius) * 1.8);
|
||||
--radius-3xl: calc(var(--radius) * 2.2);
|
||||
--radius-4xl: calc(var(--radius) * 2.6);
|
||||
}
|
||||
```
|
||||
|
||||
This means:
|
||||
|
||||
- `radius-lg` is the base value.
|
||||
- Smaller radii scale down from `--radius`.
|
||||
- Larger radii scale up from `--radius`.
|
||||
- Changing `--radius` updates the entire radius scale.
|
||||
|
||||
## Adding New Tokens
|
||||
|
||||
To add a new token, define it under `:root` and `.dark`, then expose it to Tailwind with `@theme inline`.
|
||||
|
||||
```css title="app/globals.css" showLineNumbers
|
||||
:root {
|
||||
--warning: oklch(0.84 0.16 84);
|
||||
--warning-foreground: oklch(0.28 0.07 46);
|
||||
}
|
||||
|
||||
.dark {
|
||||
--warning: oklch(0.41 0.11 46);
|
||||
--warning-foreground: oklch(0.99 0.02 95);
|
||||
}
|
||||
|
||||
@theme inline {
|
||||
--color-warning: var(--warning);
|
||||
--color-warning-foreground: var(--warning-foreground);
|
||||
}
|
||||
```
|
||||
|
||||
You can now use `bg-warning` and `text-warning-foreground` in your components.
|
||||
|
||||
```tsx /bg-warning/ /text-warning-foreground/
|
||||
<div className="bg-warning text-warning-foreground" />
|
||||
```
|
||||
|
||||
## Base Colors
|
||||
|
||||
`tailwind.baseColor` controls the default token values generated for your project when you run `init` or use a preset.
|
||||
|
||||
The available base colors are: **Neutral**, **Stone**, **Zinc**, **Mauve**, **Olive**, **Mist**, and **Taupe**.
|
||||
|
||||
## Default Theme CSS
|
||||
|
||||
The following is the full default `neutral` theme scaffold. Copy it into your global CSS file and adjust the tokens as needed.
|
||||
|
||||
<CodeCollapsibleWrapper>
|
||||
|
||||
```css showLineNumbers title="app/globals.css"
|
||||
@import "tailwindcss";
|
||||
@import "shadcn/tailwind.css";
|
||||
|
||||
@custom-variant dark (&:is(.dark *));
|
||||
|
||||
@theme inline {
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--color-card: var(--card);
|
||||
--color-card-foreground: var(--card-foreground);
|
||||
--color-popover: var(--popover);
|
||||
--color-popover-foreground: var(--popover-foreground);
|
||||
--color-primary: var(--primary);
|
||||
--color-primary-foreground: var(--primary-foreground);
|
||||
--color-secondary: var(--secondary);
|
||||
--color-secondary-foreground: var(--secondary-foreground);
|
||||
--color-muted: var(--muted);
|
||||
--color-muted-foreground: var(--muted-foreground);
|
||||
--color-accent: var(--accent);
|
||||
--color-accent-foreground: var(--accent-foreground);
|
||||
--color-destructive: var(--destructive);
|
||||
--color-border: var(--border);
|
||||
--color-input: var(--input);
|
||||
--color-ring: var(--ring);
|
||||
--color-chart-1: var(--chart-1);
|
||||
--color-chart-2: var(--chart-2);
|
||||
--color-chart-3: var(--chart-3);
|
||||
--color-chart-4: var(--chart-4);
|
||||
--color-chart-5: var(--chart-5);
|
||||
--color-sidebar: var(--sidebar);
|
||||
--color-sidebar-foreground: var(--sidebar-foreground);
|
||||
--color-sidebar-primary: var(--sidebar-primary);
|
||||
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
||||
--color-sidebar-accent: var(--sidebar-accent);
|
||||
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
||||
--color-sidebar-border: var(--sidebar-border);
|
||||
--color-sidebar-ring: var(--sidebar-ring);
|
||||
--radius-sm: calc(var(--radius) * 0.6);
|
||||
--radius-md: calc(var(--radius) * 0.8);
|
||||
--radius-lg: var(--radius);
|
||||
--radius-xl: calc(var(--radius) * 1.4);
|
||||
--radius-2xl: calc(var(--radius) * 1.8);
|
||||
--radius-3xl: calc(var(--radius) * 2.2);
|
||||
--radius-4xl: calc(var(--radius) * 2.6);
|
||||
}
|
||||
|
||||
:root {
|
||||
--radius: 0.625rem;
|
||||
--background: oklch(1 0 0);
|
||||
--foreground: oklch(0.145 0 0);
|
||||
--card: oklch(1 0 0);
|
||||
--card-foreground: oklch(0.145 0 0);
|
||||
--popover: oklch(1 0 0);
|
||||
--popover-foreground: oklch(0.145 0 0);
|
||||
--primary: oklch(0.205 0 0);
|
||||
--primary-foreground: oklch(0.985 0 0);
|
||||
--secondary: oklch(0.97 0 0);
|
||||
--secondary-foreground: oklch(0.205 0 0);
|
||||
--muted: oklch(0.97 0 0);
|
||||
--muted-foreground: oklch(0.556 0 0);
|
||||
--accent: oklch(0.97 0 0);
|
||||
--accent-foreground: oklch(0.205 0 0);
|
||||
--destructive: oklch(0.577 0.245 27.325);
|
||||
--border: oklch(0.922 0 0);
|
||||
--input: oklch(0.922 0 0);
|
||||
--ring: oklch(0.708 0 0);
|
||||
--chart-1: oklch(0.646 0.222 41.116);
|
||||
--chart-2: oklch(0.6 0.118 184.704);
|
||||
--chart-3: oklch(0.398 0.07 227.392);
|
||||
--chart-4: oklch(0.828 0.189 84.429);
|
||||
--chart-5: oklch(0.769 0.188 70.08);
|
||||
--sidebar: oklch(0.985 0 0);
|
||||
--sidebar-foreground: oklch(0.145 0 0);
|
||||
--sidebar-primary: oklch(0.205 0 0);
|
||||
--sidebar-primary-foreground: oklch(0.985 0 0);
|
||||
--sidebar-accent: oklch(0.97 0 0);
|
||||
--sidebar-accent-foreground: oklch(0.205 0 0);
|
||||
--sidebar-border: oklch(0.922 0 0);
|
||||
--sidebar-ring: oklch(0.708 0 0);
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: oklch(0.145 0 0);
|
||||
--foreground: oklch(0.985 0 0);
|
||||
--card: oklch(0.205 0 0);
|
||||
--card-foreground: oklch(0.985 0 0);
|
||||
--popover: oklch(0.205 0 0);
|
||||
--popover-foreground: oklch(0.985 0 0);
|
||||
--primary: oklch(0.922 0 0);
|
||||
--primary-foreground: oklch(0.205 0 0);
|
||||
--secondary: oklch(0.269 0 0);
|
||||
--secondary-foreground: oklch(0.985 0 0);
|
||||
--muted: oklch(0.269 0 0);
|
||||
--muted-foreground: oklch(0.708 0 0);
|
||||
--accent: oklch(0.269 0 0);
|
||||
--accent-foreground: oklch(0.985 0 0);
|
||||
--destructive: oklch(0.704 0.191 22.216);
|
||||
--border: oklch(1 0 0 / 10%);
|
||||
--input: oklch(1 0 0 / 15%);
|
||||
--ring: oklch(0.556 0 0);
|
||||
--chart-1: oklch(0.488 0.243 264.376);
|
||||
--chart-2: oklch(0.696 0.17 162.48);
|
||||
--chart-3: oklch(0.769 0.188 70.08);
|
||||
--chart-4: oklch(0.627 0.265 303.9);
|
||||
--chart-5: oklch(0.645 0.246 16.439);
|
||||
--sidebar: oklch(0.205 0 0);
|
||||
--sidebar-foreground: oklch(0.985 0 0);
|
||||
--sidebar-primary: oklch(0.488 0.243 264.376);
|
||||
--sidebar-primary-foreground: oklch(0.985 0 0);
|
||||
--sidebar-accent: oklch(0.269 0 0);
|
||||
--sidebar-accent-foreground: oklch(0.985 0 0);
|
||||
--sidebar-border: oklch(1 0 0 / 10%);
|
||||
--sidebar-ring: oklch(0.556 0 0);
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border outline-ring/50;
|
||||
}
|
||||
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</CodeCollapsibleWrapper>
|
||||
|
||||
## Without CSS Variables
|
||||
|
||||
If you do not want to use CSS variables, the CLI can generate components with inline Tailwind color utilities instead.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest init --no-css-variables
|
||||
```
|
||||
|
||||
This sets `tailwind.cssVariables` to `false` in your `components.json` file.
|
||||
|
||||
```tsx /bg-zinc-950/ /text-zinc-50/ /dark:bg-white/ /dark:text-zinc-950/
|
||||
<div className="bg-zinc-950 text-zinc-50 dark:bg-white dark:text-zinc-950" />
|
||||
```
|
||||
|
||||
<Callout className="mt-4">
|
||||
|
||||
This is an installation-time choice. To switch an existing project, delete and re-install your components.
|
||||
|
||||
</Callout>
|
||||
242
apps/v4/content/docs/(root)/typeset.mdx
Normal file
242
apps/v4/content/docs/(root)/typeset.mdx
Normal file
@@ -0,0 +1,242 @@
|
||||
---
|
||||
title: Typeset
|
||||
description: A styling system for HTML and rendered markdown, from blog posts to streaming chat. One CSS file you own.
|
||||
---
|
||||
|
||||
You render markdown and get back plain unstyled HTML: headings, paragraphs, lists, and tables. So you style the elements one by one: font sizes, line heights, spacing.
|
||||
|
||||
You do it for your blog. Then you do it again for the docs. Then again for the chat app. Every time you're fighting the same thing: sizing and spacing.
|
||||
|
||||
To fix this, we created **shadcn/typeset**. It's one CSS file that styles everything inside a `typeset` container. The file lives in your project, so you can change it directly when you need to.
|
||||
|
||||
A typeset is just a small preset class. You can have multiple typesets in your app, for different contexts.
|
||||
|
||||
```css
|
||||
.typeset-docs {
|
||||
--typeset-font-body: var(--font-geist);
|
||||
--typeset-font-heading: var(--font-geist);
|
||||
--typeset-font-mono: var(--font-geist-mono);
|
||||
--typeset-size: 15px;
|
||||
--typeset-leading: 1.75;
|
||||
--typeset-flow: 1.25em;
|
||||
}
|
||||
```
|
||||
|
||||
<Button asChild className="mt-6" size="sm">
|
||||
<Link href="/typeset">Build your typeset</Link>
|
||||
</Button>
|
||||
|
||||
---
|
||||
|
||||
## Principles
|
||||
|
||||
We read a lot about type: scale ratios, tracking, kerning, optical sizing, measure, leading, the space above and below every element. We tried exposing all of it, and it was too much. Nobody wants to set a dozen variables to make markdown look right.
|
||||
|
||||
So we sat down and condensed everything into three controls: size, leading, and flow. Everything else, heading sizes, list indents, the gap under a heading, the space around a rule, derives from them. Three controls. We called it rhythm.
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
|
||||
- **It fits its container.** Put it in a chat bubble and it follows the smaller type around it. Put it in an article and it scales up with the page. On smaller screens, it gets a small bump for readability.
|
||||
- **It uses your theme.** Colors, fonts, and radius come from your app. Dark mode follows the same tokens.
|
||||
- **It's easy to tune.** Three values control the base size, line height, and space between blocks. Change them in a preset and the whole document follows.
|
||||
- **It works well with streaming.** When a new block arrives, Typeset doesn't make earlier blocks switch margins, borders, or styles.
|
||||
|
||||
---
|
||||
|
||||
## Building Your Typeset
|
||||
|
||||
Create your typeset in the [typeset builder](/typeset). Pick your fonts and rhythm, then preview them on docs, chat, articles, and other real content.
|
||||
|
||||
The panel gives you the `typeset.css` file, the font setup for your framework, a preset class with your choices, and the wrapper to add around your content.
|
||||
|
||||
Copy `typeset.css` next to your main CSS file and import it after Tailwind:
|
||||
|
||||
```css
|
||||
@import "tailwindcss";
|
||||
@import "./typeset.css";
|
||||
```
|
||||
|
||||
Then wrap your rendered markdown with `typeset` and your preset class:
|
||||
|
||||
```tsx
|
||||
<div className="typeset typeset-docs">
|
||||
<YourMarkdownRenderer>{content}</YourMarkdownRenderer>
|
||||
</div>
|
||||
```
|
||||
|
||||
`typeset` turns the styles on. `typeset-docs` is the preset you created in the builder.
|
||||
|
||||
---
|
||||
|
||||
## Custom Typesets
|
||||
|
||||
The file includes defaults, so you can use `typeset` by itself. Most of the reading rhythm comes from three values:
|
||||
|
||||
```css
|
||||
.typeset {
|
||||
--typeset-font-body: inherit;
|
||||
--typeset-font-heading: var(--font-heading);
|
||||
--typeset-font-mono: var(--font-mono);
|
||||
|
||||
--typeset-size: 1em; /* body font-size */
|
||||
--typeset-leading: 1.75; /* line-height */
|
||||
--typeset-flow: 1.25em; /* space between blocks */
|
||||
}
|
||||
```
|
||||
|
||||
- **`--typeset-size`** sets the base text size. `1em` follows the surrounding layout. On smaller screens, Typeset bumps it up a little.
|
||||
- **`--typeset-leading`** sets the space between lines.
|
||||
- **`--typeset-flow`** sets the space between blocks. Headings and other elements derive their spacing from it.
|
||||
|
||||
The font variables tell Typeset which families to use. Leave them alone and it follows your app. Colors and radius come from your theme too.
|
||||
|
||||
Typeset doesn't set a maximum width. Your layout owns that. The Measure control in the builder adds a `max-width` to the wrapper instead of hiding it in the stylesheet.
|
||||
|
||||
You can keep more than one preset in the same app. Here is a tighter one for chat and a roomier one for docs:
|
||||
|
||||
```css
|
||||
.typeset-chat {
|
||||
--typeset-flow: 1em;
|
||||
--typeset-leading: 1.6;
|
||||
}
|
||||
|
||||
.typeset-docs {
|
||||
--typeset-size: 15px;
|
||||
--typeset-flow: 1.5em;
|
||||
}
|
||||
```
|
||||
|
||||
```tsx
|
||||
<div className="typeset typeset-chat">{message}</div>
|
||||
<article className="typeset typeset-docs">{page}</article>
|
||||
```
|
||||
|
||||
For a one-off change, skip the preset and set a value on the container:
|
||||
|
||||
```tsx
|
||||
<article className="typeset [--typeset-flow:1.75em]">...</article>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Custom Themes
|
||||
|
||||
A preset can change the whole feel of the content, not just the spacing. You can give readers a serif reading mode, a compact UI mode, or any other style that fits your product.
|
||||
|
||||
```css
|
||||
/* Reading: serif, larger type, roomy rhythm. */
|
||||
.typeset-reading {
|
||||
--typeset-font-body: var(--font-lora);
|
||||
--typeset-font-heading: var(--font-lora);
|
||||
--typeset-size: 18px;
|
||||
--typeset-leading: 1.9;
|
||||
--typeset-flow: 2em;
|
||||
}
|
||||
|
||||
/* Compact: sans, smaller type, tighter rhythm. */
|
||||
.typeset-compact {
|
||||
--typeset-font-body: var(--font-geist);
|
||||
--typeset-font-heading: var(--font-geist);
|
||||
--typeset-size: 14px;
|
||||
--typeset-leading: 1.6;
|
||||
--typeset-flow: 1em;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Accessibility and Dark Mode
|
||||
|
||||
For readers who prefer larger type and more space, create a roomier typeset and expose it as a setting:
|
||||
|
||||
```css
|
||||
.typeset-large {
|
||||
--typeset-size: 16px;
|
||||
--typeset-leading: 2;
|
||||
--typeset-flow: 2em;
|
||||
}
|
||||
```
|
||||
|
||||
Dark mode already follows your theme colors. If the text feels a little tight on a dark surface, you can loosen the leading there:
|
||||
|
||||
```css
|
||||
.dark .typeset {
|
||||
--typeset-leading: 1.9;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Responsive Table
|
||||
|
||||
Tables stay real tables and wrap to fit. To scroll a wide one horizontally instead, wrap it in `typeset-scroll`:
|
||||
|
||||
```tsx
|
||||
<div className="typeset-scroll">
|
||||
<table>...</table>
|
||||
</div>
|
||||
```
|
||||
|
||||
Do this in your renderer's table component or a small rehype plugin. It works for any wide block, not just tables.
|
||||
|
||||
---
|
||||
|
||||
## Overrides
|
||||
|
||||
Typeset lives in the `components` layer and uses `:where()` for its element selectors. Tailwind utilities on an element win without `!important`:
|
||||
|
||||
```tsx
|
||||
<div className="typeset typeset-docs">
|
||||
<p className="text-lg">...</p>
|
||||
</div>
|
||||
```
|
||||
|
||||
Plain CSS can override Typeset with a normal selector too.
|
||||
|
||||
---
|
||||
|
||||
## Opting Out
|
||||
|
||||
To keep a component out of Typeset, add `not-typeset` or `data-not-typeset`:
|
||||
|
||||
```tsx
|
||||
<div className="typeset">
|
||||
<p>Styled prose.</p>
|
||||
<Card className="not-typeset">Untouched component.</Card>
|
||||
</div>
|
||||
```
|
||||
|
||||
Both options cover the component and everything inside it. Another `typeset` container inside that subtree stays opted out too.
|
||||
|
||||
---
|
||||
|
||||
## Streaming
|
||||
|
||||
Typeset is written so that adding a new block does not change the styles of the blocks already on screen.
|
||||
|
||||
- No forward-looking selectors. `:last-child`, `:has()`, and `:empty` are left out of layout rules because their matches can change as content is added.
|
||||
- Spacing flows in one direction, using `margin-block-start` only. A new block adds its own space.
|
||||
- Table separators live on the cells being added, so a new row does not restyle the row above it.
|
||||
|
||||
Text that is still streaming can grow and wrap normally. Typeset just avoids restyling the blocks that came before it.
|
||||
|
||||
---
|
||||
|
||||
## Prior Art
|
||||
|
||||
The `prose` class from `@tailwindcss/typography` is excellent at what it was built for: adding beautiful typographic defaults to plain HTML, including content rendered from Markdown or a CMS.
|
||||
|
||||
Typeset takes a different approach with container-aware sizing, app theme tokens, presets for different contexts, and streaming stability. Here's where they differ:
|
||||
|
||||
| | @tailwindcss/typography | Typeset |
|
||||
| ------------ | -------------------------------------------- | ------------------------------------------------ |
|
||||
| Sizing | Fixed `rem` scale, `prose-sm` to `prose-2xl` | Relative to the container, any size |
|
||||
| Dark mode | `prose-invert`, a second palette | Your tokens flip, nothing to add |
|
||||
| Theming | Prose color variables; scale baked in | Your theme tokens, plus font and rhythm controls |
|
||||
| Overrides | `prose-a:`, `prose-headings:` modifier API | Plain utilities and CSS win |
|
||||
| Streaming | No append-stability contract | Designed for stable appends |
|
||||
| Distribution | npm plugin, generated CSS | One CSS file you own |
|
||||
|
||||
Typeset borrows the two best ideas from the plugin: the zero-specificity `:where()` guard pattern, and the escape-hatch class (`not-typeset`, in the spirit of `not-prose`).
|
||||
Reference in New Issue
Block a user