That's it. _Looking forward to seeing what you build with Blocks_.
## March 2024 - Breadcrumb and Input OTP
We've added a new Breadcrumb component and an Input OTP component.
### Breadcrumb
An accessible and flexible breadcrumb component. It has support for collapsed items, custom separators, bring-your-own routing `` and composable with other shadcn/ui components.
[See more examples](/docs/components/breadcrumb)
### Input OTP
A fully featured input OTP component. It has support for numeric and alphanumeric codes, custom length, copy-paste and accessible. Input OTP is built on top of [input-otp](https://github.com/guilhermerodz/input-otp) by [@guilherme_rodz](https://twitter.com/guilherme_rodz).
[Read the docs](/docs/components/input-otp)
If you have a [v0](https://v0.dev), the new components are available for generation.
## December 2023 - New components, CLI and more
We've added new components to shadcn/ui and made a lot of improvements to the CLI.
Here's a quick overview of what's new:
- [**Carousel**](#carousel) - A carousel component with motion, swipe gestures and keyboard support.
- [**Drawer**](#drawer) - A drawer component that looks amazing on mobile.
- [**Pagination**](#pagination) - A pagination component with page navigation, previous and next buttons.
- [**Resizable**](#resizable) - A resizable component for building resizable panel groups and layouts.
- [**Sonner**](#sonner) - The last toast component you'll ever need.
- [**CLI updates**](#cli-updates) - Support for custom **Tailwind prefix** and `tailwind.config.ts`.
### Carousel
We've added a fully featured carousel component with motion, swipe gestures and keyboard support. Built on top of [Embla Carousel](https://www.embla-carousel.com).
It has support for infinite looping, autoplay, vertical orientation, and more.
### Drawer
Oh the drawer component 😍. Built on top of [Vaul](https://github.com/emilkowalski/vaul) by [emilkowalski\_](https://twitter.com/emilkowalski_).
Try opening the following drawer on mobile. It looks amazing!
### Pagination
We've added a pagination component with page navigation, previous and next buttons. Simple, flexible and works with your framework's `` component.
### Resizable
Build resizable panel groups and layouts with this `` component.
`` is built using [react-resizable-panels](https://github.com/bvaughn/react-resizable-panels) by [bvaughn](https://github.com/bvaughn). It has support for mouse, touch and keyboard.
### Sonner
Another one by [emilkowalski\_](https://twitter.com/emilkowalski_). The last toast component you'll ever need. Sonner is now availabe in shadcn/ui.
### CLI updates
This has been one of the most requested features. You can now configure a custom Tailwind prefix and the cli will automatically prefix your utility classes when adding components.
This means you can now easily add shadcn/ui components to existing projects like Docusaurus, Nextra...etc. A drop-in for your existing design system with no conflict. 🔥
```tsx /tw-/
```
It works with `cn`, `cva` and CSS variables.
The cli can now also detect `tailwind.config.ts` and add the TypeScript version of the config for you.
That's it. Happy Holidays.
## July 2023 - 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, available via the [cli](/docs/cli).
```txt
Would you like to use TypeScript (recommended)? no
```
To opt-out of TypeScript, you can use the `tsx` flag in your `components.json` file.
```json {10} title="components.json" showLineNumbers
{
"style": "default",
"tailwind": {
"config": "tailwind.config.js",
"css": "src/app/globals.css",
"baseColor": "zinc",
"cssVariables": true
},
"rsc": false,
"tsx": false,
"aliases": {
"utils": "~/lib/utils",
"components": "~/components"
}
}
```
To configure import aliases, you can use the following `jsconfig.json`:
```json {4} title="jsconfig.json" showLineNumbers
{
"compilerOptions": {
"paths": {
"@/*": ["./*"]
}
}
}
```
## June 2023 - New CLI, Styles and more
I have a lot of updates to share with you today:
- [**New CLI**](#new-cli) - Rewrote the CLI from scratch. You can now add components, dependencies and configure import paths.
- [**Theming**](#theming-with-css-variables-or-tailwind-colors) - Choose between using CSS variables or Tailwind CSS utility classes for theming.
- [**Base color**](#base-color) - Configure the base color for your project. This will be used to generate the default color palette for your components.
- [**React Server Components**](#react-server-components) - Opt out of using React Server Components. The CLI will automatically append or remove the `use client` directive.
- [**Styles**](#styles) - Introducing a new concept called _Style_. A style comes with its own set of components, animations, icons and more.
- [**Exit animations**](#exit-animations) - Added exit animations to all components.
- [**Other updates**](#other-updates) - New `icon` button size, updated `sheet` component and more.
- [**Updating your project**](#updating-your-project) - How to update your project to get the latest changes.
---
### New CLI
I've been working on a new CLI for the past few weeks. It's a complete rewrite. It comes with a lot of new features and improvements.
### `init`
```bash
npx shadcn@latest init
```
When you run the `init` command, you will be asked a few questions to configure `components.json`:
```txt showLineNumbers
Which style would you like to use? › Default
Which color would you like to use as base color? › Slate
Where is your global CSS file? › › app/globals.css
Do you want to use CSS variables for colors? › no / yes
Where is your tailwind.config.js located? › tailwind.config.js
Configure the import alias for components: › @/components
Configure the import alias for utils: › @/lib/utils
Are you using React Server Components? › no / yes
```
This file contains all the information about your components: where to install them, the import paths, how they are styled...etc.
You can use this file to change the import path of a component, set a baseColor or change the styling method.
```json title="components.json" showLineNumbers
{
"style": "default",
"tailwind": {
"config": "tailwind.config.ts",
"css": "src/app/globals.css",
"baseColor": "zinc",
"cssVariables": true
},
"rsc": false,
"aliases": {
"utils": "~/lib/utils",
"components": "~/components"
}
}
```
This means you can now use the CLI with any directory structure including `src` and `app` directories.
### `add`
```bash
npx shadcn@latest add
```
The `add` command is now much more capable. You can now add UI components but also import more complex components (coming soon).
The CLI will automatically resolve all components and dependencies, format them based on your custom config and add them to your project.
### `diff` (experimental)
```bash
npx shadcn diff
```
We're also introducing a new `diff` command to help you keep track of upstream updates.
You can use this command to see what has changed in the upstream repository and update your project accordingly.
Run the `diff` command to get a list of components that have updates available:
```bash
npx shadcn diff
```
```txt
The following components have updates available:
- button
- /path/to/my-app/components/ui/button.tsx
- toast
- /path/to/my-app/components/ui/use-toast.ts
- /path/to/my-app/components/ui/toaster.tsx
```
Then run `diff [component]` to see the changes:
```bash
npx shadcn diff alert
```
```diff /pl-12/
const alertVariants = cva(
- "relative w-full rounded-lg border",
+ "relative w-full pl-12 rounded-lg border"
)
```
---
### Theming with CSS Variables or Tailwind Colors
You can choose between using CSS variables or Tailwind CSS utility classes for theming.
When you add new components, the CLI will automatically use the correct theming methods based on your `components.json` configuration.
#### Utility classes
```tsx /bg-zinc-950/ /text-zinc-50/ /dark:bg-white/ /dark:text-zinc-950/
```
To use utility classes for theming set `tailwind.cssVariables` to `false` in your `components.json` file.
```json {6} title="components.json" showLineNumbers
{
"tailwind": {
"config": "tailwind.config.js",
"css": "app/globals.css",
"baseColor": "slate",
"cssVariables": false
}
}
```
#### CSS Variables
```tsx /bg-background/ /text-foreground/
```
To use CSS variables classes for theming set `tailwind.cssVariables` to `true` in your `components.json` file.
```json {6} title="components.json" showLineNumbers
{
"tailwind": {
"config": "tailwind.config.js",
"css": "app/globals.css",
"baseColor": "slate",
"cssVariables": true
}
}
```
---
### Base color
You can now configure the base color for your project. This will be used to generate the default color palette for your components.
```json {5} title="components.json" showLineNumbers
{
"tailwind": {
"config": "tailwind.config.js",
"css": "app/globals.css",
"baseColor": "zinc",
"cssVariables": false
}
}
```
Choose between `gray`, `neutral`, `slate`, `stone` or `zinc`.
If you have `cssVariables` set to `true`, we will set the base colors as CSS variables in your `globals.css` file. If you have `cssVariables` set to `false`, we will inline the Tailwind CSS utility classes in your components.
---
### React Server Components
If you're using a framework that does not support React Server Components, you can now opt out by setting `rsc` to `false`. We will automatically append or remove the `use client` directive when adding components.
```json title="components.json" showLineNumbers
{
"rsc": false
}
```
---
### Styles
We are introducing a new concept called _Style_.
_You can think of style as the visual foundation: shapes, icons, animations & typography._ A style comes with its own set of components, animations, icons and more.
We are shipping two styles: `default` and `new-york` (with more coming soon).
The `default` style is the one you are used to. It's the one we've been using since the beginning of this project. It uses `lucide-react` for icons and `tailwindcss-animate` for animations.
The `new-york` style is a new style. It ships with smaller buttons, cards with shadows and a new set of icons from [Radix Icons](https://icons.radix-ui.com).
When you run the `init` command, you will be asked which style you would like to use. This is saved in your `components.json` file.
```json title="components.json" showLineNumbers
{
"style": "new-york"
}
```
### Theming
Start with a style as the base then theme using CSS variables or Tailwind CSS utility classes to completely change the look of your components.
---
### Exit animations
I added exit animations to all components. Click on the combobox below to see the subtle exit animation.
The animations can be customized using utility classes.
---
### Other updates
### Button
- Added a new button size `icon`:
### Sheet
- Renamed `position` to `side` to match the other elements.
- Removed the `size` props. Use `className="w-[200px] md:w-[450px]"` for responsive sizing.
---
### Updating your project
Since we follow a copy and paste approach, you will need to manually update your project to get the latest changes.
Note: we are working on a [`diff`](#diff-experimental) command to help you
keep track of upstream updates.
### Add `components.json`
Creating a `components.json` file at the root:
```json title="components.json" showLineNumbers
{
"style": "default",
"rsc": true,
"tailwind": {
"config": "tailwind.config.js",
"css": "app/globals.css",
"baseColor": "slate",
"cssVariables": true
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils"
}
}
```
Update the values for `tailwind.css` and `aliases` to match your project structure.
### Button
Add the `icon` size to the `buttonVariants`:
```tsx {7} title="components/ui/button.tsx" showLineNumbers
const buttonVariants = cva({
variants: {
size: {
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
lg: "h-11 rounded-md px-8",
icon: "h-10 w-10",
},
},
})
```
### Sheet
1. Replace the content of `sheet.tsx` with the following:
```tsx title="components/ui/sheet.tsx" showLineNumbers
"use client"
import * as React from "react"
import * as SheetPrimitive from "@radix-ui/react-dialog"
import { cva, type VariantProps } from "class-variance-authority"
import { X } from "lucide-react"
import { cn } from "@/lib/utils"
const Sheet = SheetPrimitive.Root
const SheetTrigger = SheetPrimitive.Trigger
const SheetClose = SheetPrimitive.Close
const SheetPortal = ({
className,
...props
}: SheetPrimitive.DialogPortalProps) => (
)
SheetPortal.displayName = SheetPrimitive.Portal.displayName
const SheetOverlay = React.forwardRef<
React.ElementRef,
React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
))
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName
const sheetVariants = cva(
"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
{
variants: {
side: {
top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
bottom:
"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
right:
"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
},
},
defaultVariants: {
side: "right",
},
}
)
interface SheetContentProps
extends React.ComponentPropsWithoutRef,
VariantProps {}
const SheetContent = React.forwardRef<
React.ElementRef,
SheetContentProps
>(({ side = "right", className, children, ...props }, ref) => (
{children}
Close
))
SheetContent.displayName = SheetPrimitive.Content.displayName
const SheetHeader = ({
className,
...props
}: React.HTMLAttributes) => (
)
SheetHeader.displayName = "SheetHeader"
const SheetFooter = ({
className,
...props
}: React.HTMLAttributes) => (
)
SheetFooter.displayName = "SheetFooter"
const SheetTitle = React.forwardRef<
React.ElementRef,
React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
))
SheetTitle.displayName = SheetPrimitive.Title.displayName
const SheetDescription = React.forwardRef<
React.ElementRef,
React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
))
SheetDescription.displayName = SheetPrimitive.Description.displayName
export {
Sheet,
SheetTrigger,
SheetClose,
SheetContent,
SheetHeader,
SheetFooter,
SheetTitle,
SheetDescription,
}
```
2. Rename `position` to `side`
```diff /position/ /side/
-
+
```
### Thank you
I'd like to thank everyone who has been using this project, providing feedback and contributing to it. I really appreciate it. Thank you 🙏
================================================
FILE: apps/v4/content/docs/(root)/cli.mdx
================================================
---
title: shadcn
description: Use the shadcn CLI to add components to your project.
---
## init
Use the `init` command to initialize configuration and dependencies for a new project.
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 name, url or local path to component
Options:
-t, --template the template to use. (next, next-monorepo)
-b, --base-color the base color to use. (neutral, gray, zinc, stone, slate)
-y, --yes skip confirmation prompt. (default: true)
-f, --force force overwrite of existing configuration. (default: false)
-c, --cwd the working directory. defaults to the current directory.
-s, --silent mute output. (default: false)
--src-dir use the src directory when creating a new project. (default: false)
--no-src-dir do not use the src directory when creating a new project.
--css-variables use css variables for theming. (default: true)
--no-css-variables do not use css variables for theming.
-h, --help display help for command
```
## 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 the working directory. defaults to the current directory.
-a, --all add all available components (default: false)
-p, --path the path to add the component to.
-s, --silent mute output. (default: false)
--src-dir use the src directory when creating a new project. (default: false)
--no-src-dir do not use the src directory when creating a new project.
--css-variables use css variables for theming. (default: true)
--no-css-variables do not use css variables for theming.
-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 destination directory for json files (default: "./public/r")
-c, --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
```
================================================
FILE: apps/v4/content/docs/(root)/components-json.mdx
================================================
---
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.
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.
You can create a `components.json` file in your project by running the following command:
```bash
npx shadcn@latest init
```
See the CLI section 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 installation section 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 color palette for your components. **This cannot be changed after initialization.**
```json title="components.json"
{
"tailwind": {
"baseColor": "gray" | "neutral" | "slate" | "stone" | "zinc"
}
}
```
### tailwind.cssVariables
You can choose between using CSS variables or Tailwind CSS utility classes for theming.
To use utility classes for theming set `tailwind.cssVariables` to `false`. For CSS variables, set `tailwind.cssVariables` to `true`.
```json title="components.json"
{
"tailwind": {
"cssVariables": `true` | `false`
}
}
```
For more information, see the theming docs.
**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 and the `paths` config from your `tsconfig.json` or `jsconfig.json` file to place generated components in the correct location.
Path aliases have to be set up in your `tsconfig.json` or `jsconfig.json` file.
**Important:** If you're using the `src` directory, make sure it is included
under `paths` in your `tsconfig.json` or `jsconfig.json` file.
### 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"
}
}
```
================================================
FILE: apps/v4/content/docs/(root)/figma.mdx
================================================
---
title: Figma
description: Every component recreated in Figma. With customizable props, typography and icons.
---
**Note:** The Figma files are contributed by the community. If you have any
questions or feedback, please reach out to the Figma file maintainers.
## 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.
## Free
- [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](https://www.figma.com/community/file/1514746685758799870/obra-shadcn-ui) by [Obra Studio](https://obra.studio/) - Carefully crafted kit designed in the philosophy of shadcn, tracks v4, MIT licensed
================================================
FILE: apps/v4/content/docs/(root)/index.mdx
================================================
---
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._
How do I pull upstream updates in an Open Code approach?
shadcn/ui follows a headless component architecture. This means the core
of your app can receive fixes by updating your dependencies, for
instance, radix-ui or input-otp.
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.
## 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._
================================================
FILE: apps/v4/content/docs/(root)/javascript.mdx
================================================
---
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 {10} title="components.json" showLineNumbers
{
"style": "default",
"tailwind": {
"config": "tailwind.config.js",
"css": "src/app/globals.css",
"baseColor": "zinc",
"cssVariables": true
},
"rsc": false,
"tsx": false,
"aliases": {
"utils": "~/lib/utils",
"components": "~/components"
}
}
```
To configure import aliases, you can use the following `jsconfig.json`:
```json {4} title="jsconfig.json" showLineNumbers
{
"compilerOptions": {
"paths": {
"@/*": ["./*"]
}
}
}
```
================================================
FILE: apps/v4/content/docs/(root)/legacy.mdx
================================================
---
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).
================================================
FILE: apps/v4/content/docs/(root)/meta.json
================================================
{
"title": "Get Started",
"pages": [
"index",
"[Installation](/docs/installation)",
"components-json",
"theming",
"[Dark Mode](/docs/dark-mode)",
"[CLI](/docs/cli)",
"monorepo",
"typography",
"v0",
"javascript",
"blocks",
"figma",
"changelog",
"legacy"
]
}
================================================
FILE: apps/v4/content/docs/(root)/monorepo.mdx
================================================
---
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
### Create a new monorepo project
To create a new monorepo project, run the `init` command. You will be prompted
to select the type of project you are creating.
```bash
npx shadcn@canary init
```
Select the `Next.js (Monorepo)` option.
```bash
? Would you like to start a new project?
Next.js
❯ Next.js (Monorepo)
```
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.
Note: The monorepo uses React 19 and Tailwind CSS v4.
### 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@canary 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@canary 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@canary 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"
```
## 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": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "",
"css": "../../packages/ui/src/styles/globals.css",
"baseColor": "zinc",
"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": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/styles/globals.css",
"baseColor": "zinc",
"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.
================================================
FILE: apps/v4/content/docs/(root)/react-19.mdx
================================================
---
title: Next.js 15 + React 19
description: Using shadcn/ui with Next.js 15 and React 19.
---
**Update:** We have added full support for React 19 and Tailwind v4 in the
`canary` release. See the docs for [Tailwind v4](/docs/tailwind-v4) for more
information.
**The following guide applies to any framework that supports React 19**. I
titled this page "Next.js 15 + React 19" to help people upgrading to Next.js
15 find it. We are working with package maintainers to help upgrade to React
19.
## 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"
},
```
You can check if a package lists React 19 as a peer dependency by running
`npm info peerDependencies`.
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
```
**Note:** This is npm only. PNPM and Bun will only show a silent warning.
## 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 --force
npm i --legacy-peer-deps
```
This will install the package and ignore the peer dependency warnings.
What do the `--force` and `--legacy-peer-deps` flag do?
- `--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.
### 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 track the progress of the upgrade, I've created a table below with 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.
Add the following to your `package.json`
```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.
Run `npm install --legacy-peer-deps`
================================================
FILE: apps/v4/content/docs/(root)/styleguide.mdx
================================================
---
title: Styleguide
description: A styleguide for writing documentation in mdx.
---
The OpenAI API provides a simple interface to state-of-the-art AI models for text generation, natural language processing, computer vision, and more. This example generates text output from a prompt, as you might using ChatGPT.
## Analyze image inputs
You can provide image inputs to the model as well. Scan receipts, analyze screenshots, or find objects in the real world with [computer vision](/docs/installation/computer-vision). This is code in a `pre` tag and `npx` command in a `code` tag.
```bash
npm install foo
```
```bash
npx shadcn@latest init
```
```bash
npx shadcn@latest add button
```
```tsx
```
```tsx showLineNumbers
// With line numbers
export default function Home() {
return
Hello
}
```
```tsx title="Button.tsx"
export default function Button({ children }: { children: React.ReactNode }) {
return
}
```
This is a code block with a title.
## Line Numbers and Line Highlighting
Draw attention to a particular line of code.
```tsx {4} showLineNumbers
import { useFloating } from "@floating-ui/react"
function MyComponent() {
const { refs, floatingStyles } = useFloating()
return (
<>
>
)
}
```
## Word Highlighting
Draw attention to a particular word or series of characters.
```tsx /floatingStyles/
import { useFloating } from "@floating-ui/react"
function MyComponent() {
const { refs, floatingStyles } = useFloating()
return (
<>
>
)
}
```
How
```tsx title="apps/www/registry/registry-blocks.tsx"
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"],
},
]
```
```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
```
```diff showLineNumbers
- @plugin 'tailwindcss-animate';
+ @import "tw-animate-css";
```
## CSS Variables
```tsx /bg-background/ /text-foreground/
```
To use CSS variables for theming set `tailwind.cssVariables` to `true` in your `components.json` file.
```json {8} title="components.json"
{
"style": "default",
"rsc": true,
"tailwind": {
"config": "",
"css": "app/globals.css",
"baseColor": "neutral",
"cssVariables": true
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/registry/new-york-v4/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"iconLibrary": "lucide"
}
```
## Utility classes
```tsx /bg-zinc-950/ /text-zinc-50/ /dark:bg-white/ /dark:text-zinc-950/
```
To use utility classes for theming set `tailwind.cssVariables` to `false` in your `components.json` file.
```json {8} title="components.json"
{
"style": "default",
"rsc": true,
"tailwind": {
"config": "",
"css": "app/globals.css",
"baseColor": "slate",
"cssVariables": false
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/registry/new-york-v4/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"iconLibrary": "lucide"
}
```
================================================
FILE: apps/v4/content/docs/(root)/tailwind-v4.mdx
================================================
---
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 test Tailwind v4 + React 19 today using the `canary` release of the CLI. See the framework specific guides below for how to get started.
Next.js
Vite
Laravel
React Router
Astro
TanStack Start
Gatsby
Manual
## Upgrade Your Project
**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.
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 for eg. 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,
React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
))
AccordionItem.displayName = "AccordionItem"
```
#### After
```tsx showLineNumbers
function AccordionItem({
className,
...props
}: React.ComponentProps) {
return (
)
}
```
## Changelog
### March 19, 2025 - Deprecate `tailwindcss-animate`
We've deprecated `tailwindcss-animate` in favor of `tw-animate-css`.
New project 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 revisted 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].
Commit any changes
**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 "..."
```
Update components
```bash
npx shadcn@latest add --all --overwrite
```
Update colors
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.
Review changes
Review and re-apply any changes you made to your components.
[^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.
================================================
FILE: apps/v4/content/docs/(root)/theming.mdx
================================================
---
title: Theming
description: Using CSS Variables and color utilities for theming.
---
You can choose between using CSS variables (recommended) or utility classes for theming.
## CSS Variables
```tsx /bg-background/ /text-foreground/
```
To use CSS variables for theming set `tailwind.cssVariables` to `true` in your `components.json` file.
```json {8} title="components.json" showLineNumbers
{
"style": "default",
"rsc": true,
"tailwind": {
"config": "",
"css": "app/globals.css",
"baseColor": "neutral",
"cssVariables": true
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"iconLibrary": "lucide"
}
```
## Utility classes
```tsx /bg-zinc-950/ /text-zinc-50/ /dark:bg-white/ /dark:text-zinc-950/
```
To use utility classes for theming set `tailwind.cssVariables` to `false` in your `components.json` file.
```json {8} title="components.json" showLineNumbers
{
"style": "default",
"rsc": true,
"tailwind": {
"config": "",
"css": "app/globals.css",
"baseColor": "neutral",
"cssVariables": false
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"iconLibrary": "lucide"
}
```
## Convention
We use a simple `background` and `foreground` convention for colors. The `background` variable is used for the background color of the component and the `foreground` variable is used for the text color.
The `background` suffix is omitted when the variable is used for the background color of the component.
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
Hello
```
## List of variables
Here's the list of variables available for customization:
```css title="app/globals.css" showLineNumbers
: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.269 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.371 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.439 0 0);
}
```
## Adding new colors
To add new colors, you need to add them to your CSS file and to your `tailwind.config.js` file.
```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 the `warning` utility class in your components.
```tsx /bg-warning/ /text-warning-foreground/
```
## Other color formats
See the [Tailwind CSS documentation](https://tailwindcss.com/docs/colors) for more information on using colors in Tailwind CSS.
## Base Colors
For reference, here's a list of the base colors that are available.
### Neutral
```css title="app/globals.css" showLineNumbers
: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);
}
```
### Stone
```css title="app/globals.css" showLineNumbers
:root {
--radius: 0.625rem;
--background: oklch(1 0 0);
--foreground: oklch(0.147 0.004 49.25);
--card: oklch(1 0 0);
--card-foreground: oklch(0.147 0.004 49.25);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.147 0.004 49.25);
--primary: oklch(0.216 0.006 56.043);
--primary-foreground: oklch(0.985 0.001 106.423);
--secondary: oklch(0.97 0.001 106.424);
--secondary-foreground: oklch(0.216 0.006 56.043);
--muted: oklch(0.97 0.001 106.424);
--muted-foreground: oklch(0.553 0.013 58.071);
--accent: oklch(0.97 0.001 106.424);
--accent-foreground: oklch(0.216 0.006 56.043);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.923 0.003 48.717);
--input: oklch(0.923 0.003 48.717);
--ring: oklch(0.709 0.01 56.259);
--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.001 106.423);
--sidebar-foreground: oklch(0.147 0.004 49.25);
--sidebar-primary: oklch(0.216 0.006 56.043);
--sidebar-primary-foreground: oklch(0.985 0.001 106.423);
--sidebar-accent: oklch(0.97 0.001 106.424);
--sidebar-accent-foreground: oklch(0.216 0.006 56.043);
--sidebar-border: oklch(0.923 0.003 48.717);
--sidebar-ring: oklch(0.709 0.01 56.259);
}
.dark {
--background: oklch(0.147 0.004 49.25);
--foreground: oklch(0.985 0.001 106.423);
--card: oklch(0.216 0.006 56.043);
--card-foreground: oklch(0.985 0.001 106.423);
--popover: oklch(0.216 0.006 56.043);
--popover-foreground: oklch(0.985 0.001 106.423);
--primary: oklch(0.923 0.003 48.717);
--primary-foreground: oklch(0.216 0.006 56.043);
--secondary: oklch(0.268 0.007 34.298);
--secondary-foreground: oklch(0.985 0.001 106.423);
--muted: oklch(0.268 0.007 34.298);
--muted-foreground: oklch(0.709 0.01 56.259);
--accent: oklch(0.268 0.007 34.298);
--accent-foreground: oklch(0.985 0.001 106.423);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.553 0.013 58.071);
--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.216 0.006 56.043);
--sidebar-foreground: oklch(0.985 0.001 106.423);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0.001 106.423);
--sidebar-accent: oklch(0.268 0.007 34.298);
--sidebar-accent-foreground: oklch(0.985 0.001 106.423);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.553 0.013 58.071);
}
```
### Zinc
```css title="app/globals.css" showLineNumbers
:root {
--radius: 0.625rem;
--background: oklch(1 0 0);
--foreground: oklch(0.141 0.005 285.823);
--card: oklch(1 0 0);
--card-foreground: oklch(0.141 0.005 285.823);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.141 0.005 285.823);
--primary: oklch(0.21 0.006 285.885);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.967 0.001 286.375);
--secondary-foreground: oklch(0.21 0.006 285.885);
--muted: oklch(0.967 0.001 286.375);
--muted-foreground: oklch(0.552 0.016 285.938);
--accent: oklch(0.967 0.001 286.375);
--accent-foreground: oklch(0.21 0.006 285.885);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.92 0.004 286.32);
--input: oklch(0.92 0.004 286.32);
--ring: oklch(0.705 0.015 286.067);
--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.141 0.005 285.823);
--sidebar-primary: oklch(0.21 0.006 285.885);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.967 0.001 286.375);
--sidebar-accent-foreground: oklch(0.21 0.006 285.885);
--sidebar-border: oklch(0.92 0.004 286.32);
--sidebar-ring: oklch(0.705 0.015 286.067);
}
.dark {
--background: oklch(0.141 0.005 285.823);
--foreground: oklch(0.985 0 0);
--card: oklch(0.21 0.006 285.885);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.21 0.006 285.885);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.92 0.004 286.32);
--primary-foreground: oklch(0.21 0.006 285.885);
--secondary: oklch(0.274 0.006 286.033);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.274 0.006 286.033);
--muted-foreground: oklch(0.705 0.015 286.067);
--accent: oklch(0.274 0.006 286.033);
--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.552 0.016 285.938);
--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.21 0.006 285.885);
--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.274 0.006 286.033);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.552 0.016 285.938);
}
```
### Gray
```css title="app/globals.css" showLineNumbers
:root {
--radius: 0.625rem;
--background: oklch(1 0 0);
--foreground: oklch(0.13 0.028 261.692);
--card: oklch(1 0 0);
--card-foreground: oklch(0.13 0.028 261.692);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.13 0.028 261.692);
--primary: oklch(0.21 0.034 264.665);
--primary-foreground: oklch(0.985 0.002 247.839);
--secondary: oklch(0.967 0.003 264.542);
--secondary-foreground: oklch(0.21 0.034 264.665);
--muted: oklch(0.967 0.003 264.542);
--muted-foreground: oklch(0.551 0.027 264.364);
--accent: oklch(0.967 0.003 264.542);
--accent-foreground: oklch(0.21 0.034 264.665);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.928 0.006 264.531);
--input: oklch(0.928 0.006 264.531);
--ring: oklch(0.707 0.022 261.325);
--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.002 247.839);
--sidebar-foreground: oklch(0.13 0.028 261.692);
--sidebar-primary: oklch(0.21 0.034 264.665);
--sidebar-primary-foreground: oklch(0.985 0.002 247.839);
--sidebar-accent: oklch(0.967 0.003 264.542);
--sidebar-accent-foreground: oklch(0.21 0.034 264.665);
--sidebar-border: oklch(0.928 0.006 264.531);
--sidebar-ring: oklch(0.707 0.022 261.325);
}
.dark {
--background: oklch(0.13 0.028 261.692);
--foreground: oklch(0.985 0.002 247.839);
--card: oklch(0.21 0.034 264.665);
--card-foreground: oklch(0.985 0.002 247.839);
--popover: oklch(0.21 0.034 264.665);
--popover-foreground: oklch(0.985 0.002 247.839);
--primary: oklch(0.928 0.006 264.531);
--primary-foreground: oklch(0.21 0.034 264.665);
--secondary: oklch(0.278 0.033 256.848);
--secondary-foreground: oklch(0.985 0.002 247.839);
--muted: oklch(0.278 0.033 256.848);
--muted-foreground: oklch(0.707 0.022 261.325);
--accent: oklch(0.278 0.033 256.848);
--accent-foreground: oklch(0.985 0.002 247.839);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.551 0.027 264.364);
--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.21 0.034 264.665);
--sidebar-foreground: oklch(0.985 0.002 247.839);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0.002 247.839);
--sidebar-accent: oklch(0.278 0.033 256.848);
--sidebar-accent-foreground: oklch(0.985 0.002 247.839);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.551 0.027 264.364);
}
```
### Slate
```css title="app/globals.css" showLineNumbers
:root {
--radius: 0.625rem;
--background: oklch(1 0 0);
--foreground: oklch(0.129 0.042 264.695);
--card: oklch(1 0 0);
--card-foreground: oklch(0.129 0.042 264.695);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.129 0.042 264.695);
--primary: oklch(0.208 0.042 265.755);
--primary-foreground: oklch(0.984 0.003 247.858);
--secondary: oklch(0.968 0.007 247.896);
--secondary-foreground: oklch(0.208 0.042 265.755);
--muted: oklch(0.968 0.007 247.896);
--muted-foreground: oklch(0.554 0.046 257.417);
--accent: oklch(0.968 0.007 247.896);
--accent-foreground: oklch(0.208 0.042 265.755);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.929 0.013 255.508);
--input: oklch(0.929 0.013 255.508);
--ring: oklch(0.704 0.04 256.788);
--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.984 0.003 247.858);
--sidebar-foreground: oklch(0.129 0.042 264.695);
--sidebar-primary: oklch(0.208 0.042 265.755);
--sidebar-primary-foreground: oklch(0.984 0.003 247.858);
--sidebar-accent: oklch(0.968 0.007 247.896);
--sidebar-accent-foreground: oklch(0.208 0.042 265.755);
--sidebar-border: oklch(0.929 0.013 255.508);
--sidebar-ring: oklch(0.704 0.04 256.788);
}
.dark {
--background: oklch(0.129 0.042 264.695);
--foreground: oklch(0.984 0.003 247.858);
--card: oklch(0.208 0.042 265.755);
--card-foreground: oklch(0.984 0.003 247.858);
--popover: oklch(0.208 0.042 265.755);
--popover-foreground: oklch(0.984 0.003 247.858);
--primary: oklch(0.929 0.013 255.508);
--primary-foreground: oklch(0.208 0.042 265.755);
--secondary: oklch(0.279 0.041 260.031);
--secondary-foreground: oklch(0.984 0.003 247.858);
--muted: oklch(0.279 0.041 260.031);
--muted-foreground: oklch(0.704 0.04 256.788);
--accent: oklch(0.279 0.041 260.031);
--accent-foreground: oklch(0.984 0.003 247.858);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.551 0.027 264.364);
--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.208 0.042 265.755);
--sidebar-foreground: oklch(0.984 0.003 247.858);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.984 0.003 247.858);
--sidebar-accent: oklch(0.279 0.041 260.031);
--sidebar-accent-foreground: oklch(0.984 0.003 247.858);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.551 0.027 264.364);
}
```
================================================
FILE: apps/v4/content/docs/(root)/v0.mdx
================================================
---
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.
Open in v0
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).
================================================
FILE: apps/v4/content/docs/components/accordion.mdx
================================================
---
title: Accordion
description: A vertically stacked set of interactive headings that each reveal a section of content.
component: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/accordion
api: https://www.radix-ui.com/docs/primitives/components/accordion#api-reference
---
## Installation
CLIManual
```bash
npx shadcn@latest add accordion
```
Install the following dependencies:
```bash
npm install @radix-ui/react-accordion
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion"
```
```tsx showLineNumbers
Is it accessible?
Yes. It adheres to the WAI-ARIA design pattern.
```
================================================
FILE: apps/v4/content/docs/components/alert-dialog.mdx
================================================
---
title: Alert Dialog
description: A modal dialog that interrupts the user with important content and expects a response.
featured: true
component: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/alert-dialog
api: https://www.radix-ui.com/docs/primitives/components/alert-dialog#api-reference
---
## Installation
CLIManual
```bash
npx shadcn@latest add alert-dialog
```
Install the following dependencies:
```bash
npm install @radix-ui/react-alert-dialog
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from "@/components/ui/alert-dialog"
```
```tsx showLineNumbers
OpenAre you absolutely sure?
This action cannot be undone. This will permanently delete your account
and remove your data from our servers.
CancelContinue
```
================================================
FILE: apps/v4/content/docs/components/alert.mdx
================================================
---
title: Alert
description: Displays a callout for user attention.
component: true
---
## Installation
CLIManual
```bash
npx shadcn@latest add alert
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
```
```tsx showLineNumbers
Heads up!
You can add components and dependencies to your app using the cli.
```
================================================
FILE: apps/v4/content/docs/components/aspect-ratio.mdx
================================================
---
title: Aspect Ratio
description: Displays content within a desired ratio.
component: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/aspect-ratio
api: https://www.radix-ui.com/docs/primitives/components/aspect-ratio#api-reference
---
## Installation
CLIManual
```bash
npx shadcn@latest add aspect-ratio
```
Install the following dependencies:
```bash
npm install @radix-ui/react-aspect-ratio
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import { AspectRatio } from "@/components/ui/aspect-ratio"
```
```tsx showLineNumbers
```
================================================
FILE: apps/v4/content/docs/components/avatar.mdx
================================================
---
title: Avatar
description: An image element with a fallback for representing the user.
component: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/avatar
api: https://www.radix-ui.com/docs/primitives/components/avatar#api-reference
---
## Installation
CLIManual
```bash
npx shadcn@latest add avatar
```
Install the following dependencies:
```bash
npm install @radix-ui/react-avatar
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
```
```tsx showLineNumbers
CN
```
================================================
FILE: apps/v4/content/docs/components/badge.mdx
================================================
---
title: Badge
description: Displays a badge or a component that looks like a badge.
component: true
---
## Installation
CLIManual
```bash
npx shadcn@latest add badge
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx
import { Badge } from "@/components/ui/badge"
```
```tsx
Badge
```
### Link
You can use the `asChild` prop to make another component look like a badge. Here's an example of a link that looks like a badge.
```tsx showLineNumbers
import { Link } from "next/link"
import { Badge } from "@/components/ui/badge"
export function LinkAsBadge() {
return (
Badge
)
}
```
================================================
FILE: apps/v4/content/docs/components/breadcrumb.mdx
================================================
---
title: Breadcrumb
description: Displays the path to the current resource using a hierarchy of links.
component: true
---
## Installation
CLIManual
```bash
npx shadcn@latest add breadcrumb
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from "@/components/ui/breadcrumb"
```
```tsx showLineNumbers
HomeComponentsBreadcrumb
```
## Examples
### Custom separator
Use a custom component as `children` for `` to create a custom separator.
```tsx showLineNumbers {1,10-12}
import { SlashIcon } from "lucide-react"
...
HomeComponents
```
---
### Dropdown
You can compose `` with a `` to create a dropdown in the breadcrumb.
```tsx showLineNumbers {1-6,11-21}
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
...
Components
DocumentationThemesGitHub
```
---
### Collapsed
We provide a `` component to show a collapsed state when the breadcrumb is too long.
```tsx showLineNumbers {1,9}
import { BreadcrumbEllipsis } from "@/components/ui/breadcrumb"
...
{/* ... */}
{/* ... */}
```
---
### Link component
To use a custom link component from your routing library, you can use the `asChild` prop on ``.
```tsx showLineNumbers {1,8-10}
import { Link } from "next/link"
...
Home
{/* ... */}
```
---
### Responsive
Here's an example of a responsive breadcrumb that composes `` with ``, ``, and ``.
It displays a dropdown on desktop and a drawer on mobile.
================================================
FILE: apps/v4/content/docs/components/button.mdx
================================================
---
title: Button
description: Displays a button or a component that looks like a button.
featured: true
component: true
---
## Installation
CLIManual
```bash
npx shadcn@latest add button
```
Install the following dependencies:
```bash
npm install @radix-ui/react-slot
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx
import { Button } from "@/components/ui/button"
```
```tsx
```
## Link
You can use the `asChild` prop to make another component look like a button. Here's an example of a link that looks like a button.
```tsx showLineNumbers
import { Link } from "next/link"
import { Button } from "@/components/ui/button"
export function LinkAsButton() {
return (
)
}
```
## Examples
### Default
### Secondary
### Destructive
### Outline
### Ghost
### Link
### Icon
### With Icon
### Loading
================================================
FILE: apps/v4/content/docs/components/calendar.mdx
================================================
---
title: Calendar
description: A date field component that allows users to enter and edit date.
component: true
links:
doc: https://react-day-picker.js.org
---
## Blocks
We have built a collection of 30+ calendar blocks that you can use to build your own calendar components.
See all calendar blocks in the [Blocks Library](/blocks/calendar) page.
## Installation
CLIManual
```bash
npx shadcn@latest add calendar
```
Install the following dependencies:
```bash
npm install react-day-picker date-fns
```
Add the `Button` component to your project.
The `Calendar` component uses the `Button` component. Make sure you have it installed in your project.
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import { Calendar } from "@/components/ui/calendar"
```
```tsx showLineNumbers
const [date, setDate] = React.useState(new Date())
return (
)
```
See the [React DayPicker](https://react-day-picker.js.org) documentation for more information.
## About
The `Calendar` component is built on top of [React DayPicker](https://react-day-picker.js.org).
## Customization
See the [React DayPicker](https://react-day-picker.js.org/docs/customization) documentation for more information on how to customize the `Calendar` component.
## Date Picker
You can use the `` component to build a date picker. See the [Date Picker](/docs/components/date-picker) page for more information.
## Persian / Hijri / Jalali Calendar
To use the Persian calendar, edit `components/ui/calendar.tsx` and replace `react-day-picker` with `react-day-picker/persian`.
```diff
- import { DayPicker } from "react-day-picker"
+ import { DayPicker } from "react-day-picker/persian"
```
## Examples
### Range Calendar
### Month and Year Selector
### Date of Birth Picker
### Date and Time Picker
### Natural Language Picker
This component uses the `chrono-node` library to parse natural language dates.
### Form
## Upgrade Guide
### Tailwind v4
If you're already using Tailwind v4, you can upgrade to the latest version of the `Calendar` component by running the following command:
```bash
npx shadcn@latest add calendar
```
When you're prompted to overwrite the existing `Calendar` component, select `Yes`. **If you have made any changes to the `Calendar` component, you will need to merge your changes with the new version.**
This will update the `Calendar` component and `react-day-picker` to the latest version.
Next, follow the [React DayPicker](https://daypicker.dev/upgrading) upgrade guide to upgrade your existing components to the latest version.
#### Installing Blocks
After upgrading the `Calendar` component, you can install the new blocks by running the `shadcn@latest add` command.
```bash
npx shadcn@latest add calendar-02
```
This will install the latest version of the calendar blocks.
### Tailwind v3
If you're using Tailwind v3, you can upgrade to the latest version of the `Calendar` by copying the following code to your `calendar.tsx` file.
```tsx showLineNumbers title="components/ui/calendar.tsx"
"use client"
import * as React from "react"
import {
ChevronDownIcon,
ChevronLeftIcon,
ChevronRightIcon,
} from "lucide-react"
import { DayButton, DayPicker, getDefaultClassNames } from "react-day-picker"
import { cn } from "@/lib/utils"
import { Button, buttonVariants } from "@/components/ui/button"
function Calendar({
className,
classNames,
showOutsideDays = true,
captionLayout = "label",
buttonVariant = "ghost",
formatters,
components,
...props
}: React.ComponentProps & {
buttonVariant?: React.ComponentProps["variant"]
}) {
const defaultClassNames = getDefaultClassNames()
return (
svg]:rotate-180`,
String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
className
)}
captionLayout={captionLayout}
formatters={{
formatMonthDropdown: (date) =>
date.toLocaleString("default", { month: "short" }),
...formatters,
}}
classNames={{
root: cn("w-fit", defaultClassNames.root),
months: cn(
"relative flex flex-col gap-4 md:flex-row",
defaultClassNames.months
),
month: cn("flex w-full flex-col gap-4", defaultClassNames.month),
nav: cn(
"absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1",
defaultClassNames.nav
),
button_previous: cn(
buttonVariants({ variant: buttonVariant }),
"h-[--cell-size] w-[--cell-size] select-none p-0 aria-disabled:opacity-50",
defaultClassNames.button_previous
),
button_next: cn(
buttonVariants({ variant: buttonVariant }),
"h-[--cell-size] w-[--cell-size] select-none p-0 aria-disabled:opacity-50",
defaultClassNames.button_next
),
month_caption: cn(
"flex h-[--cell-size] w-full items-center justify-center px-[--cell-size]",
defaultClassNames.month_caption
),
dropdowns: cn(
"flex h-[--cell-size] w-full items-center justify-center gap-1.5 text-sm font-medium",
defaultClassNames.dropdowns
),
dropdown_root: cn(
"has-focus:border-ring border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] relative rounded-md border",
defaultClassNames.dropdown_root
),
dropdown: cn("absolute inset-0 opacity-0", defaultClassNames.dropdown),
caption_label: cn(
"select-none font-medium",
captionLayout === "label"
? "text-sm"
: "[&>svg]:text-muted-foreground flex h-8 items-center gap-1 rounded-md pl-2 pr-1 text-sm [&>svg]:size-3.5",
defaultClassNames.caption_label
),
table: "w-full border-collapse",
weekdays: cn("flex", defaultClassNames.weekdays),
weekday: cn(
"text-muted-foreground flex-1 select-none rounded-md text-[0.8rem] font-normal",
defaultClassNames.weekday
),
week: cn("mt-2 flex w-full", defaultClassNames.week),
week_number_header: cn(
"w-[--cell-size] select-none",
defaultClassNames.week_number_header
),
week_number: cn(
"text-muted-foreground select-none text-[0.8rem]",
defaultClassNames.week_number
),
day: cn(
"group/day relative aspect-square h-full w-full select-none p-0 text-center [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md",
defaultClassNames.day
),
range_start: cn(
"bg-accent rounded-l-md",
defaultClassNames.range_start
),
range_middle: cn("rounded-none", defaultClassNames.range_middle),
range_end: cn("bg-accent rounded-r-md", defaultClassNames.range_end),
today: cn(
"bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none",
defaultClassNames.today
),
outside: cn(
"text-muted-foreground aria-selected:text-muted-foreground",
defaultClassNames.outside
),
disabled: cn(
"text-muted-foreground opacity-50",
defaultClassNames.disabled
),
hidden: cn("invisible", defaultClassNames.hidden),
...classNames,
}}
components={{
Root: ({ className, rootRef, ...props }) => {
return (
)
},
Chevron: ({ className, orientation, ...props }) => {
if (orientation === "left") {
return (
)
}
if (orientation === "right") {
return (
)
}
return (
)
},
DayButton: CalendarDayButton,
WeekNumber: ({ children, ...props }) => {
return (
{children}
)
},
...components,
}}
{...props}
/>
)
}
function CalendarDayButton({
className,
day,
modifiers,
...props
}: React.ComponentProps) {
const defaultClassNames = getDefaultClassNames()
const ref = React.useRef(null)
React.useEffect(() => {
if (modifiers.focused) ref.current?.focus()
}, [modifiers.focused])
return (
**If you have made any changes to the `Calendar` component, you will need to merge your changes with the new version.**
Then follow the [React DayPicker](https://daypicker.dev/upgrading) upgrade guide to upgrade your dependencies and existing components to the latest version.
#### Installing Blocks
After upgrading the `Calendar` component, you can install the new blocks by running the `shadcn@latest add` command.
```bash
npx shadcn@latest add calendar-02
```
This will install the latest version of the calendar blocks.
================================================
FILE: apps/v4/content/docs/components/card.mdx
================================================
---
title: Card
description: Displays a card with header, content, and footer.
component: true
---
## Installation
CLIManual
```bash
npx shadcn@latest add card
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import {
Card,
CardAction,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card"
```
```tsx showLineNumbers
Card TitleCard DescriptionCard Action
Card Content
Card Footer
```
================================================
FILE: apps/v4/content/docs/components/carousel.mdx
================================================
---
title: Carousel
description: A carousel with motion and swipe built using Embla.
component: true
links:
doc: https://www.embla-carousel.com/get-started/react
api: https://www.embla-carousel.com/api
---
## About
The carousel component is built using the [Embla Carousel](https://www.embla-carousel.com/) library.
## Installation
CLIManual
```bash
npx shadcn@latest add carousel
```
Install the following dependencies:
```bash
npm install embla-carousel-react
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from "@/components/ui/carousel"
```
```tsx showLineNumbers
.........
```
## Examples
### Sizes
To set the size of the items, you can use the `basis` utility class on the ``.
```tsx showLineNumbers {4-6}
// 33% of the carousel width.
.........
```
```tsx showLineNumbers {4-6}
// 50% on small screens and 33% on larger screens.
.........
```
### Spacing
To set the spacing between the items, we use a `pl-[VALUE]` utility on the `` and a negative `-ml-[VALUE]` on the ``.
**Why:** I tried to use the `gap` property or a `grid` layout on the `
` but it required a lot of math and mental effort to get the
spacing right. I found `pl-[VALUE]` and `-ml-[VALUE]` utilities much easier to
use.
You can always adjust this in your own project if you need to.
```tsx showLineNumbers /-ml-4/ /pl-4/
.........
```
```tsx showLineNumbers /-ml-2/ /pl-2/ /md:-ml-4/ /md:pl-4/
.........
```
### Orientation
Use the `orientation` prop to set the orientation of the carousel.
```tsx showLineNumbers /vertical | horizontal/
.........
```
## Options
You can pass options to the carousel using the `opts` prop. See the [Embla Carousel docs](https://www.embla-carousel.com/api/options/) for more information.
```tsx showLineNumbers {2-5}
.........
```
## API
Use a state and the `setApi` props to get an instance of the carousel API.
```tsx showLineNumbers {1,4,22}
import { type CarouselApi } from "@/components/ui/carousel"
export function Example() {
const [api, setApi] = React.useState()
const [current, setCurrent] = React.useState(0)
const [count, setCount] = React.useState(0)
React.useEffect(() => {
if (!api) {
return
}
setCount(api.scrollSnapList().length)
setCurrent(api.selectedScrollSnap() + 1)
api.on("select", () => {
setCurrent(api.selectedScrollSnap() + 1)
})
}, [api])
return (
.........
)
}
```
## Events
You can listen to events using the api instance from `setApi`.
```tsx showLineNumbers {1,4-14,16}
import { type CarouselApi } from "@/components/ui/carousel"
export function Example() {
const [api, setApi] = React.useState()
React.useEffect(() => {
if (!api) {
return
}
api.on("select", () => {
// Do something on select.
})
}, [api])
return (
.........
)
}
```
See the [Embla Carousel docs](https://www.embla-carousel.com/api/events/) for more information on using events.
## Plugins
You can use the `plugins` prop to add plugins to the carousel.
```ts showLineNumbers {1,6-10}
import Autoplay from "embla-carousel-autoplay"
export function Example() {
return (
// ...
)
}
```
See the [Embla Carousel docs](https://www.embla-carousel.com/api/plugins/) for more information on using plugins.
================================================
FILE: apps/v4/content/docs/components/chart.mdx
================================================
---
title: Chart
description: Beautiful charts. Built using Recharts. Copy and paste into your apps.
component: true
---
**Note:** We're working on upgrading to Recharts v3. In the meantime, if you'd like to start testing v3, see the code in the comment [here](https://github.com/shadcn-ui/ui/issues/7669#issuecomment-2998299159). We'll have an official release soon.
Introducing **Charts**. A collection of chart components that you can copy and paste into your apps.
Charts are designed to look great out of the box. They work well with the other components and are fully customizable to fit your project.
[Browse the Charts Library](/charts).
## Component
We use [Recharts](https://recharts.org/) under the hood.
We designed the `chart` component with composition in mind. **You build your charts using Recharts components and only bring in custom components, such as `ChartTooltip`, when and where you need it**.
```tsx showLineNumbers /ChartContainer/ /ChartTooltipContent/
import { Bar, BarChart } from "recharts"
import { ChartContainer, ChartTooltipContent } from "@/components/ui/charts"
export function MyChart() {
return (
} />
)
}
```
We do not wrap Recharts. This means you're not locked into an abstraction. When a new Recharts version is released, you can follow the official upgrade path to upgrade your charts.
**The components are yours**.
## Installation
**Note:** If you are using charts with **React 19** or the **Next.js 15**, see the note [here](/docs/react-19#recharts).
CLIManualRun the following command to install `chart.tsx`
```bash
npx shadcn@latest add chart
```
Add the following colors to your CSS file
```css title="app/globals.css" showLineNumbers
@layer base {
:root {
--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);
}
.dark {
--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);
}
}
```
Install the following dependencies:
```bash
npm install recharts
```
Copy and paste the following code into `components/ui/chart.tsx`.Add the following colors to your CSS file
```css title="app/globals.css" showLineNumbers
@layer base {
:root {
--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);
}
.dark {
--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);
}
}
```
## Your First Chart
Let's build your first chart. We'll build a bar chart, add a grid, axis, tooltip and legend.
Start by defining your data
The following data represents the number of desktop and mobile users for each month.
**Note:** Your data can be in any shape. You are not limited to the shape of the data below. Use the `dataKey` prop to map your data to the chart.
```tsx title="components/example-chart.tsx" showLineNumbers
const chartData = [
{ month: "January", desktop: 186, mobile: 80 },
{ month: "February", desktop: 305, mobile: 200 },
{ month: "March", desktop: 237, mobile: 120 },
{ month: "April", desktop: 73, mobile: 190 },
{ month: "May", desktop: 209, mobile: 130 },
{ month: "June", desktop: 214, mobile: 140 },
]
```
Define your chart config
The chart config holds configuration for the chart. This is where you place human-readable strings, such as labels, icons and color tokens for theming.
```tsx title="components/example-chart.tsx" showLineNumbers
import { type ChartConfig } from "@/components/ui/chart"
const chartConfig = {
desktop: {
label: "Desktop",
color: "#2563eb",
},
mobile: {
label: "Mobile",
color: "#60a5fa",
},
} satisfies ChartConfig
```
Build your chart
You can now build your chart using Recharts components.
**Important:** Remember to set a `min-h-[VALUE]` on the `ChartContainer` component. This is required for the chart be responsive.
### Add a Grid
Let's add a grid to the chart.
Import the `CartesianGrid` component.
```tsx /CartesianGrid/
import { Bar, BarChart, CartesianGrid } from "recharts"
```
Add the `CartesianGrid` component to your chart.
```tsx showLineNumbers {3}
```
### Add an Axis
To add an x-axis to the chart, we'll use the `XAxis` component.
Import the `XAxis` component.
```tsx /XAxis/
import { Bar, BarChart, CartesianGrid, XAxis } from "recharts"
```
Add the `XAxis` component to your chart.
```tsx showLineNumbers {4-10}
value.slice(0, 3)}
/>
```
### Add Tooltip
So far we've only used components from Recharts. They look great out of the box thanks to some customization in the `chart` component.
To add a tooltip, we'll use the custom `ChartTooltip` and `ChartTooltipContent` components from `chart`.
Import the `ChartTooltip` and `ChartTooltipContent` components.
```tsx
import { ChartTooltip, ChartTooltipContent } from "@/components/ui/chart"
```
Add the components to your chart.
```tsx showLineNumbers {11}
value.slice(0, 3)}
/>
} />
```
Hover to see the tooltips. Easy, right? Two components, and we've got a beautiful tooltip.
### Add Legend
We'll do the same for the legend. We'll use the `ChartLegend` and `ChartLegendContent` components from `chart`.
Import the `ChartLegend` and `ChartLegendContent` components.
```tsx
import { ChartLegend, ChartLegendContent } from "@/components/ui/chart"
```
Add the components to your chart.
```tsx showLineNumbers {12}
value.slice(0, 3)}
/>
} />
} />
```
Done. You've built your first chart! What's next?
- [Themes and Colors](/docs/components/chart#theming)
- [Tooltip](/docs/components/chart#tooltip)
- [Legend](/docs/components/chart#legend)
## Chart Config
The chart config is where you define the labels, icons and colors for a chart.
It is intentionally decoupled from chart data.
This allows you to share config and color tokens between charts. It can also works independently for cases where your data or color tokens live remotely or in a different format.
```tsx showLineNumbers /ChartConfig/
import { Monitor } from "lucide-react"
import { type ChartConfig } from "@/components/ui/chart"
const chartConfig = {
desktop: {
label: "Desktop",
icon: Monitor,
// A color like 'hsl(220, 98%, 61%)' or 'var(--color-name)'
color: "#2563eb",
// OR a theme object with 'light' and 'dark' keys
theme: {
light: "#2563eb",
dark: "#dc2626",
},
},
} satisfies ChartConfig
```
## Theming
Charts has built-in support for theming. You can use css variables (recommended) or color values in any color format, such as hex, hsl or oklch.
### CSS Variables
Define your colors in your css file
```css {6-7,14-15} title="app/globals.css" showLineNumbers
@layer base {
:root {
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
}
.dark: {
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
}
}
```
Add the color to your `chartConfig`
```tsx {4,8} showLineNumbers
const chartConfig = {
desktop: {
label: "Desktop",
color: "var(--chart-1)",
},
mobile: {
label: "Mobile",
color: "var(--chart-2)",
},
} satisfies ChartConfig
```
### hex, hsl or oklch
You can also define your colors directly in the chart config. Use the color format you prefer.
```tsx showLineNumbers
const chartConfig = {
desktop: {
label: "Desktop",
color: "#2563eb",
},
} satisfies ChartConfig
```
### Using Colors
To use the theme colors in your chart, reference the colors using the format `var(--color-KEY)`.
#### Components
```tsx
```
#### Chart Data
```tsx showLineNumbers
const chartData = [
{ browser: "chrome", visitors: 275, fill: "var(--color-chrome)" },
{ browser: "safari", visitors: 200, fill: "var(--color-safari)" },
]
```
#### Tailwind
```tsx
```
## Tooltip
A chart tooltip contains a label, name, indicator and value. You can use a combination of these to customize your tooltip.
You can turn on/off any of these using the `hideLabel`, `hideIndicator` props and customize the indicator style using the `indicator` prop.
Use `labelKey` and `nameKey` to use a custom key for the tooltip label and name.
Chart comes with the `` and `` components. You can use these two components to add custom tooltips to your chart.
```tsx
import { ChartTooltip, ChartTooltipContent } from "@/components/ui/chart"
```
```tsx
} />
```
### Props
Use the following props to customize the tooltip.
| Prop | Type | Description |
| :-------------- | :----------------------- | :------------------------------------------- |
| `labelKey` | string | The config or data key to use for the label. |
| `nameKey` | string | The config or data key to use for the name. |
| `indicator` | `dot` `line` or `dashed` | The indicator style for the tooltip. |
| `hideLabel` | boolean | Whether to hide the label. |
| `hideIndicator` | boolean | Whether to hide the indicator. |
### Colors
Colors are automatically referenced from the chart config.
### Custom
To use a custom key for tooltip label and names, use the `labelKey` and `nameKey` props.
```tsx showLineNumbers /browser/
const chartData = [
{ browser: "chrome", visitors: 187, fill: "var(--color-chrome)" },
{ browser: "safari", visitors: 200, fill: "var(--color-safari)" },
]
const chartConfig = {
visitors: {
label: "Total Visitors",
},
chrome: {
label: "Chrome",
color: "hsl(var(--chart-1))",
},
safari: {
label: "Safari",
color: "hsl(var(--chart-2))",
},
} satisfies ChartConfig
```
```tsx
}
/>
```
This will use `Total Visitors` for label and `Chrome` and `Safari` for the tooltip names.
## Legend
You can use the custom `` and `` components to add a legend to your chart.
```tsx
import { ChartLegend, ChartLegendContent } from "@/components/ui/chart"
```
```tsx
} />
```
### Colors
Colors are automatically referenced from the chart config.
### Custom
To use a custom key for legend names, use the `nameKey` prop.
```tsx showLineNumbers /browser/
const chartData = [
{ browser: "chrome", visitors: 187, fill: "var(--color-chrome)" },
{ browser: "safari", visitors: 200, fill: "var(--color-safari)" },
]
const chartConfig = {
chrome: {
label: "Chrome",
color: "hsl(var(--chart-1))",
},
safari: {
label: "Safari",
color: "hsl(var(--chart-2))",
},
} satisfies ChartConfig
```
```tsx
} />
```
This will use `Chrome` and `Safari` for the legend names.
## Accessibility
You can turn on the `accessibilityLayer` prop to add an accessible layer to your chart.
This prop adds keyboard access and screen reader support to your charts.
```tsx
```
================================================
FILE: apps/v4/content/docs/components/checkbox.mdx
================================================
---
title: Checkbox
description: A control that allows the user to toggle between checked and not checked.
component: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/checkbox
api: https://www.radix-ui.com/docs/primitives/components/checkbox#api-reference
---
## Installation
CLIManual
```bash
npx shadcn@latest add checkbox
```
Install the following dependencies:
```bash
npm install @radix-ui/react-checkbox
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx
import { Checkbox } from "@/components/ui/checkbox"
```
```tsx
```
## Examples
### Form
================================================
FILE: apps/v4/content/docs/components/collapsible.mdx
================================================
---
title: Collapsible
description: An interactive component which expands/collapses a panel.
component: true
featured: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/collapsible
api: https://www.radix-ui.com/docs/primitives/components/collapsible#api-reference
---
## Installation
CLIManual
```bash
npx shadcn@latest add collapsible
```
Install the following dependencies:
```bash
npm install @radix-ui/react-collapsible
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "@/components/ui/collapsible"
```
```tsx showLineNumbers
Can I use this in my project?
Yes. Free to use for personal and commercial projects. No attribution
required.
```
================================================
FILE: apps/v4/content/docs/components/combobox.mdx
================================================
---
title: Combobox
description: Autocomplete input and command palette with a list of suggestions.
component: true
---
## Installation
The Combobox is built using a composition of the `` and the `` components.
See installation instructions for the [Popover](/docs/components/popover#installation) and the [Command](/docs/components/command#installation) components.
## Usage
```tsx showLineNumbers title="components/example-combobox.tsx"
"use client"
import * as React from "react"
import { CheckIcon, ChevronsUpDownIcon } from "lucide-react"
import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from "@/components/ui/command"
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover"
const frameworks = [
{
value: "next.js",
label: "Next.js",
},
{
value: "sveltekit",
label: "SvelteKit",
},
{
value: "nuxt.js",
label: "Nuxt.js",
},
{
value: "remix",
label: "Remix",
},
{
value: "astro",
label: "Astro",
},
]
export function ExampleCombobox() {
const [open, setOpen] = React.useState(false)
const [value, setValue] = React.useState("")
return (
No framework found.
{frameworks.map((framework) => (
{
setValue(currentValue === value ? "" : currentValue)
setOpen(false)
}}
>
{framework.label}
))}
)
}
```
## Examples
### Combobox
### Popover
### Dropdown menu
### Responsive
You can create a responsive combobox by using the `` on desktop and the `` components on mobile.
### Form
================================================
FILE: apps/v4/content/docs/components/command.mdx
================================================
---
title: Command
description: Fast, composable, unstyled command menu for React.
component: true
links:
doc: https://cmdk.paco.me
---
## About
The `` component uses the [`cmdk`](https://cmdk.paco.me) component by [pacocoursey](https://twitter.com/pacocoursey).
## Installation
CLIManual
```bash
npx shadcn@latest add command
```
Install the following dependencies:
```bash
npm install cmdk
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import {
Command,
CommandDialog,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
CommandSeparator,
CommandShortcut,
} from "@/components/ui/command"
```
```tsx showLineNumbers
No results found.CalendarSearch EmojiCalculatorProfileBillingSettings
```
## Examples
### Dialog
To show the command menu in a dialog, use the `` component.
```tsx showLineNumbers title="components/example-command-menu.tsx"
export function CommandMenu() {
const [open, setOpen] = React.useState(false)
React.useEffect(() => {
const down = (e: KeyboardEvent) => {
if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
e.preventDefault()
setOpen((open) => !open)
}
}
document.addEventListener("keydown", down)
return () => document.removeEventListener("keydown", down)
}, [])
return (
No results found.CalendarSearch EmojiCalculator
)
}
```
### Combobox
You can use the `` component as a combobox. See the [Combobox](/docs/components/combobox) page for more information.
================================================
FILE: apps/v4/content/docs/components/context-menu.mdx
================================================
---
title: Context Menu
description: Displays a menu to the user — such as a set of actions or functions — triggered by a button.
component: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/context-menu
api: https://www.radix-ui.com/docs/primitives/components/context-menu#api-reference
---
## Installation
CLIManual
```bash
npx shadcn@latest add context-menu
```
Install the following dependencies:
```bash
npm install @radix-ui/react-context-menu
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import {
ContextMenu,
ContextMenuContent,
ContextMenuItem,
ContextMenuTrigger,
} from "@/components/ui/context-menu"
```
```tsx showLineNumbers
Right clickProfileBillingTeamSubscription
```
================================================
FILE: apps/v4/content/docs/components/data-table.mdx
================================================
---
title: Data Table
description: Powerful table and datagrids built using TanStack Table.
component: true
links:
doc: https://tanstack.com/table/v8/docs/introduction
---
## Introduction
Every data table or datagrid I've created has been unique. They all behave differently, have specific sorting and filtering requirements, and work with different data sources.
It doesn't make sense to combine all of these variations into a single component. If we do that, we'll lose the flexibility that [headless UI](https://tanstack.com/table/v8/docs/introduction#what-is-headless-ui) provides.
So instead of a data-table component, I thought it would be more helpful to provide a guide on how to build your own.
We'll start with the basic `
` component and build a complex data table from scratch.
**Tip:** If you find yourself using the same table in multiple places in your app, you can always extract it into a reusable component.
## Table of Contents
This guide will show you how to use [TanStack Table](https://tanstack.com/table) and the `
` component to build your own custom data table. We'll cover the following topics:
- [Basic Table](#basic-table)
- [Row Actions](#row-actions)
- [Pagination](#pagination)
- [Sorting](#sorting)
- [Filtering](#filtering)
- [Visibility](#visibility)
- [Row Selection](#row-selection)
- [Reusable Components](#reusable-components)
## Installation
1. Add the `
` component to your project:
```bash
npx shadcn@latest add table
```
2. Add `tanstack/react-table` dependency:
```bash
npm install @tanstack/react-table
```
## Prerequisites
We are going to build a table to show recent payments. Here's what our data looks like:
```tsx showLineNumbers
type Payment = {
id: string
amount: number
status: "pending" | "processing" | "success" | "failed"
email: string
}
export const payments: Payment[] = [
{
id: "728ed52f",
amount: 100,
status: "pending",
email: "m@example.com",
},
{
id: "489e1d42",
amount: 125,
status: "processing",
email: "example@gmail.com",
},
// ...
]
```
## Project Structure
Start by creating the following file structure:
```txt
app
└── payments
├── columns.tsx
├── data-table.tsx
└── page.tsx
```
I'm using a Next.js example here but this works for any other React framework.
- `columns.tsx` (client component) will contain our column definitions.
- `data-table.tsx` (client component) will contain our `` component.
- `page.tsx` (server component) is where we'll fetch data and render our table.
## Basic Table
Let's start by building a basic table.
### Column Definitions
First, we'll define our columns.
```tsx showLineNumbers title="app/payments/columns.tsx" {3,14-27}
"use client"
import { ColumnDef } from "@tanstack/react-table"
// This type is used to define the shape of our data.
// You can use a Zod schema here if you want.
export type Payment = {
id: string
amount: number
status: "pending" | "processing" | "success" | "failed"
email: string
}
export const columns: ColumnDef[] = [
{
accessorKey: "status",
header: "Status",
},
{
accessorKey: "email",
header: "Email",
},
{
accessorKey: "amount",
header: "Amount",
},
]
```
**Note:** Columns are where you define the core of what your table
will look like. They define the data that will be displayed, how it will be
formatted, sorted and filtered.
### `` component
Next, we'll create a `` component to render our table.
```tsx showLineNumbers title="app/payments/data-table.tsx"
"use client"
import {
ColumnDef,
flexRender,
getCoreRowModel,
useReactTable,
} from "@tanstack/react-table"
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table"
interface DataTableProps {
columns: ColumnDef[]
data: TData[]
}
export function DataTable({
columns,
data,
}: DataTableProps) {
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
})
return (
)
}
```
**Tip**: If you find yourself using `` in multiple places, this is the component you could make reusable by extracting it to `components/ui/data-table.tsx`.
``
### Render the table
Finally, we'll render our table in our page component.
```tsx showLineNumbers title="app/payments/page.tsx" {22}
import { columns, Payment } from "./columns"
import { DataTable } from "./data-table"
async function getData(): Promise {
// Fetch data from your API here.
return [
{
id: "728ed52f",
amount: 100,
status: "pending",
email: "m@example.com",
},
// ...
]
}
export default async function DemoPage() {
const data = await getData()
return (
)
}
```
## Cell Formatting
Let's format the amount cell to display the dollar amount. We'll also align the cell to the right.
### Update columns definition
Update the `header` and `cell` definitions for amount as follows:
```tsx showLineNumbers title="app/payments/columns.tsx" {4-15}
export const columns: ColumnDef[] = [
{
accessorKey: "amount",
header: () =>
},
},
]
```
You can use the same approach to format other cells and headers.
## Row Actions
Let's add row actions to our table. We'll use a `` component for this.
### Update columns definition
Update our columns definition to add a new `actions` column. The `actions` cell returns a `` component.
```tsx showLineNumbers title="app/payments/columns.tsx" {4,6-14,18-45}
"use client"
import { ColumnDef } from "@tanstack/react-table"
import { MoreHorizontal } from "lucide-react"
import { Button } from "@/components/ui/button"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
export const columns: ColumnDef[] = [
// ...
{
id: "actions",
cell: ({ row }) => {
const payment = row.original
return (
Actions navigator.clipboard.writeText(payment.id)}
>
Copy payment ID
View customerView payment details
)
},
},
// ...
]
```
You can access the row data using `row.original` in the `cell` function. Use this to handle actions for your row eg. use the `id` to make a DELETE call to your API.
## Pagination
Next, we'll add pagination to our table.
### Update ``
```tsx showLineNumbers title="app/payments/data-table.tsx" {5,17}
import {
ColumnDef,
flexRender,
getCoreRowModel,
getPaginationRowModel,
useReactTable,
} from "@tanstack/react-table"
export function DataTable({
columns,
data,
}: DataTableProps) {
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
})
// ...
}
```
This will automatically paginate your rows into pages of 10. See the [pagination docs](https://tanstack.com/table/v8/docs/api/features/pagination) for more information on customizing page size and implementing manual pagination.
### Add pagination controls
We can add pagination controls to our table using the `` component and the `table.previousPage()`, `table.nextPage()` API methods.
```tsx showLineNumbers title="app/payments/data-table.tsx" {1,15,21-39}
import { Button } from "@/components/ui/button"
export function DataTable({
columns,
data,
}: DataTableProps) {
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
})
return (
{ // .... }
)
}
```
See [Reusable Components](#reusable-components) section for a more advanced pagination component.
## Sorting
Let's make the email column sortable.
### Update ``
```tsx showLineNumbers title="app/payments/data-table.tsx" showLineNumbers {3,6,10,18,25-28}
"use client"
import * as React from "react"
import {
ColumnDef,
SortingState,
flexRender,
getCoreRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
} from "@tanstack/react-table"
export function DataTable({
columns,
data,
}: DataTableProps) {
const [sorting, setSorting] = React.useState([])
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
onSortingChange: setSorting,
getSortedRowModel: getSortedRowModel(),
state: {
sorting,
},
})
return (
{ ... }
)
}
```
### Make header cell sortable
We can now update the `email` header cell to add sorting controls.
```tsx showLineNumbers title="app/payments/columns.tsx" {4,9-19}
"use client"
import { ColumnDef } from "@tanstack/react-table"
import { ArrowUpDown } from "lucide-react"
export const columns: ColumnDef[] = [
{
accessorKey: "email",
header: ({ column }) => {
return (
)
},
},
]
```
This will automatically sort the table (asc and desc) when the user toggles on the header cell.
## Filtering
Let's add a search input to filter emails in our table.
### Update ``
```tsx showLineNumbers title="app/payments/data-table.tsx" {6,10,17,24-26,35-36,39,45-54}
"use client"
import * as React from "react"
import {
ColumnDef,
ColumnFiltersState,
SortingState,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
} from "@tanstack/react-table"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
export function DataTable({
columns,
data,
}: DataTableProps) {
const [sorting, setSorting] = React.useState([])
const [columnFilters, setColumnFilters] = React.useState(
[]
)
const table = useReactTable({
data,
columns,
onSortingChange: setSorting,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
onColumnFiltersChange: setColumnFilters,
getFilteredRowModel: getFilteredRowModel(),
state: {
sorting,
columnFilters,
},
})
return (
)
}
```
This adds a checkbox to each row and a checkbox in the header to select all rows.
### Show selected rows
You can show the number of selected rows using the `table.getFilteredSelectedRowModel()` API.
```tsx
```
## Reusable Components
Here are some components you can use to build your data tables. This is from the [Tasks](/examples/tasks) demo.
### Column header
Make any column header sortable and hideable.
```tsx showLineNumbers {5}
export const columns = [
{
accessorKey: "email",
header: ({ column }) => (
),
},
]
```
### Pagination
Add pagination controls to your table including page size and selection count.
```tsx
```
### Column toggle
A component to toggle column visibility.
```tsx
```
================================================
FILE: apps/v4/content/docs/components/date-picker.mdx
================================================
---
title: Date Picker
description: A date picker component with range and presets.
component: true
---
## Installation
The Date Picker is built using a composition of the `` and the `` components.
See installation instructions for the [Popover](/docs/components/popover#installation) and the [Calendar](/docs/components/calendar#installation) components.
## Usage
```tsx showLineNumbers title="components/example-date-picker.tsx"
"use client"
import * as React from "react"
import { format } from "date-fns"
import { Calendar as CalendarIcon } from "lucide-react"
import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import { Calendar } from "@/components/ui/calendar"
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover"
export function DatePickerDemo() {
const [date, setDate] = React.useState()
return (
)
}
```
See the [React DayPicker](https://react-day-picker.js.org) documentation for more information.
## Examples
### Date of Birth Picker
### Picker with Input
### Date and Time Picker
### Natural Language Picker
This component uses the `chrono-node` library to parse natural language dates.
### Form
================================================
FILE: apps/v4/content/docs/components/dialog.mdx
================================================
---
title: Dialog
description: A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.
featured: true
component: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/dialog
api: https://www.radix-ui.com/docs/primitives/components/dialog#api-reference
---
## Installation
CLIManual
```bash
npx shadcn@latest add dialog
```
Install the following dependencies:
```bash
npm install @radix-ui/react-dialog
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog"
```
```tsx showLineNumbers
```
## Examples
### Custom close button
## Notes
To use the `Dialog` component from within a `Context Menu` or `Dropdown Menu`, you must encase the `Context Menu` or
`Dropdown Menu` component in the `Dialog` component.
```tsx showLineNumbers title="components/example-dialog-context-menu.tsx" {1, 26}
```
================================================
FILE: apps/v4/content/docs/components/drawer.mdx
================================================
---
title: Drawer
description: A drawer component for React.
component: true
links:
doc: https://vaul.emilkowal.ski/getting-started
---
## About
Drawer is built on top of [Vaul](https://github.com/emilkowalski/vaul) by [emilkowalski\_](https://twitter.com/emilkowalski_).
## Installation
CLIManual
```bash
npx shadcn@latest add drawer
```
Install the following dependencies:
```bash
npm install vaul
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import {
Drawer,
DrawerClose,
DrawerContent,
DrawerDescription,
DrawerFooter,
DrawerHeader,
DrawerTitle,
DrawerTrigger,
} from "@/components/ui/drawer"
```
```tsx showLineNumbers
OpenAre you absolutely sure?This action cannot be undone.
```
## Examples
### Responsive Dialog
You can combine the `Dialog` and `Drawer` components to create a responsive dialog. This renders a `Dialog` component on desktop and a `Drawer` on mobile.
================================================
FILE: apps/v4/content/docs/components/dropdown-menu.mdx
================================================
---
title: Dropdown Menu
description: Displays a menu to the user — such as a set of actions or functions — triggered by a button.
featured: true
component: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/dropdown-menu
api: https://www.radix-ui.com/docs/primitives/components/dropdown-menu#api-reference
---
## Installation
CLIManual
```bash
npx shadcn@latest add dropdown-menu
```
Install the following dependencies:
```bash
npm install @radix-ui/react-dropdown-menu
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
```
```tsx showLineNumbers
OpenMy AccountProfileBillingTeamSubscription
```
## Examples
### Checkboxes
### Radio Group
================================================
FILE: apps/v4/content/docs/components/form.mdx
================================================
---
title: React Hook Form
description: Building forms with React Hook Form and Zod.
links:
doc: https://react-hook-form.com
---
Forms are tricky. They are one of the most common things you'll build in a web application, but also one of the most complex.
Well-designed HTML forms are:
- Well-structured and semantically correct.
- Easy to use and navigate (keyboard).
- Accessible with ARIA attributes and proper labels.
- Has support for client and server side validation.
- Well-styled and consistent with the rest of the application.
In this guide, we will take a look at building forms with [`react-hook-form`](https://react-hook-form.com/) and [`zod`](https://zod.dev). We're going to use a `` component to compose accessible forms using Radix UI components.
## Features
The `` component is a wrapper around the `react-hook-form` library. It provides a few things:
- Composable components for building forms.
- A `` component for building controlled form fields.
- Form validation using `zod`.
- Handles accessibility and error messages.
- Uses `React.useId()` for generating unique IDs.
- Applies the correct `aria` attributes to form fields based on states.
- Built to work with all Radix UI components.
- Bring your own schema library. We use `zod` but you can use anything you want.
- **You have full control over the markup and styling.**
## Anatomy
```tsx showLineNumbers
```
## Example
```tsx showLineNumbers
const form = useForm()
(
UsernameThis is your public display name.
)}
/>
```
## Installation
CLIManual
### Command
```bash
npx shadcn@latest add form
```
Install the following dependencies:
```bash
npm install @radix-ui/react-label @radix-ui/react-slot react-hook-form @hookform/resolvers zod
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
### Create a form schema
Define the shape of your form using a Zod schema. You can read more about using Zod in the [Zod documentation](https://zod.dev).
```tsx showLineNumbers title="components/example-form.tsx" {3,5-7}
"use client"
import { z } from "zod"
const formSchema = z.object({
username: z.string().min(2).max(50),
})
```
### Define a form
Use the `useForm` hook from `react-hook-form` to create a form.
```tsx showLineNumbers title="components/example-form.tsx" {3-4,14-20,22-27}
"use client"
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
import { z } from "zod"
const formSchema = z.object({
username: z.string().min(2, {
message: "Username must be at least 2 characters.",
}),
})
export function ProfileForm() {
// 1. Define your form.
const form = useForm>({
resolver: zodResolver(formSchema),
defaultValues: {
username: "",
},
})
// 2. Define a submit handler.
function onSubmit(values: z.infer) {
// Do something with the form values.
// ✅ This will be type-safe and validated.
console.log(values)
}
}
```
Since `FormField` is using a controlled component, you need to provide a default value for the field. See the [React Hook Form docs](https://react-hook-form.com/docs/usecontroller) to learn more about controlled components.
### Build your form
We can now use the `` components to build our form.
```tsx showLineNumbers title="components/example-form.tsx" {7-17,28-50}
"use client"
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
import { z } from "zod"
import { Button } from "@/components/ui/button"
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form"
import { Input } from "@/components/ui/input"
const formSchema = z.object({
username: z.string().min(2, {
message: "Username must be at least 2 characters.",
}),
})
export function ProfileForm() {
// ...
return (
)
}
```
### Done
That's it. You now have a fully accessible form that is type-safe with client-side validation.
## Examples
See the following links for more examples on how to use the `` component with other components:
- [Checkbox](/docs/components/checkbox#form)
- [Date Picker](/docs/components/date-picker#form)
- [Input](/docs/components/input#form)
- [Radio Group](/docs/components/radio-group#form)
- [Select](/docs/components/select#form)
- [Switch](/docs/components/switch#form)
- [Textarea](/docs/components/textarea#form)
- [Combobox](/docs/components/combobox#form)
================================================
FILE: apps/v4/content/docs/components/hover-card.mdx
================================================
---
title: Hover Card
description: For sighted users to preview content available behind a link.
component: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/hover-card
api: https://www.radix-ui.com/docs/primitives/components/hover-card#api-reference
---
## Installation
CLIManual
```bash
npx shadcn@latest add hover-card
```
Install the following dependencies:
```bash
npm install @radix-ui/react-hover-card
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/components/ui/hover-card"
```
```tsx showLineNumbers
Hover
The React Framework – created and maintained by @vercel.
```
================================================
FILE: apps/v4/content/docs/components/index.mdx
================================================
---
title: Components
description: Here you can find all the components available in the library. We are working on adding more components.
---
================================================
FILE: apps/v4/content/docs/components/input-otp.mdx
================================================
---
title: Input OTP
description: Accessible one-time password component with copy paste functionality.
component: true
links:
doc: https://input-otp.rodz.dev
---
## About
Input OTP is built on top of [input-otp](https://github.com/guilhermerodz/input-otp) by [@guilherme_rodz](https://twitter.com/guilherme_rodz).
## Installation
CLIManualRun the following command:
```bash
npx shadcn@latest add input-otp
```
Install the following dependencies:
```bash
npm install input-otp
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import {
InputOTP,
InputOTPGroup,
InputOTPSeparator,
InputOTPSlot,
} from "@/components/ui/input-otp"
```
```tsx showLineNumbers
```
## Examples
### Pattern
Use the `pattern` prop to define a custom pattern for the OTP input.
```tsx showLineNumbers {1,7}
import { REGEXP_ONLY_DIGITS_AND_CHARS } from "input-otp"
...
{/* ... */}
```
### Separator
You can use the `` component to add a separator between the input groups.
```tsx showLineNumbers {4,15}
import {
InputOTP,
InputOTPGroup,
InputOTPSeparator,
InputOTPSlot,
} from "@/components/ui/input-otp"
...
```
### Controlled
You can use the `value` and `onChange` props to control the input value.
### Form
## Changelog
### 2024-03-19 Composition
We've made some updates and replaced the render props pattern with composition. Here's how to update your code if you prefer the composition pattern.
**Note:** You are not required to update your code if you are using the
`render` prop. It is still supported.
Update to the latest version of `input-otp`.
```bash
npm install input-otp@latest
```
Update `input-otp.tsx`
```diff showLineNumbers title="input-otp.tsx" {2,8-11}
- import { OTPInput, SlotProps } from "input-otp"
+ import { OTPInput, OTPInputContext } from "input-otp"
const InputOTPSlot = React.forwardRef<
React.ElementRef<"div">,
- SlotProps & React.ComponentPropsWithoutRef<"div">
- >(({ char, hasFakeCaret, isActive, className, ...props }, ref) => {
+ React.ComponentPropsWithoutRef<"div"> & { index: number }
+ >(({ index, className, ...props }, ref) => {
+ const inputOTPContext = React.useContext(OTPInputContext)
+ const { char, hasFakeCaret, isActive } = inputOTPContext.slots[index]
```
Then replace the `render` prop in your code.
```diff showLineNumbers {2-12}
```
### 2024-03-19 Disabled
To add a disabled state to the input, update `` as follows:
```tsx showLineNumbers title="input-otp.tsx" {4,7-11}
const InputOTP = React.forwardRef<
React.ElementRef,
React.ComponentPropsWithoutRef
>(({ className, containerClassName, ...props }, ref) => (
))
InputOTP.displayName = "InputOTP"
```
================================================
FILE: apps/v4/content/docs/components/input.mdx
================================================
---
title: Input
description: Displays a form input field or a component that looks like an input field.
component: true
---
## Installation
CLIManual
```bash
npx shadcn@latest add input
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx
import { Input } from "@/components/ui/input"
```
```tsx
```
## Examples
### Default
### File
### Disabled
### With Label
### With Button
### Form
================================================
FILE: apps/v4/content/docs/components/label.mdx
================================================
---
title: Label
description: Renders an accessible label associated with controls.
component: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/label
api: https://www.radix-ui.com/docs/primitives/components/label#api-reference
---
## Installation
CLIManual
```bash
npx shadcn@latest add label
```
Install the following dependencies:
```bash
npm install @radix-ui/react-label
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx
import { Label } from "@/components/ui/label"
```
```tsx
```
================================================
FILE: apps/v4/content/docs/components/menubar.mdx
================================================
---
title: Menubar
description: A visually persistent menu common in desktop applications that provides quick access to a consistent set of commands.
component: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/menubar
api: https://www.radix-ui.com/docs/primitives/components/menubar#api-reference
---
## Installation
CLIManual
```bash
npx shadcn@latest add menubar
```
Install the following dependencies:
```bash
npm install @radix-ui/react-menubar
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import {
Menubar,
MenubarContent,
MenubarItem,
MenubarMenu,
MenubarSeparator,
MenubarShortcut,
MenubarTrigger,
} from "@/components/ui/menubar"
```
```tsx showLineNumbers
File
New Tab ⌘TNew WindowSharePrint
```
================================================
FILE: apps/v4/content/docs/components/navigation-menu.mdx
================================================
---
title: Navigation Menu
description: A collection of links for navigating websites.
component: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/navigation-menu
api: https://www.radix-ui.com/docs/primitives/components/navigation-menu#api-reference
---
## Installation
CLIManual
```bash
npx shadcn@latest add navigation-menu
```
Install the following dependencies:
```bash
npm install @radix-ui/react-navigation-menu
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import {
NavigationMenu,
NavigationMenuContent,
NavigationMenuIndicator,
NavigationMenuItem,
NavigationMenuLink,
NavigationMenuList,
NavigationMenuTrigger,
NavigationMenuViewport,
} from "@/components/ui/navigation-menu"
```
```tsx showLineNumbers
Item OneLink
```
## Link
You can use the `asChild` prop to make another component look like a navigation menu trigger. Here's an example of a link that looks like a navigation menu trigger.
```tsx showLineNumbers title="components/example-navigation-menu.tsx"
import { Link } from "next/link"
export function NavigationMenuDemo() {
return (
Documentation
)
}
```
================================================
FILE: apps/v4/content/docs/components/pagination.mdx
================================================
---
title: Pagination
description: Pagination with page navigation, next and previous links.
component: true
---
## Installation
CLIManual
```bash
npx shadcn@latest add pagination
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from "@/components/ui/pagination"
```
```tsx showLineNumbers
1
```
### Next.js
By default the `` component will render an `` tag.
To use the Next.js `` component, make the following updates to `pagination.tsx`.
```diff showLineNumbers /typeof Link/ {1}
+ import Link from "next/link"
- type PaginationLinkProps = ... & React.ComponentProps<"a">
+ type PaginationLinkProps = ... & React.ComponentProps
const PaginationLink = ({...props }: ) => (
-
+
// ...
-
+
)
```
**Note:** We are making updates to the cli to automatically do this for you.
================================================
FILE: apps/v4/content/docs/components/popover.mdx
================================================
---
title: Popover
description: Displays rich content in a portal, triggered by a button.
component: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/popover
api: https://www.radix-ui.com/docs/primitives/components/popover#api-reference
---
## Installation
CLIManual
```bash
npx shadcn@latest add popover
```
Install the following dependencies:
```bash
npm install @radix-ui/react-popover
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover"
```
```tsx showLineNumbers
OpenPlace content for the popover here.
```
================================================
FILE: apps/v4/content/docs/components/progress.mdx
================================================
---
title: Progress
description: Displays an indicator showing the completion progress of a task, typically displayed as a progress bar.
component: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/progress
api: https://www.radix-ui.com/docs/primitives/components/progress#api-reference
---
## Installation
CLIManual
```bash
npx shadcn@latest add progress
```
Install the following dependencies:
```bash
npm install @radix-ui/react-progress
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import { Progress } from "@/components/ui/progress"
```
```tsx showLineNumbers
```
================================================
FILE: apps/v4/content/docs/components/radio-group.mdx
================================================
---
title: Radio Group
description: A set of checkable buttons—known as radio buttons—where no more than one of the buttons can be checked at a time.
component: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/radio-group
api: https://www.radix-ui.com/docs/primitives/components/radio-group#api-reference
---
## Installation
CLIManual
```bash
npx shadcn@latest add radio-group
```
Install the following dependencies:
```bash
npm install @radix-ui/react-radio-group
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import { Label } from "@/components/ui/label"
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
```
```tsx showLineNumbers
```
## Examples
### Form
================================================
FILE: apps/v4/content/docs/components/resizable.mdx
================================================
---
title: Resizable
description: Accessible resizable panel groups and layouts with keyboard support.
component: true
links:
doc: https://github.com/bvaughn/react-resizable-panels
api: https://github.com/bvaughn/react-resizable-panels/tree/main/packages/react-resizable-panels
---
## About
The `Resizable` component is built on top of [react-resizable-panels](https://github.com/bvaughn/react-resizable-panels) by [bvaughn](https://github.com/bvaughn).
## Installation
CLIManual
```bash
npx shadcn@latest add resizable
```
Install the following dependencies:
```bash
npm install react-resizable-panels
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import {
ResizableHandle,
ResizablePanel,
ResizablePanelGroup,
} from "@/components/ui/resizable"
```
```tsx showLineNumbers
OneTwo
```
## Examples
### Vertical
Use the `direction` prop to set the direction of the resizable panels.
```tsx showLineNumbers {9}
import {
ResizableHandle,
ResizablePanel,
ResizablePanelGroup,
} from "@/components/ui/resizable"
export default function Example() {
return (
OneTwo
)
}
```
### Handle
You can set or hide the handle by using the `withHandle` prop on the `ResizableHandle` component.
```tsx showLineNumbers {11}
import {
ResizableHandle,
ResizablePanel,
ResizablePanelGroup,
} from "@/components/ui/resizable"
export default function Example() {
return (
OneTwo
)
}
```
================================================
FILE: apps/v4/content/docs/components/scroll-area.mdx
================================================
---
title: Scroll-area
description: Augments native scroll functionality for custom, cross-browser styling.
component: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/scroll-area
api: https://www.radix-ui.com/docs/primitives/components/scroll-area#api-reference
---
## Installation
CLIManual
```bash
npx shadcn@latest add scroll-area
```
Install the following dependencies:
```bash
npm install @radix-ui/react-scroll-area
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import { ScrollArea } from "@/components/ui/scroll-area"
```
```tsx showLineNumbers
Jokester began sneaking into the castle in the middle of the night and leaving
jokes all over the place: under the king's pillow, in his soup, even in the
royal toilet. The king was furious, but he couldn't seem to stop Jokester. And
then, one day, the people of the kingdom discovered that the jokes left by
Jokester were so funny that they couldn't help but laugh. And once they
started laughing, they couldn't stop.
```
## Examples
### Horizontal Scrolling
================================================
FILE: apps/v4/content/docs/components/select.mdx
================================================
---
title: Select
description: Displays a list of options for the user to pick from—triggered by a button.
component: true
featured: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/select
api: https://www.radix-ui.com/docs/primitives/components/select#api-reference
---
## Installation
CLIManual
```bash
npx shadcn@latest add select
```
Install the following dependencies:
```bash
npm install @radix-ui/react-select
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
```
```tsx showLineNumbers
```
## Examples
### Scrollable
### Form
================================================
FILE: apps/v4/content/docs/components/separator.mdx
================================================
---
title: Separator
description: Visually or semantically separates content.
component: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/separator
api: https://www.radix-ui.com/docs/primitives/components/separator#api-reference
---
## Installation
CLIManual
```bash
npx shadcn@latest add separator
```
Install the following dependencies:
```bash
npm install @radix-ui/react-separator
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import { Separator } from "@/components/ui/separator"
```
```tsx showLineNumbers
```
================================================
FILE: apps/v4/content/docs/components/sheet.mdx
================================================
---
title: Sheet
description: Extends the Dialog component to display content that complements the main content of the screen.
component: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/dialog
api: https://www.radix-ui.com/docs/primitives/components/dialog#api-reference
---
## Installation
CLIManual
```bash
npx shadcn@latest add sheet
```
Install the following dependencies:
```bash
npm install @radix-ui/react-dialog
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
### Usage
```tsx showLineNumbers
import {
Sheet,
SheetContent,
SheetDescription,
SheetHeader,
SheetTitle,
SheetTrigger,
} from "@/components/ui/sheet"
```
```tsx showLineNumbers
OpenAre you absolutely sure?
This action cannot be undone. This will permanently delete your account
and remove your data from our servers.
```
## Examples
### Side
Use the `side` property to `` to indicate the edge of the screen where the component will appear. The values can be `top`, `right`, `bottom` or `left`.
### Size
You can adjust the size of the sheet using CSS classes:
```tsx showLineNumbers {3}
OpenAre you absolutely sure?
This action cannot be undone. This will permanently delete your account
and remove your data from our servers.
```
================================================
FILE: apps/v4/content/docs/components/sidebar.mdx
================================================
---
title: Sidebar
description: A composable, themeable and customizable sidebar component.
component: true
---
A sidebar that collapses to icons.
Sidebars are one of the most complex components to build. They are central
to any application and often contain a lot of moving parts.
I don't like building sidebars. So I built 30+ of them. All kinds of
configurations. Then I extracted the core components into `sidebar.tsx`.
We now have a solid foundation to build on top of. Composable. Themeable.
Customizable.
[Browse the Blocks Library](/blocks).
## Installation
CLIManualRun the following command to install `sidebar.tsx`
```bash
npx shadcn@latest add sidebar
```
Add the following colors to your CSS file
The command above should install the colors for you. If not, copy and paste the following in your CSS file.
We'll go over the colors later in the [theming section](/docs/components/sidebar#theming).
```css showLineNumbers title="app/globals.css"
@layer base {
:root {
--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 {
--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.439 0 0);
}
}
```
Copy and paste the following code into your project.Update the import paths to match your project setup.Add the following colors to your CSS file
We'll go over the colors later in the [theming section](/docs/components/sidebar#theming).
```css showLineNumbers title="app/globals.css"
@layer base {
:root {
--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 {
--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.439 0 0);
}
}
```
## Structure
A `Sidebar` component is composed of the following parts:
- `SidebarProvider` - Handles collapsible state.
- `Sidebar` - The sidebar container.
- `SidebarHeader` and `SidebarFooter` - Sticky at the top and bottom of the sidebar.
- `SidebarContent` - Scrollable content.
- `SidebarGroup` - Section within the `SidebarContent`.
- `SidebarTrigger` - Trigger for the `Sidebar`.
## Usage
```tsx showLineNumbers title="app/layout.tsx"
import { SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar"
import { AppSidebar } from "@/components/app-sidebar"
export default function Layout({ children }: { children: React.ReactNode }) {
return (
{children}
)
}
```
```tsx showLineNumbers title="components/app-sidebar.tsx"
import {
Sidebar,
SidebarContent,
SidebarFooter,
SidebarGroup,
SidebarHeader,
} from "@/components/ui/sidebar"
export function AppSidebar() {
return (
)
}
```
## Your First Sidebar
Let's start with the most basic sidebar. A collapsible sidebar with a menu.
Add a `SidebarProvider` and `SidebarTrigger` at the root of your application.
```tsx showLineNumbers title="app/layout.tsx"
import { SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar"
import { AppSidebar } from "@/components/app-sidebar"
export default function Layout({ children }: { children: React.ReactNode }) {
return (
{children}
)
}
```
Create a new sidebar component at `components/app-sidebar.tsx`.
```tsx showLineNumbers title="components/app-sidebar.tsx"
import { Sidebar, SidebarContent } from "@/components/ui/sidebar"
export function AppSidebar() {
return (
)
}
```
Now, let's add a `SidebarMenu` to the sidebar.
We'll use the `SidebarMenu` component in a `SidebarGroup`.
```tsx showLineNumbers title="components/app-sidebar.tsx"
import { Calendar, Home, Inbox, Search, Settings } from "lucide-react"
import {
Sidebar,
SidebarContent,
SidebarGroup,
SidebarGroupContent,
SidebarGroupLabel,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
} from "@/components/ui/sidebar"
// Menu items.
const items = [
{
title: "Home",
url: "#",
icon: Home,
},
{
title: "Inbox",
url: "#",
icon: Inbox,
},
{
title: "Calendar",
url: "#",
icon: Calendar,
},
{
title: "Search",
url: "#",
icon: Search,
},
{
title: "Settings",
url: "#",
icon: Settings,
},
]
export function AppSidebar() {
return (
Application
{items.map((item) => (
{item.title}
))}
)
}
```
You've created your first sidebar.
You should see something like this:
Your first sidebar.
## Components
The components in `sidebar.tsx` are built to be composable i.e you build your sidebar by putting the provided components together. They also compose well with other shadcn/ui components such as `DropdownMenu`, `Collapsible` or `Dialog` etc.
**If you need to change the code in `sidebar.tsx`, you are encouraged to do so. The code is yours. Use `sidebar.tsx` as a starting point and build your own.**
In the next sections, we'll go over each component and how to use them.
## SidebarProvider
The `SidebarProvider` component is used to provide the sidebar context to the `Sidebar` component. You should always wrap your application in a `SidebarProvider` component.
### Props
| Name | Type | Description |
| -------------- | ------------------------- | -------------------------------------------- |
| `defaultOpen` | `boolean` | Default open state of the sidebar. |
| `open` | `boolean` | Open state of the sidebar (controlled). |
| `onOpenChange` | `(open: boolean) => void` | Sets open state of the sidebar (controlled). |
### Width
If you have a single sidebar in your application, you can use the `SIDEBAR_WIDTH` and `SIDEBAR_WIDTH_MOBILE` variables in `sidebar.tsx` to set the width of the sidebar.
```tsx showLineNumbers title="components/ui/sidebar.tsx"
const SIDEBAR_WIDTH = "16rem"
const SIDEBAR_WIDTH_MOBILE = "18rem"
```
For multiple sidebars in your application, you can use the `style` prop to set the width of the sidebar.
To set the width of the sidebar, you can use the `--sidebar-width` and `--sidebar-width-mobile` CSS variables in the `style` prop.
```tsx showLineNumbers title="components/ui/sidebar.tsx"
```
This will handle the width of the sidebar but also the layout spacing.
### Keyboard Shortcut
The `SIDEBAR_KEYBOARD_SHORTCUT` variable is used to set the keyboard shortcut used to open and close the sidebar.
To trigger the sidebar, you use the `cmd+b` keyboard shortcut on Mac and `ctrl+b` on Windows.
You can change the keyboard shortcut by updating the `SIDEBAR_KEYBOARD_SHORTCUT` variable.
```tsx showLineNumbers title="components/ui/sidebar.tsx"
const SIDEBAR_KEYBOARD_SHORTCUT = "b"
```
### Persisted State
The `SidebarProvider` supports persisting the sidebar state across page reloads and server-side rendering. It uses cookies to store the current state of the sidebar. When the sidebar state changes, a default cookie named `sidebar_state` is set with the current open/closed state. This cookie is then read on subsequent page loads to restore the sidebar state.
To persist sidebar state in Next.js, set up your `SidebarProvider` in `app/layout.tsx` like this:
```tsx showLineNumbers title="app/layout.tsx"
import { cookies } from "next/headers"
import { SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar"
import { AppSidebar } from "@/components/app-sidebar"
export async function Layout({ children }: { children: React.ReactNode }) {
const cookieStore = await cookies()
const defaultOpen = cookieStore.get("sidebar_state")?.value === "true"
return (
{children}
)
}
```
You can change the name of the cookie by updating the `SIDEBAR_COOKIE_NAME` variable in `sidebar.tsx`.
```tsx showLineNumbers title="components/ui/sidebar.tsx"
const SIDEBAR_COOKIE_NAME = "sidebar_state"
```
## Sidebar
The main `Sidebar` component used to render a collapsible sidebar.
```tsx showLineNumbers
import { Sidebar } from "@/components/ui/sidebar"
export function AppSidebar() {
return
}
```
### Props
| Property | Type | Description |
| ------------- | --------------------------------- | --------------------------------- |
| `side` | `left` or `right` | The side of the sidebar. |
| `variant` | `sidebar`, `floating`, or `inset` | The variant of the sidebar. |
| `collapsible` | `offcanvas`, `icon`, or `none` | Collapsible state of the sidebar. |
### side
Use the `side` prop to change the side of the sidebar.
Available options are `left` and `right`.
```tsx showLineNumbers
import { Sidebar } from "@/components/ui/sidebar"
export function AppSidebar() {
return
}
```
### variant
Use the `variant` prop to change the variant of the sidebar.
Available options are `sidebar`, `floating` and `inset`.
```tsx showLineNumbers
import { Sidebar } from "@/components/ui/sidebar"
export function AppSidebar() {
return
}
```
**Note:** If you use the `inset` variant, remember to wrap your main content
in a `SidebarInset` component.
```tsx showLineNumbers
{children}
```
### collapsible
Use the `collapsible` prop to make the sidebar collapsible.
Available options are `offcanvas`, `icon` and `none`.
```tsx showLineNumbers
import { Sidebar } from "@/components/ui/sidebar"
export function AppSidebar() {
return
}
```
| Prop | Description |
| ----------- | ------------------------------------------------------------ |
| `offcanvas` | A collapsible sidebar that slides in from the left or right. |
| `icon` | A sidebar that collapses to icons. |
| `none` | A non-collapsible sidebar. |
## useSidebar
The `useSidebar` hook is used to control the sidebar.
```tsx showLineNumbers
import { useSidebar } from "@/components/ui/sidebar"
export function AppSidebar() {
const {
state,
open,
setOpen,
openMobile,
setOpenMobile,
isMobile,
toggleSidebar,
} = useSidebar()
}
```
| Property | Type | Description |
| --------------- | ------------------------- | --------------------------------------------- |
| `state` | `expanded` or `collapsed` | The current state of the sidebar. |
| `open` | `boolean` | Whether the sidebar is open. |
| `setOpen` | `(open: boolean) => void` | Sets the open state of the sidebar. |
| `openMobile` | `boolean` | Whether the sidebar is open on mobile. |
| `setOpenMobile` | `(open: boolean) => void` | Sets the open state of the sidebar on mobile. |
| `isMobile` | `boolean` | Whether the sidebar is on mobile. |
| `toggleSidebar` | `() => void` | Toggles the sidebar. Desktop and mobile. |
## SidebarHeader
Use the `SidebarHeader` component to add a sticky header to the sidebar.
The following example adds a `` to the `SidebarHeader`.
A sidebar header with a dropdown menu.
```tsx showLineNumbers title="components/app-sidebar.tsx"
Select Workspace
Acme IncAcme Corp.
```
## SidebarFooter
Use the `SidebarFooter` component to add a sticky footer to the sidebar.
The following example adds a `` to the `SidebarFooter`.
A sidebar footer with a dropdown menu.
```tsx showLineNumbers title="components/app-sidebar.tsx"
export function AppSidebar() {
return (
Username
AccountBillingSign out
)
}
```
## SidebarContent
The `SidebarContent` component is used to wrap the content of the sidebar. This is where you add your `SidebarGroup` components. It is scrollable.
```tsx showLineNumbers
import { Sidebar, SidebarContent } from "@/components/ui/sidebar"
export function AppSidebar() {
return (
)
}
```
## SidebarGroup
Use the `SidebarGroup` component to create a section within the sidebar.
A `SidebarGroup` has a `SidebarGroupLabel`, a `SidebarGroupContent` and an optional `SidebarGroupAction`.
A sidebar group.
```tsx showLineNumbers
import { Sidebar, SidebarContent, SidebarGroup } from "@/components/ui/sidebar"
export function AppSidebar() {
return (
ApplicationAdd Project
)
}
```
## Collapsible SidebarGroup
To make a `SidebarGroup` collapsible, wrap it in a `Collapsible`.
A collapsible sidebar group.
```tsx showLineNumbers
export function AppSidebar() {
return (
Help
)
}
```
**Note:** We wrap the `CollapsibleTrigger` in a `SidebarGroupLabel` to render
a button.
## SidebarGroupAction
Use the `SidebarGroupAction` component to add an action button to the `SidebarGroup`.
A sidebar group with an action button.
```tsx showLineNumbers {5-7}
export function AppSidebar() {
return (
ProjectsAdd Project
)
}
```
## SidebarMenu
The `SidebarMenu` component is used for building a menu within a `SidebarGroup`.
A `SidebarMenu` component is composed of `SidebarMenuItem`, `SidebarMenuButton`, `` and `` components.
Here's an example of a `SidebarMenu` component rendering a list of projects.
A sidebar menu with a list of projects.
```tsx showLineNumbers
Projects
{projects.map((project) => (
{project.name}
))}
```
## SidebarMenuButton
The `SidebarMenuButton` component is used to render a menu button within a `SidebarMenuItem`.
### Link or Anchor
By default, the `SidebarMenuButton` renders a button but you can use the `asChild` prop to render a different component such as a `Link` or an `a` tag.
```tsx showLineNumbers
Home
```
### Icon and Label
You can render an icon and a truncated label inside the button. Remember to wrap the label in a ``.
```tsx showLineNumbers
Home
```
### isActive
Use the `isActive` prop to mark a menu item as active.
```tsx showLineNumbers
Home
```
## SidebarMenuAction
The `SidebarMenuAction` component is used to render a menu action within a `SidebarMenuItem`.
This button works independently of the `SidebarMenuButton` i.e you can have the `` as a clickable link and the `` as a button.
```tsx showLineNumbers
HomeAdd Project
```
### DropdownMenu
Here's an example of a `SidebarMenuAction` component rendering a `DropdownMenu`.
A sidebar menu action with a dropdown menu.
```tsx showLineNumbers
HomeEdit ProjectDelete Project
```
## SidebarMenuSub
The `SidebarMenuSub` component is used to render a submenu within a `SidebarMenu`.
Use `` and `` to render a submenu item.
A sidebar menu with a submenu.
```tsx showLineNumbers
```
## Collapsible SidebarMenu
To make a `SidebarMenu` component collapsible, wrap it and the `SidebarMenuSub` components in a `Collapsible`.
A collapsible sidebar menu.
```tsx showLineNumbers
```
## SidebarMenuBadge
The `SidebarMenuBadge` component is used to render a badge within a `SidebarMenuItem`.
A sidebar menu with a badge.
```tsx showLineNumbers
24
```
## SidebarMenuSkeleton
The `SidebarMenuSkeleton` component is used to render a skeleton for a `SidebarMenu`. You can use this to show a loading state when using React Server Components, SWR or react-query.
```tsx showLineNumbers
function NavProjectsSkeleton() {
return (
{Array.from({ length: 5 }).map((_, index) => (
))}
)
}
```
## SidebarSeparator
The `SidebarSeparator` component is used to render a separator within a `Sidebar`.
```tsx showLineNumbers
```
## SidebarTrigger
Use the `SidebarTrigger` component to render a button that toggles the sidebar.
The `SidebarTrigger` component must be used within a `SidebarProvider`.
```tsx showLineNumbers
```
### Custom Trigger
To create a custom trigger, you can use the `useSidebar` hook.
```tsx showLineNumbers
import { useSidebar } from "@/components/ui/sidebar"
export function CustomTrigger() {
const { toggleSidebar } = useSidebar()
return
}
```
## SidebarRail
The `SidebarRail` component is used to render a rail within a `Sidebar`. This rail can be used to toggle the sidebar.
```tsx showLineNumbers
```
## Data Fetching
### React Server Components
Here's an example of a `SidebarMenu` component rendering a list of projects using React Server Components.
A sidebar menu using React Server Components.
```tsx showLineNumbers {6} title="Skeleton to show loading state."
function NavProjectsSkeleton() {
return (
{Array.from({ length: 5 }).map((_, index) => (
))}
)
}
```
```tsx showLineNumbers {2} title="Server component fetching data."
async function NavProjects() {
const projects = await fetchProjects()
return (
{projects.map((project) => (
{project.name}
))}
)
}
```
```tsx showLineNumbers {8-10} title="Usage with React Suspense."
function AppSidebar() {
return (
Projects}>
)
}
```
### SWR and React Query
You can use the same approach with [SWR](https://swr.vercel.app/) or [react-query](https://tanstack.com/query/latest/docs/framework/react/overview).
```tsx showLineNumbers title="SWR"
function NavProjects() {
const { data, isLoading } = useSWR("/api/projects", fetcher)
if (isLoading) {
return (
{Array.from({ length: 5 }).map((_, index) => (
))}
)
}
if (!data) {
return ...
}
return (
{data.map((project) => (
{project.name}
))}
)
}
```
```tsx showLineNumbers title="React Query"
function NavProjects() {
const { data, isLoading } = useQuery()
if (isLoading) {
return (
{Array.from({ length: 5 }).map((_, index) => (
))}
)
}
if (!data) {
return ...
}
return (
{data.map((project) => (
{project.name}
))}
)
}
```
## Controlled Sidebar
Use the `open` and `onOpenChange` props to control the sidebar.
A controlled sidebar.
```tsx showLineNumbers
export function AppSidebar() {
const [open, setOpen] = React.useState(false)
return (
)
}
```
## Theming
We use the following CSS variables to theme the sidebar.
```css
@layer base {
:root {
--sidebar-background: 0 0% 98%;
--sidebar-foreground: 240 5.3% 26.1%;
--sidebar-primary: 240 5.9% 10%;
--sidebar-primary-foreground: 0 0% 98%;
--sidebar-accent: 240 4.8% 95.9%;
--sidebar-accent-foreground: 240 5.9% 10%;
--sidebar-border: 220 13% 91%;
--sidebar-ring: 217.2 91.2% 59.8%;
}
.dark {
--sidebar-background: 240 5.9% 10%;
--sidebar-foreground: 240 4.8% 95.9%;
--sidebar-primary: 0 0% 98%;
--sidebar-primary-foreground: 240 5.9% 10%;
--sidebar-accent: 240 3.7% 15.9%;
--sidebar-accent-foreground: 240 4.8% 95.9%;
--sidebar-border: 240 3.7% 15.9%;
--sidebar-ring: 217.2 91.2% 59.8%;
}
}
```
**We intentionally use different variables for the sidebar and the rest of the application** to make it easy to have a sidebar that is styled differently from the rest of the application. Think a sidebar with a darker shade from the main application.
## Styling
Here are some tips for styling the sidebar based on different states.
- **Styling an element based on the sidebar collapsible state.** The following will hide the `SidebarGroup` when the sidebar is in `icon` mode.
```tsx
```
- **Styling a menu action based on the menu button active state.** The following will force the menu action to be visible when the menu button is active.
```tsx
```
You can find more tips on using states for styling in this [Twitter thread](https://x.com/shadcn/status/1842329158879420864).
## Changelog
### 2024-10-30 Cookie handling in setOpen
- [#5593](https://github.com/shadcn-ui/ui/pull/5593) - Improved setOpen callback logic in ``.
Update the `setOpen` callback in `` as follows:
```tsx showLineNumbers
const setOpen = React.useCallback(
(value: boolean | ((value: boolean) => boolean)) => {
const openState = typeof value === "function" ? value(open) : value
if (setOpenProp) {
setOpenProp(openState)
} else {
_setOpen(openState)
}
// This sets the cookie to keep the sidebar state.
document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`
},
[setOpenProp, open]
)
```
### 2024-10-21 Fixed `text-sidebar-foreground`
- [#5491](https://github.com/shadcn-ui/ui/pull/5491) - Moved `text-sidebar-foreground` from `` to `` component.
### 2024-10-20 Typo in `useSidebar` hook.
Fixed typo in `useSidebar` hook.
```diff showLineNumbers title="sidebar.tsx"
- throw new Error("useSidebar must be used within a Sidebar.")
+ throw new Error("useSidebar must be used within a SidebarProvider.")
```
================================================
FILE: apps/v4/content/docs/components/skeleton.mdx
================================================
---
title: Skeleton
description: Use to show a placeholder while content is loading.
component: true
---
## Installation
CLIManual
```bash
npx shadcn@latest add skeleton
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx
import { Skeleton } from "@/components/ui/skeleton"
```
```tsx
```
## Examples
### Card
================================================
FILE: apps/v4/content/docs/components/slider.mdx
================================================
---
title: Slider
description: An input where the user selects a value from within a given range.
component: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/slider
api: https://www.radix-ui.com/docs/primitives/components/slider#api-reference
---
## Installation
CLIManual
```bash
npx shadcn@latest add slider
```
Install the following dependencies:
```bash
npm install @radix-ui/react-slider
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx
import { Slider } from "@/components/ui/slider"
```
```tsx
```
================================================
FILE: apps/v4/content/docs/components/sonner.mdx
================================================
---
title: Sonner
description: An opinionated toast component for React.
component: true
links:
doc: https://sonner.emilkowal.ski
---
## About
Sonner is built and maintained by [emilkowalski\_](https://twitter.com/emilkowalski_).
## Installation
CLIManualRun the following command:
```bash
npx shadcn@latest add sonner
```
Add the Toaster component
```tsx title="app/layout.tsx" {1,9}
import { Toaster } from "@/components/ui/sonner"
export default function RootLayout({ children }) {
return (
{children}
)
}
```
Install the following dependencies:
```bash
npm install sonner next-themes
```
Copy and paste the following code into your project.Add the Toaster component
```tsx title="app/layout.tsx" {1,9}
import { Toaster } from "@/components/ui/sonner"
export default function RootLayout({ children }) {
return (
{children}
)
}
```
## Usage
```tsx
import { toast } from "sonner"
```
```tsx
toast("Event has been created.")
```
================================================
FILE: apps/v4/content/docs/components/switch.mdx
================================================
---
title: Switch
description: A control that allows the user to toggle between checked and not checked.
component: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/switch
api: https://www.radix-ui.com/docs/primitives/components/switch#api-reference
---
## Installation
CLIManual
```bash
npx shadcn@latest add switch
```
Install the following dependencies:
```bash
npm install @radix-ui/react-switch
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx
import { Switch } from "@/components/ui/switch"
```
```tsx
```
## Examples
### Form
================================================
FILE: apps/v4/content/docs/components/table.mdx
================================================
---
title: Table
description: A responsive table component.
component: true
---
## Installation
CLIManual
```bash
npx shadcn@latest add table
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import {
Table,
TableBody,
TableCaption,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table"
```
```tsx showLineNumbers
A list of your recent invoices.InvoiceStatusMethodAmountINV001PaidCredit Card$250.00
```
## Data Table
You can use the `
` component to build more complex data tables. Combine it with [@tanstack/react-table](https://tanstack.com/table/v8) to create tables with sorting, filtering and pagination.
See the [Data Table](/docs/components/data-table) documentation for more information.
You can also see an example of a data table in the [Tasks](/examples/tasks) demo.
================================================
FILE: apps/v4/content/docs/components/tabs.mdx
================================================
---
title: Tabs
description: A set of layered sections of content—known as tab panels—that are displayed one at a time.
component: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/tabs
api: https://www.radix-ui.com/docs/primitives/components/tabs#api-reference
---
## Installation
CLIManual
```bash
npx shadcn@latest add tabs
```
Install the following dependencies:
```bash
npm install @radix-ui/react-tabs
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
```
```tsx showLineNumbers
AccountPasswordMake changes to your account here.Change your password here.
```
================================================
FILE: apps/v4/content/docs/components/textarea.mdx
================================================
---
title: Textarea
description: Displays a form textarea or a component that looks like a textarea.
component: true
---
## Installation
CLIManual
```bash
npx shadcn@latest add textarea
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx
import { Textarea } from "@/components/ui/textarea"
```
```tsx
```
## Examples
### Default
### Disabled
### With Label
### With Text
### With Button
### Form
================================================
FILE: apps/v4/content/docs/components/toast.mdx
================================================
---
title: Toast
description: A succinct message that is displayed temporarily.
component: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/toast
api: https://www.radix-ui.com/docs/primitives/components/toast#api-reference
---
See the [sonner](/docs/components/sonner) documentation for more information.
If you're looking for the old toast component, see the [old docs](https://v3.shadcn.com/docs/components/toast) for more information.
================================================
FILE: apps/v4/content/docs/components/toggle-group.mdx
================================================
---
title: Toggle Group
description: A set of two-state buttons that can be toggled on or off.
component: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/toggle-group
api: https://www.radix-ui.com/docs/primitives/components/toggle-group#api-reference
---
## Installation
CLIManual
```bash
npx shadcn@latest add toggle-group
```
Install the following dependencies:
```bash
npm install @radix-ui/react-toggle-group
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
```
```tsx
ABC
```
## Examples
### Default
### Outline
### Single
### Small
### Large
### Disabled
================================================
FILE: apps/v4/content/docs/components/toggle.mdx
================================================
---
title: Toggle
description: A two-state button that can be either on or off.
component: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/toggle
api: https://www.radix-ui.com/docs/primitives/components/toggle#api-reference
---
## Installation
CLIManual
```bash
npx shadcn@latest add toggle
```
Install the following dependencies:
```bash
npm install @radix-ui/react-toggle
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx
import { Toggle } from "@/components/ui/toggle"
```
```tsx
Toggle
```
## Examples
### Default
### Outline
### With Text
### Small
### Large
### Disabled
================================================
FILE: apps/v4/content/docs/components/tooltip.mdx
================================================
---
title: Tooltip
description: A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it.
component: true
links:
doc: https://www.radix-ui.com/docs/primitives/components/tooltip
api: https://www.radix-ui.com/docs/primitives/components/tooltip#api-reference
---
## Installation
CLIManual
```bash
npx shadcn@latest add tooltip
```
Install the following dependencies:
```bash
npm install @radix-ui/react-tooltip
```
Copy and paste the following code into your project.Update the import paths to match your project setup.
## Usage
```tsx showLineNumbers
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip"
```
```tsx showLineNumbers
Hover
Add to library
```
================================================
FILE: apps/v4/content/docs/components/typography.mdx
================================================
---
title: Typography
description: Styles for headings, paragraphs, lists...etc
component: true
---
We do not ship any typography styles by default. This page is an example of how you can use utility classes to style your text.
## h1
## h2
## h3
## h4
## p
## blockquote
## table
## list
## Inline code
## Lead
## Large
## Small
## Muted
================================================
FILE: apps/v4/content/docs/dark-mode/astro.mdx
================================================
---
title: Astro
description: Adding dark mode to your astro app.
---
## Create an inline theme script
```astro title="src/pages/index.astro"
---
import '../styles/globals.css'
---
Astro
```
## Add a mode toggle
```tsx title="src/components/ModeToggle.tsx"
import * as React from "react"
import { Moon, Sun } from "lucide-react"
import { Button } from "@/components/ui/button"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
export function ModeToggle() {
const [theme, setThemeState] = React.useState<
"theme-light" | "dark" | "system"
>("theme-light")
React.useEffect(() => {
const isDarkMode = document.documentElement.classList.contains("dark")
setThemeState(isDarkMode ? "dark" : "theme-light")
}, [])
React.useEffect(() => {
const isDark =
theme === "dark" ||
(theme === "system" &&
window.matchMedia("(prefers-color-scheme: dark)").matches)
document.documentElement.classList[isDark ? "add" : "remove"]("dark")
}, [theme])
return (
setThemeState("theme-light")}>
Light
setThemeState("dark")}>
Dark
setThemeState("system")}>
System
)
}
```
## Display the mode toggle
Place a mode toggle on your site to toggle between light and dark mode.
```astro title="src/pages/index.astro"
---
import '../styles/globals.css'
import { ModeToggle } from '@/components/ModeToggle';
---
Astro
```
================================================
FILE: apps/v4/content/docs/dark-mode/index.mdx
================================================
---
title: Dark Mode
description: Adding dark mode to your site.
---
Next.js
Vite
Astro
Remix
================================================
FILE: apps/v4/content/docs/dark-mode/meta.json
================================================
{
"title": "Dark mode",
"pages": ["index", "next", "vite", "astro", "remix"]
}
================================================
FILE: apps/v4/content/docs/dark-mode/next.mdx
================================================
---
title: Next.js
description: Adding dark mode to your next app.
---
## Install next-themes
Start by installing `next-themes`:
```bash
npm install next-themes
```
## Create a theme provider
```tsx title="components/theme-provider.tsx" showLineNumbers
"use client"
import * as React from "react"
import { ThemeProvider as NextThemesProvider } from "next-themes"
export function ThemeProvider({
children,
...props
}: React.ComponentProps) {
return {children}
}
```
## Wrap your root layout
Add the `ThemeProvider` to your root layout and add the `suppressHydrationWarning` prop to the `html` tag.
```tsx {1,6,9-14,16} title="app/layout.tsx" showLineNumbers
import { ThemeProvider } from "@/components/theme-provider"
export default function RootLayout({ children }: RootLayoutProps) {
return (
<>
{children}
>
)
}
```
## Add a mode toggle
Place a mode toggle on your site to toggle between light and dark mode.
================================================
FILE: apps/v4/content/docs/dark-mode/remix.mdx
================================================
---
title: Remix
description: Adding dark mode to your remix app.
---
## Modify your tailwind.css file
Add `:root[class~="dark"]` to your tailwind.css file. This will allow you to use the `dark` class on your html element to apply dark mode styles.
```css {2} title="app/tailwind.css" showLineNumbers
.dark,
:root[class~="dark"] {
...;
}
```
## Install remix-themes
Start by installing `remix-themes`:
```bash
npm install remix-themes
```
## Create a session storage and theme session resolver
```tsx title="app/sessions.server.tsx" showLineNumbers
import { createThemeSessionResolver } from "remix-themes"
// You can default to 'development' if process.env.NODE_ENV is not set
const isProduction = process.env.NODE_ENV === "production"
const sessionStorage = createCookieSessionStorage({
cookie: {
name: "theme",
path: "/",
httpOnly: true,
sameSite: "lax",
secrets: ["s3cr3t"],
// Set domain and secure only if in production
...(isProduction
? { domain: "your-production-domain.com", secure: true }
: {}),
},
})
export const themeSessionResolver = createThemeSessionResolver(sessionStorage)
```
## Set up Remix Themes
Add the `ThemeProvider` to your root layout.
```tsx {1-3,6-11,15-22,25-26,28,33} title="app/root.tsx" showLineNumbers
import clsx from "clsx"
import { PreventFlashOnWrongTheme, ThemeProvider, useTheme } from "remix-themes"
import { themeSessionResolver } from "./sessions.server"
// Return the theme from the session storage using the loader
export async function loader({ request }: LoaderFunctionArgs) {
const { getTheme } = await themeSessionResolver(request)
return {
theme: getTheme(),
}
}
// Wrap your app with ThemeProvider.
// `specifiedTheme` is the stored theme in the session storage.
// `themeAction` is the action name that's used to change the theme in the session storage.
export default function AppWithProviders() {
const data = useLoaderData()
return (
)
}
export function App() {
const data = useLoaderData()
const [theme] = useTheme()
return (
)
}
```
## Add an action route
Create a file in `/routes/action.set-theme.ts`. Ensure that you pass the filename to the ThemeProvider component. This route it's used to store the preferred theme in the session storage when the user changes it.
```tsx title="app/routes/action.set-theme.ts" showLineNumbers
import { createThemeAction } from "remix-themes"
import { themeSessionResolver } from "./sessions.server"
export const action = createThemeAction(themeSessionResolver)
```
## Add a mode toggle
Place a mode toggle on your site to toggle between light and dark mode.
```tsx title="components/mode-toggle.tsx" showLineNumbers
import { Moon, Sun } from "lucide-react"
import { Theme, useTheme } from "remix-themes"
import { Button } from "./ui/button"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "./ui/dropdown-menu"
export function ModeToggle() {
const [, setTheme] = useTheme()
return (
setTheme(Theme.LIGHT)}>
Light
setTheme(Theme.DARK)}>
Dark
)
}
```
================================================
FILE: apps/v4/content/docs/dark-mode/vite.mdx
================================================
---
title: Vite
description: Adding dark mode to your vite app.
---
## Create a theme provider
```tsx title="components/theme-provider.tsx"
import { createContext, useContext, useEffect, useState } from "react"
type Theme = "dark" | "light" | "system"
type ThemeProviderProps = {
children: React.ReactNode
defaultTheme?: Theme
storageKey?: string
}
type ThemeProviderState = {
theme: Theme
setTheme: (theme: Theme) => void
}
const initialState: ThemeProviderState = {
theme: "system",
setTheme: () => null,
}
const ThemeProviderContext = createContext(initialState)
export function ThemeProvider({
children,
defaultTheme = "system",
storageKey = "vite-ui-theme",
...props
}: ThemeProviderProps) {
const [theme, setTheme] = useState(
() => (localStorage.getItem(storageKey) as Theme) || defaultTheme
)
useEffect(() => {
const root = window.document.documentElement
root.classList.remove("light", "dark")
if (theme === "system") {
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)")
.matches
? "dark"
: "light"
root.classList.add(systemTheme)
return
}
root.classList.add(theme)
}, [theme])
const value = {
theme,
setTheme: (theme: Theme) => {
localStorage.setItem(storageKey, theme)
setTheme(theme)
},
}
return (
{children}
)
}
export const useTheme = () => {
const context = useContext(ThemeProviderContext)
if (context === undefined)
throw new Error("useTheme must be used within a ThemeProvider")
return context
}
```
## Wrap your root layout
Add the `ThemeProvider` to your root layout.
```tsx {1,5-7} title="App.tsx"
import { ThemeProvider } from "@/components/theme-provider"
function App() {
return (
{children}
)
}
export default App
```
## Add a mode toggle
Place a mode toggle on your site to toggle between light and dark mode.
```tsx title="components/mode-toggle.tsx"
import { Moon, Sun } from "lucide-react"
import { Button } from "@/components/ui/button"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { useTheme } from "@/components/theme-provider"
export function ModeToggle() {
const { setTheme } = useTheme()
return (
setTheme("light")}>
Light
setTheme("dark")}>
Dark
setTheme("system")}>
System
)
}
```
================================================
FILE: apps/v4/content/docs/installation/astro.mdx
================================================
---
title: Astro
description: Install and configure shadcn/ui for Astro
---
### Create project
Start by creating a new Astro project:
```bash
npx create-astro@latest astro-app --template with-tailwindcss --install --add react --git
```
### Edit tsconfig.json file
Add the following code to the `tsconfig.json` file to resolve paths:
```ts title="tsconfig.json" {4-9} showLineNumbers
{
"compilerOptions": {
// ...
"baseUrl": ".",
"paths": {
"@/*": [
"./src/*"
]
}
// ...
}
}
```
### Run the CLI
Run the `shadcn` init command to setup your project:
```bash
npx shadcn@latest init
```
### Add Components
You can now start adding components to your project.
```bash
npx shadcn@latest add button
```
The command above will add the `Button` component to your project. You can then import it like this:
```astro title="src/pages/index.astro" {2,16} showLineNumbers
---
import { Button } from "@/components/ui/button"
---
Astro + TailwindCSS
```
================================================
FILE: apps/v4/content/docs/installation/gatsby.mdx
================================================
---
title: Gatsby
description: Install and configure Gatsby.
---
**Update:** We have added full support for React 19 and Tailwind v4 in the
`canary` release. See the docs for [Tailwind v4](/docs/tailwind-v4) for more
information.
### Create project
Start by creating a new Gatsby project using `create-gatsby`:
```bash
npm init gatsby
```
### Configure your Gatsby project to use TypeScript and Tailwind CSS
You will be asked a few questions to configure your project:
```txt showLineNumbers
✔ What would you like to call your site?
· your-app-name
✔ What would you like to name the folder where your site will be created?
· your-app-name
✔ Will you be using JavaScript or TypeScript?
· TypeScript
✔ Will you be using a CMS?
· Choose whatever you want
✔ Would you like to install a styling system?
· Tailwind CSS
✔ Would you like to install additional features with other plugins?
· Choose whatever you want
✔ Shall we do this? (Y/n) · Yes
```
### Edit tsconfig.json file
Add the following code to the `tsconfig.json` file to resolve paths:
```ts {4-9} showLineNumbers
{
"compilerOptions": {
// ...
"baseUrl": ".",
"paths": {
"@/*": [
"./src/*"
]
}
// ...
}
}
```
### Create gatsby-node.ts file
Create a `gatsby-node.ts` file at the root of your project if it doesn’t already exist, and add the code below to the `gatsby-node` file so your app can resolve paths:
```ts
import * as path from "path"
export const onCreateWebpackConfig = ({ actions }) => {
actions.setWebpackConfig({
resolve: {
alias: {
"@/components": path.resolve(__dirname, "src/components"),
"@/lib/utils": path.resolve(__dirname, "src/lib/utils"),
},
},
})
}
```
### Run the CLI
Run the `shadcn` init command to setup your project:
```bash
npx shadcn@latest init
```
### Configure components.json
You will be asked a few questions to configure `components.json`:
```txt showLineNumbers
Would you like to use TypeScript (recommended)? no / yes
Which style would you like to use? › Default
Which color would you like to use as base color? › Slate
Where is your global CSS file? › › ./src/styles/globals.css
Do you want to use CSS variables for colors? › no / yes
Where is your tailwind.config.js located? › tailwind.config.js
Configure the import alias for components: › @/components
Configure the import alias for utils: › @/lib/utils
Are you using React Server Components? › no
```
### That's it
You can now start adding components to your project.
```bash
npx shadcn@latest add button
```
The command above will add the `Button` component to your project. You can then import it like this:
```tsx {1,6} showLineNumbers
import { Button } from "@/components/ui/button"
export default function Home() {
return (
)
}
```
================================================
FILE: apps/v4/content/docs/installation/index.mdx
================================================
---
title: Installation
description: How to install dependencies and structure your app.
---
## Pick Your Framework
Start by selecting your framework of choice. Then follow the instructions to install the dependencies and structure your app. shadcn/ui is built to work with all React frameworks.
Next.js
Vite
Laravel
React Router
Astro
TanStack Start
TanStack Router
Manual
================================================
FILE: apps/v4/content/docs/installation/laravel.mdx
================================================
---
title: Laravel
description: Install and configure shadcn/ui for Laravel
---
### Create project
Start by creating a new Laravel project with Inertia and React using the laravel installer `laravel new my-app`:
```bash
laravel new my-app --react
```
### Add Components
You can now start adding components to your project.
```bash
npx shadcn@latest add switch
```
The command above will add the `Switch` component to `resources/js/components/ui/switch.tsx`. You can then import it like this:
```tsx title="resources/js/pages/index.tsx" {1,6} showLineNumbers
import { Switch } from "@/components/ui/switch"
const MyPage = () => {
return (
)
}
export default MyPage
```
================================================
FILE: apps/v4/content/docs/installation/manual.mdx
================================================
---
title: Manual Installation
description: Add dependencies to your project manually.
---
### Add Tailwind CSS
Components are styled using Tailwind CSS. You need to install Tailwind CSS in your project.
[Follow the Tailwind CSS installation instructions to get started.](https://tailwindcss.com/docs/installation)
### Add dependencies
Add the following dependencies to your project:
```bash
npm install class-variance-authority clsx tailwind-merge lucide-react tw-animate-css
```
### Configure path aliases
Configure the path aliases in your `tsconfig.json` file.
```json {3-6} title="tsconfig.json" showLineNumbers
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./*"]
}
}
}
```
The `@` alias is a preference. You can use other aliases if you want.
### Configure styles
Add the following to your styles/globals.css file. You can learn more about using CSS variables for theming in the [theming section](/docs/theming).
```css showLineNumbers title="src/styles/globals.css"
@import "tailwindcss";
@import "tw-animate-css";
@custom-variant dark (&:is(.dark *));
:root {
--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);
--destructive-foreground: 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);
--radius: 0.625rem;
--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.145 0 0);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.145 0 0);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.985 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.396 0.141 25.723);
--destructive-foreground: oklch(0.637 0.237 25.331);
--border: oklch(0.269 0 0);
--input: oklch(0.269 0 0);
--ring: oklch(0.439 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(0.269 0 0);
--sidebar-ring: oklch(0.439 0 0);
}
@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-destructive-foreground: var(--destructive-foreground);
--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);
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
--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);
}
@layer base {
* {
@apply border-border outline-ring/50;
}
body {
@apply bg-background text-foreground;
}
}
```
### Add a cn helper
```ts showLineNumbers title="lib/utils.ts"
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
```
### Create a `components.json` file
Create a `components.json` file in the root of your project.
```json title="components.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/styles/globals.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"iconLibrary": "lucide"
}
```
### That's it
You can now start adding components to your project.
================================================
FILE: apps/v4/content/docs/installation/meta.json
================================================
{
"pages": [
"next",
"vite",
"laravel",
"react-router",
"remix",
"astro",
"tanstack",
"tanstack-router",
"manual"
]
}
================================================
FILE: apps/v4/content/docs/installation/next.mdx
================================================
---
title: Next.js
description: Install and configure shadcn/ui for Next.js.
---
### Create project
Run the `init` command to create a new Next.js project or to setup an existing one:
```bash
npx shadcn@latest init
```
Choose between a Next.js project or a Monorepo.
### Add Components
You can now start adding components to your project.
```bash
npx shadcn@latest add button
```
The command above will add the `Button` component to your project. You can then import it like this:
```tsx {1,6} showLineNumbers title="app/page.tsx"
import { Button } from "@/components/ui/button"
export default function Home() {
return (
)
}
```
================================================
FILE: apps/v4/content/docs/installation/react-router.mdx
================================================
---
title: React Router
description: Install and configure shadcn/ui for React Router.
---
### Create project
```bash
npx create-react-router@latest my-app
```
### Run the CLI
Run the `shadcn` init command to setup your project:
```bash
npx shadcn@latest init
```
### Add Components
You can now start adding components to your project.
```bash
npx shadcn@latest add button
```
The command above will add the `Button` component to your project. You can then import it like this:
```tsx showLineNumbers title="app/routes/home.tsx"
import { Button } from "~/components/ui/button"
import type { Route } from "./+types/home"
export function meta({}: Route.MetaArgs) {
return [
{ title: "New React Router App" },
{ name: "description", content: "Welcome to React Router!" },
]
}
export default function Home() {
return (
)
}
```
================================================
FILE: apps/v4/content/docs/installation/remix.mdx
================================================
---
title: Remix
description: Install and configure shadcn/ui for Remix.
---
**Note:** This guide is for Remix. For React Router, see the [React Router](/docs/installation/react-router) guide.
### Create project
Start by creating a new Remix project using `create-remix`:
```bash
npx create-remix@latest my-app
```
### Run the CLI
Run the `shadcn` init command to setup your project:
```bash
npx shadcn@latest init
```
### Configure components.json
You will be asked a few questions to configure `components.json`:
```bash
Which color would you like to use as base color? › Neutral
```
### App structure
**Note**: This app structure is only a suggestion. You can place the files wherever you want.
- Place the UI components in the `app/components/ui` folder.
- Your own components can be placed in the `app/components` folder.
- The `app/lib` folder contains all the utility functions. We have a `utils.ts` where we define the `cn` helper.
- The `app/tailwind.css` file contains the global CSS.
### Install Tailwind CSS
```bash
npm install -D tailwindcss@latest autoprefixer@latest
```
Then we create a `postcss.config.js` file:
```js title="postcss.config.js" showLineNumbers
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
```
And finally we add the following to our `remix.config.js` file:
```js title="remix.config.js" {4-5} showLineNumbers
/** @type {import('@remix-run/dev').AppConfig} */
export default {
...
tailwind: true,
postcss: true,
...
};
```
### Add `tailwind.css` to your app
In your `app/root.tsx` file, import the `tailwind.css` file:
```js {1, 4} showLineNumbers title="app/root.tsx"
import styles from "./tailwind.css?url"
export const links: LinksFunction = () => [
{ rel: "stylesheet", href: styles },
...(cssBundleHref ? [{ rel: "stylesheet", href: cssBundleHref }] : []),
]
```
### That's it
You can now start adding components to your project.
```bash
npx shadcn@latest add button
```
The command above will add the `Button` component to your project. You can then import it like this:
```tsx {1,6} showLineNumbers title="app/routes/index.tsx"
import { Button } from "~/components/ui/button"
export default function Home() {
return (
)
}
```
================================================
FILE: apps/v4/content/docs/installation/tanstack-router.mdx
================================================
---
title: TanStack Router
description: Install and configure shadcn/ui for TanStack Router.
---
### Create project
Start by creating a new TanStack Router project:
```bash
npx create-tsrouter-app@latest my-app --template file-router --tailwind --add-ons shadcn
```
### Add Components
You can now start adding components to your project.
```bash
npx shadcn@canary add button
```
The command above will add the `Button` component to your project. You can then import it like this:
```tsx title="src/routes/index.tsx" showLineNumbers {3,12}
import { createFileRoute } from "@tanstack/react-router"
import { Button } from "@/components/ui/button"
export const Route = createFileRoute("/")({
component: App,
})
function App() {
return (
)
}
```
================================================
FILE: apps/v4/content/docs/installation/tanstack.mdx
================================================
---
title: TanStack Start
description: Install and configure shadcn/ui for TanStack Start.
---
### Create project
Start by creating a new TanStack Start project by following the [Build a Project from Scratch](https://tanstack.com/start/latest/docs/framework/react/build-from-scratch) guide on the TanStack Start website.
**Do not add Tailwind yet. We'll install Tailwind v4 in the next step.**
### Add Tailwind
Install `tailwindcss` and its dependencies.
```bash
npm install tailwindcss @tailwindcss/postcss postcss
```
### Create postcss.config.ts
Create a `postcss.config.ts` file at the root of your project.
```ts title="postcss.config.ts" showLineNumbers
export default {
plugins: {
"@tailwindcss/postcss": {},
},
}
```
### Create `app/styles/app.css`
Create an `app.css` file in the `app/styles` directory and import `tailwindcss`
```css title="app/styles/app.css"
@import "tailwindcss" source("../");
```
### Import `app.css`
```tsx title="app/routes/__root.tsx" showLineNumbers {5,21-26} showLineNumbers
import type { ReactNode } from "react"
import { createRootRoute, Outlet } from "@tanstack/react-router"
import { Meta, Scripts } from "@tanstack/start"
import appCss from "@/styles/app.css?url"
export const Route = createRootRoute({
head: () => ({
meta: [
{
charSet: "utf-8",
},
{
name: "viewport",
content: "width=device-width, initial-scale=1",
},
{
title: "TanStack Start Starter",
},
],
links: [
{
rel: "stylesheet",
href: appCss,
},
],
}),
component: RootComponent,
})
```
### Edit tsconfig.json file
Add the following code to the `tsconfig.json` file to resolve paths.
```ts title="tsconfig.json" showLineNumbers {9-12}
{
"compilerOptions": {
"jsx": "react-jsx",
"moduleResolution": "Bundler",
"module": "ESNext",
"target": "ES2022",
"skipLibCheck": true,
"strictNullChecks": true,
"baseUrl": ".",
"paths": {
"@/*": ["./app/*"]
}
}
}
```
### Run the CLI
Run the `shadcn` init command to setup your project:
```bash
npx shadcn@canary init
```
This will create a `components.json` file in the root of your project and configure CSS variables inside `app/styles/app.css`.
### That's it
You can now start adding components to your project.
```bash
npx shadcn@canary add button
```
The command above will add the `Button` component to your project. You can then import it like this:
```tsx title="app/routes/index.tsx" showLineNumbers {1,6}
import { Button } from "@/components/ui/button"
function Home() {
const router = useRouter()
const state = Route.useLoaderData()
return (
)
}
```
================================================
FILE: apps/v4/content/docs/installation/vite.mdx
================================================
---
title: Vite
description: Install and configure shadcn/ui for Vite.
---
### Create project
Start by creating a new React project using `vite`. Select the **React + TypeScript** template:
```bash
npm create vite@latest
```
### Add Tailwind CSS
```bash
npm install tailwindcss @tailwindcss/vite
```
Replace everything in `src/index.css` with the following:
```css title="src/index.css"
@import "tailwindcss";
```
### Edit tsconfig.json file
The current version of Vite splits TypeScript configuration into three files, two of which need to be edited.
Add the `baseUrl` and `paths` properties to the `compilerOptions` section of the `tsconfig.json` and
`tsconfig.app.json` files:
```ts title="tsconfig.json" {11-16} showLineNumbers
{
"files": [],
"references": [
{
"path": "./tsconfig.app.json"
},
{
"path": "./tsconfig.node.json"
}
],
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}
```
### Edit tsconfig.app.json file
Add the following code to the `tsconfig.app.json` file to resolve paths, for your IDE:
```ts title="tsconfig.app.json" {4-9} showLineNumbers
{
"compilerOptions": {
// ...
"baseUrl": ".",
"paths": {
"@/*": [
"./src/*"
]
}
// ...
}
}
```
### Update vite.config.ts
Add the following code to the vite.config.ts so your app can resolve paths without error:
```bash
npm install -D @types/node
```
```typescript title="vite.config.ts" showLineNumbers {1,2,8-13}
import path from "path"
import tailwindcss from "@tailwindcss/vite"
import react from "@vitejs/plugin-react"
import { defineConfig } from "vite"
// https://vite.dev/config/
export default defineConfig({
plugins: [react(), tailwindcss()],
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
})
```
### Run the CLI
Run the `shadcn` init command to setup your project:
```bash
npx shadcn@latest init
```
You will be asked a few questions to configure `components.json`.
```txt
Which color would you like to use as base color? › Neutral
```
### Add Components
You can now start adding components to your project.
```bash
npx shadcn@latest add button
```
The command above will add the `Button` component to your project. You can then import it like this:
```tsx showLineNumbers title="src/App.tsx"
import { Button } from "@/components/ui/button"
function App() {
return (
)
}
export default App
```
================================================
FILE: apps/v4/content/docs/registry/examples.mdx
================================================
---
title: Examples
description: "Examples of registry items: styles, components, css vars, etc."
---
## registry:style
### Custom style that extends shadcn/ui
The following registry item is a custom style that extends shadcn/ui. On `npx shadcn init`, it will:
- Install `@tabler/icons-react` as a dependency.
- Add the `login-01` block and `calendar` component to the project.
- Add the `editor` from a remote registry.
- Set the `font-sans` variable to `Inter, sans-serif`.
- Install a `brand` color in light and dark mode.
```json title="example-style.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "example-style",
"type": "registry:style",
"dependencies": ["@tabler/icons-react"],
"registryDependencies": [
"login-01",
"calendar",
"https://example.com/r/editor.json"
],
"cssVars": {
"theme": {
"font-sans": "Inter, sans-serif"
},
"light": {
"brand": "20 14.3% 4.1%"
},
"dark": {
"brand": "20 14.3% 4.1%"
}
}
}
```
### Custom style from scratch
The following registry item is a custom style that doesn't extend shadcn/ui. See the `extends: none` field.
It can be used to create a new style from scratch i.e custom components, css vars, dependencies, etc.
On `npx shadcn add`, the following will:
- Install `tailwind-merge` and `clsx` as dependencies.
- Add the `utils` registry item from the shadcn/ui registry.
- Add the `button`, `input`, `label`, and `select` components from a remote registry.
- Install new css vars: `main`, `bg`, `border`, `text`, `ring`.
```json title="example-style.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"extends": "none",
"name": "new-style",
"type": "registry:style",
"dependencies": ["tailwind-merge", "clsx"],
"registryDependencies": [
"utils",
"https://example.com/r/button.json",
"https://example.com/r/input.json",
"https://example.com/r/label.json",
"https://example.com/r/select.json"
],
"cssVars": {
"theme": {
"font-sans": "Inter, sans-serif",
}
"light": {
"main": "#88aaee",
"bg": "#dfe5f2",
"border": "#000",
"text": "#000",
"ring": "#000",
},
"dark": {
"main": "#88aaee",
"bg": "#272933",
"border": "#000",
"text": "#e6e6e6",
"ring": "#fff",
}
}
}
```
## registry:theme
### Custom theme
```json title="example-theme.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "custom-theme",
"type": "registry:theme",
"cssVars": {
"light": {
"background": "oklch(1 0 0)",
"foreground": "oklch(0.141 0.005 285.823)",
"primary": "oklch(0.546 0.245 262.881)",
"primary-foreground": "oklch(0.97 0.014 254.604)",
"ring": "oklch(0.746 0.16 232.661)",
"sidebar-primary": "oklch(0.546 0.245 262.881)",
"sidebar-primary-foreground": "oklch(0.97 0.014 254.604)",
"sidebar-ring": "oklch(0.746 0.16 232.661)"
},
"dark": {
"background": "oklch(1 0 0)",
"foreground": "oklch(0.141 0.005 285.823)",
"primary": "oklch(0.707 0.165 254.624)",
"primary-foreground": "oklch(0.97 0.014 254.604)",
"ring": "oklch(0.707 0.165 254.624)",
"sidebar-primary": "oklch(0.707 0.165 254.624)",
"sidebar-primary-foreground": "oklch(0.97 0.014 254.604)",
"sidebar-ring": "oklch(0.707 0.165 254.624)"
}
}
}
```
### Custom colors
The following style will init using shadcn/ui defaults and then add a custom `brand` color.
```json title="example-style.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "custom-style",
"type": "registry:style",
"cssVars": {
"light": {
"brand": "oklch(0.99 0.00 0)"
},
"dark": {
"brand": "oklch(0.14 0.00 286)"
}
}
}
```
## registry:block
### Custom block
This blocks installs the `login-01` block from the shadcn/ui registry.
```json title="login-01.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "login-01",
"type": "registry:block",
"description": "A simple login form.",
"registryDependencies": ["button", "card", "input", "label"],
"files": [
{
"path": "blocks/login-01/page.tsx",
"content": "import { LoginForm } ...",
"type": "registry:page",
"target": "app/login/page.tsx"
},
{
"path": "blocks/login-01/components/login-form.tsx",
"content": "...",
"type": "registry:component"
}
]
}
```
### Install a block and override primitives
You can install a block fromt the shadcn/ui registry and override the primitives using your custom ones.
On `npx shadcn add`, the following will:
- Add the `login-01` block from the shadcn/ui registry.
- Override the `button`, `input`, and `label` primitives with the ones from the remote registry.
```json title="example-style.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "custom-login",
"type": "registry:block",
"registryDependencies": [
"login-01",
"https://example.com/r/button.json",
"https://example.com/r/input.json",
"https://example.com/r/label.json"
]
}
```
## CSS Variables
### Custom Theme Variables
Add custom theme variables to the `theme` object.
```json title="example-theme.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "custom-theme",
"type": "registry:theme",
"cssVars": {
"theme": {
"font-heading": "Inter, sans-serif",
"shadow-card": "0 0 0 1px rgba(0, 0, 0, 0.1)"
}
}
}
```
### Override Tailwind CSS variables
```json title="example-theme.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "custom-theme",
"type": "registry:theme",
"cssVars": {
"theme": {
"spacing": "0.2rem",
"breakpoint-sm": "640px",
"breakpoint-md": "768px",
"breakpoint-lg": "1024px",
"breakpoint-xl": "1280px",
"breakpoint-2xl": "1536px"
}
}
}
```
## Add custom CSS
### Base styles
```json title="example-base.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "custom-style",
"type": "registry:style",
"css": {
"@layer base": {
"h1": {
"font-size": "var(--text-2xl)"
},
"h2": {
"font-size": "var(--text-xl)"
}
}
}
}
```
### Components
```json title="example-card.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "custom-card",
"type": "registry:component",
"css": {
"@layer components": {
"card": {
"background-color": "var(--color-white)",
"border-radius": "var(--rounded-lg)",
"padding": "var(--spacing-6)",
"box-shadow": "var(--shadow-xl)"
}
}
}
}
```
## Add custom utilities
### Simple utility
```json title="example-component.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "custom-component",
"type": "registry:component",
"css": {
"@utility content-auto": {
"content-visibility": "auto"
}
}
}
```
### Complex utility
```json title="example-utility.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "custom-component",
"type": "registry:component",
"css": {
"@utility scrollbar-hidden": {
"scrollbar-hidden": {
"&::-webkit-scrollbar": {
"display": "none"
}
}
}
}
}
```
### Functional utilities
```json title="example-functional.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "custom-component",
"type": "registry:component",
"css": {
"@utility tab-*": {
"tab-size": "var(--tab-size-*)"
}
}
}
```
## Add custom plugins
```json title="example-plugin.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "custom-plugin",
"type": "registry:component",
"css": {
"@plugin @tailwindcss/typography": {},
"@plugin foo": {}
}
}
```
## Add custom animations
Note: you need to define both `@keyframes` in css and `theme` in cssVars to use animations.
```json title="example-component.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "custom-component",
"type": "registry:component",
"cssVars": {
"theme": {
"--animate-wiggle": "wiggle 1s ease-in-out infinite"
}
},
"css": {
"@keyframes wiggle": {
"0%, 100%": {
"transform": "rotate(-3deg)"
},
"50%": {
"transform": "rotate(3deg)"
}
}
}
}
```
## Universal Items
As of `2.9.0`, you can create universal items that can be installed without framework detection or components.json.
To make an item universal i.e framework agnostic, all the files in the item must have an explicit target.
Here's an example of a registry item that installs custom Cursor rules for _python_:
```json title=".cursor/rules/custom-python.mdc" showLineNumbers {9}
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "python-rules",
"type": "registry:item",
"files": [
{
"path": "/path/to/your/registry/default/custom-python.mdc",
"type": "registry:file",
"target": "~/.cursor/rules/custom-python.mdc",
"content": "..."
}
]
}
```
Here's another example for installation custom ESLint config:
```json title=".eslintrc.json" showLineNumbers {9}
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "my-eslint-config",
"type": "registry:item",
"files": [
{
"path": "/path/to/your/registry/default/custom-eslint.json",
"type": "registry:file",
"target": "~/.eslintrc.json",
"content": "..."
}
]
}
```
You can also have a universal item that installs multiple files:
```json title="my-custom-starter-template.json" showLineNumbers {9}
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "my-custom-start-template",
"type": "registry:item",
dependencies: ["better-auth"]
"files": [
{
"path": "/path/to/file-01.json",
"type": "registry:file",
"target": "~/file-01.json",
"content": "..."
},
{
"path": "/path/to/file-02.vue",
"type": "registry:file",
"target": "~/pages/file-02.vue",
"content": "..."
}
]
}
```
================================================
FILE: apps/v4/content/docs/registry/faq.mdx
================================================
---
title: FAQ
description: Frequently asked questions about running a registry.
---
## Frequently asked questions
### What does a complex component look like?
Here's an example of a complex component that installs a page, two components, a hook, a format-date utils and a config file.
```json showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "hello-world",
"title": "Hello World",
"type": "registry:block",
"description": "A complex hello world component",
"files": [
{
"path": "registry/new-york/hello-world/page.tsx",
"type": "registry:page",
"target": "app/hello/page.tsx"
},
{
"path": "registry/new-york/hello-world/components/hello-world.tsx",
"type": "registry:component"
},
{
"path": "registry/new-york/hello-world/components/formatted-message.tsx",
"type": "registry:component"
},
{
"path": "registry/new-york/hello-world/hooks/use-hello.ts",
"type": "registry:hook"
},
{
"path": "registry/new-york/hello-world/lib/format-date.ts",
"type": "registry:utils"
},
{
"path": "registry/new-york/hello-world/hello.config.ts",
"type": "registry:file",
"target": "~/hello.config.ts"
}
]
}
```
### How do I add a new Tailwind color?
To add a new color you need to add it to `cssVars` under `light` and `dark` keys.
```json showLineNumbers {10-18}
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "hello-world",
"title": "Hello World",
"type": "registry:block",
"description": "A complex hello world component",
"files": [
// ...
],
"cssVars": {
"light": {
"brand-background": "20 14.3% 4.1%",
"brand-accent": "20 14.3% 4.1%"
},
"dark": {
"brand-background": "20 14.3% 4.1%",
"brand-accent": "20 14.3% 4.1%"
}
}
}
```
The CLI will update the project CSS file. Once updated, the new colors will be available to be used as utility classes: `bg-brand` and `text-brand-accent`.
### How do I add or override a Tailwind theme variable?
To add or override a theme variable you add it to `cssVars.theme` under the key you want to add or override.
```json showLineNumbers {10-15}
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "hello-world",
"title": "Hello World",
"type": "registry:block",
"description": "A complex hello world component",
"files": [
// ...
],
"cssVars": {
"theme": {
"text-base": "3rem",
"ease-in-out": "cubic-bezier(0.4, 0, 0.2, 1)",
"font-heading": "Poppins, sans-serif"
}
}
}
```
================================================
FILE: apps/v4/content/docs/registry/getting-started.mdx
================================================
---
title: Getting Started
description: Learn how to get setup and run your own component registry.
---
This guide will walk you through the process of setting up your own component registry.
It assumes you already have a project with components and would like to turn it into a registry.
If you're starting a new registry project, you can use the [registry template](https://github.com/shadcn-ui/registry-template) as a starting point. We have already configured it for you.
## registry.json
The `registry.json` file is only required if you're using the `shadcn` CLI to build your registry.
If you're using a different build system, you can skip this step as long as your build system produces valid JSON files that conform to the [registry-item schema specification](/docs/registry/registry-item-json).
### Add a registry.json file
Create a `registry.json` file in the root of your project. Your project can be a Next.js, Remix, Vite, or any other project that supports React.
```json title="registry.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry.json",
"name": "acme",
"homepage": "https://acme.com",
"items": [
// ...
]
}
```
This `registry.json` file must conform to the [registry schema specification](/docs/registry/registry-json).
## Add a registry item
### Create your component
Add your first component. Here's an example of a simple `` component:
```tsx title="registry/new-york/hello-world/hello-world.tsx" showLineNumbers
import { Button } from "@/components/ui/button"
export function HelloWorld() {
return
}
```
**Note:** This example places the component in the `registry/new-york`
directory. You can place it anywhere in your project as long as you set the
correct path in the `registry.json` file and you follow the `registry/[NAME]`
directory structure.
```txt
registry
└── new-york
└── hello-world
└── hello-world.tsx
```
### Add your component to the registry
To add your component to the registry, you need to add your component definition to `registry.json`.
```json title="registry.json" showLineNumbers {6-17}
{
"$schema": "https://ui.shadcn.com/schema/registry.json",
"name": "acme",
"homepage": "https://acme.com",
"items": [
{
"name": "hello-world",
"type": "registry:block",
"title": "Hello World",
"description": "A simple hello world component.",
"files": [
{
"path": "registry/new-york/hello-world/hello-world.tsx",
"type": "registry:component"
}
]
}
]
}
```
You define your registry item by adding a `name`, `type`, `title`, `description` and `files`.
For every file you add, you must specify the `path` and `type` of the file. The `path` is the relative path to the file from the root of your project. The `type` is the type of the file.
You can read more about the registry item schema and file types in the [registry item schema docs](/docs/registry/registry-item-json).
## Build your registry
### Install the shadcn CLI
Note: the `build` command is currently only available in the `shadcn@canary` version of the CLI.
```bash
npm install shadcn@canary
```
### Add a build script
Add a `registry:build` script to your `package.json` file.
```json title="package.json" showLineNumbers
{
"scripts": {
"registry:build": "shadcn build"
}
}
```
### Run the build script
Run the build script to generate the registry JSON files.
```bash
npm run registry:build
```
**Note:** By default, the build script will generate the registry JSON files
in `public/r` e.g `public/r/hello-world.json`.
You can change the output directory by passing the `--output` option. See the [shadcn build command](/docs/cli#build) for more information.
## Serve your registry
If you're running your registry on Next.js, you can now serve your registry by running the `next` server. The command might differ for other frameworks.
```bash
npm run dev
```
Your files will now be served at `http://localhost:3000/r/[NAME].json` eg. `http://localhost:3000/r/hello-world.json`.
## Publish your registry
To make your registry available to other developers, you can publish it by deploying your project to a public URL.
## Adding Auth
The `shadcn` CLI does not offer a built-in way to add auth to your registry. We recommend handling authorization on your registry server.
A common simple approach is to use a `token` query parameter to authenticate requests to your registry. e.g. `http://localhost:3000/r/hello-world.json?token=[SECURE_TOKEN_HERE]`.
Use the secure token to authenticate requests and return a 401 Unauthorized response if the token is invalid. Both the `shadcn` CLI and `Open in v0` will handle the 401 response and display a message to the user.
**Note:** Make sure to encrypt and expire tokens.
## Guidelines
Here are some guidelines to follow when building components for a registry.
- Place your registry item in the `registry/[STYLE]/[NAME]` directory. I'm using `new-york` as an example. It can be anything you want as long as it's nested under the `registry` directory.
- The following properties are required for the block definition: `name`, `description`, `type` and `files`.
- 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 or a URL to a registry item eg. `http://localhost:3000/r/editor.json`.
- Make sure to list all dependencies in `dependencies`. A dependency is the name of the package in the registry eg. `zod`, `sonner`, etc. To set a version, you can use the `name@version` format eg. `zod@^3.20.0`.
- **Imports should always use the `@/registry` path.** eg. `import { HelloWorld } from "@/registry/new-york/hello-world/hello-world"`
- Ideally, place your files within a registry item in `components`, `hooks`, `lib` directories.
## Install using the CLI
To install a registry item using the `shadcn` CLI, use the `add` command followed by the URL of the registry item.
```bash
npx shadcn@latest add http://localhost:3000/r/hello-world.json
```
================================================
FILE: apps/v4/content/docs/registry/index.mdx
================================================
---
title: Registry
description: Run your own code registry.
---
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.
**Note:** The registry works with any project type and any framework, and is
not limited to React.
A distribution system for code
## Requirements
You are free to design and host your custom registry as you see fit. The only requirement is that your registry items must be valid JSON files that conform to the [registry-item schema specification](/docs/registry/registry-item-json).
If you'd like to see an example of a registry, we have a [template project](https://github.com/shadcn-ui/registry-template) for you to use as a starting point.
================================================
FILE: apps/v4/content/docs/registry/meta.json
================================================
{
"pages": [
"index",
"getting-started",
"faq",
"open-in-v0",
"examples",
"registry-json",
"registry-item-json"
]
}
================================================
FILE: apps/v4/content/docs/registry/open-in-v0.mdx
================================================
---
title: Open in v0
description: Integrate your registry with Open in v0.
---
If your registry is hosted and publicly accessible via a URL, you can open a registry item in v0 by using the `https://v0.dev/chat/api/open?url=[URL]` endpoint.
eg. [https://v0.dev/chat/api/open?url=https://ui.shadcn.com/r/styles/new-york/login-01.json](https://v0.dev/chat/api/open?url=https://ui.shadcn.com/r/styles/new-york/login-01.json)
**Note:** The `Open in v0` button does not support `cssVars` and `tailwind`
properties.
## Button
See [Build your Open in v0 button](https://v0.dev/chat/button) for more information on how to build your own `Open in v0` button.
Here's a simple example of how to add a `Open in v0` button to your site.
```jsx showLineNumbers
import { Button } from "@/components/ui/button"
export function OpenInV0Button({ url }: { url: string }) {
return (
)
}
```
```jsx
```
## Authentication
See the [Adding Auth](/docs/registry/getting-started#adding-auth) section for more information on how to authenticate requests to your registry and Open in v0.
================================================
FILE: apps/v4/content/docs/registry/registry-item-json.mdx
================================================
---
title: registry-item.json
description: Specification for registry items.
---
The `registry-item.json` schema is used to define your custom registry items.
```json title="registry-item.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "hello-world",
"type": "registry:block",
"title": "Hello World",
"description": "A simple hello world component.",
"files": [
{
"path": "registry/new-york/hello-world/hello-world.tsx",
"type": "registry:component"
},
{
"path": "registry/new-york/hello-world/use-hello-world.ts",
"type": "registry:hook"
}
],
"cssVars": {
"theme": {
"font-heading": "Poppins, sans-serif"
},
"light": {
"brand": "20 14.3% 4.1%"
},
"dark": {
"brand": "20 14.3% 4.1%"
}
}
}
```
See more examples
## Definitions
You can see the JSON Schema for `registry-item.json` [here](https://ui.shadcn.com/schema/registry-item.json).
### $schema
The `$schema` property is used to specify the schema for the `registry-item.json` file.
```json title="registry-item.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json"
}
```
### name
The name of the item. This is used to identify the item in the registry. It should be unique for your registry.
```json title="registry-item.json" showLineNumbers
{
"name": "hello-world"
}
```
### title
A human-readable title for your registry item. Keep it short and descriptive.
```json title="registry-item.json" showLineNumbers
{
"title": "Hello World"
}
```
### description
A description of your registry item. This can be longer and more detailed than the `title`.
```json title="registry-item.json" showLineNumbers
{
"description": "A simple hello world component."
}
```
### type
The `type` property is used to specify the type of your registry item. This is used to determine the type and target path of the item when resolved for a project.
```json title="registry-item.json" showLineNumbers
{
"type": "registry:block"
}
```
The following types are supported:
| Type | Description |
| -------------------- | ------------------------------------------------ |
| `registry:block` | Use for complex components with multiple files. |
| `registry:component` | Use for simple components. |
| `registry:lib` | Use for lib and utils. |
| `registry:hook` | Use for hooks. |
| `registry:ui` | Use for UI components and single-file primitives |
| `registry:page` | Use for page or file-based routes. |
| `registry:file` | Use for miscellaneous files. |
| `registry:style` | Use for registry styles. eg. `new-york` |
| `registry:theme` | Use for themes. |
| `registry:item` | Use for universal registry items. |
### author
The `author` property is used to specify the author of the registry item.
It can be unique to the registry item or the same as the author of the registry.
```json title="registry-item.json" showLineNumbers
{
"author": "John Doe "
}
```
### dependencies
The `dependencies` property is used to specify the dependencies of your registry item. This is for `npm` packages.
Use `@version` to specify the version of your registry item.
```json title="registry-item.json" showLineNumbers
{
"dependencies": [
"@radix-ui/react-accordion",
"zod",
"lucide-react",
"name@1.0.2"
]
}
```
### registryDependencies
Used for registry dependencies. Can be names or URLs. Use the name of the item to reference shadcn/ui components and urls to reference other registries.
- For `shadcn/ui` registry items such as `button`, `input`, `select`, etc use the name eg. `['button', 'input', 'select']`.
- For custom registry items use the URL of the registry item eg. `['https://example.com/r/hello-world.json']`.
```json title="registry-item.json" showLineNumbers
{
"registryDependencies": [
"button",
"input",
"select",
"https://example.com/r/editor.json"
]
}
```
Note: The CLI will automatically resolve remote registry dependencies.
### files
The `files` property is used to specify the files of your registry item. Each file has a `path`, `type` and `target` (optional) property.
**The `target` property is required for `registry:page` and `registry:file` types.**
```json title="registry-item.json" showLineNumbers
{
"files": [
{
"path": "registry/new-york/hello-world/page.tsx",
"type": "registry:page",
"target": "app/hello/page.tsx"
},
{
"path": "registry/new-york/hello-world/hello-world.tsx",
"type": "registry:component"
},
{
"path": "registry/new-york/hello-world/use-hello-world.ts",
"type": "registry:hook"
},
{
"path": "registry/new-york/hello-world/.env",
"type": "registry:file",
"target": "~/.env"
}
]
}
```
#### path
The `path` property is used to specify the path to the file in your registry. This path is used by the build script to parse, transform and build the registry JSON payload.
#### type
The `type` property is used to specify the type of the file. See the [type](#type) section for more information.
#### target
The `target` property is used to indicate where the file should be placed in a project. This is optional and only required for `registry:page` and `registry:file` types.
By default, the `shadcn` cli will read a project's `components.json` file to determine the target path. For some files, such as routes or config you can specify the target path manually.
Use `~` to refer to the root of the project e.g `~/foo.config.js`.
### tailwind
**DEPRECATED:** Use `cssVars.theme` instead for Tailwind v4 projects.
The `tailwind` property is used for tailwind configuration such as `theme`, `plugins` and `content`.
You can use the `tailwind.config` property to add colors, animations and plugins to your registry item.
```json title="registry-item.json" showLineNumbers
{
"tailwind": {
"config": {
"theme": {
"extend": {
"colors": {
"brand": "hsl(var(--brand))"
},
"keyframes": {
"wiggle": {
"0%, 100%": { "transform": "rotate(-3deg)" },
"50%": { "transform": "rotate(3deg)" }
}
},
"animation": {
"wiggle": "wiggle 1s ease-in-out infinite"
}
}
}
}
}
}
```
### cssVars
Use to define CSS variables for your registry item.
```json title="registry-item.json" showLineNumbers
{
"cssVars": {
"theme": {
"font-heading": "Poppins, sans-serif"
},
"light": {
"brand": "20 14.3% 4.1%",
"radius": "0.5rem"
},
"dark": {
"brand": "20 14.3% 4.1%"
}
}
}
```
### css
Use `css` to add new rules to the project's CSS file eg. `@layer base`, `@layer components`, `@utility`, `@keyframes`, `@plugin`, etc.
```json title="registry-item.json" showLineNumbers
{
"css": {
"@plugin @tailwindcss/typography": {},
"@plugin foo": {},
"@layer base": {
"body": {
"font-size": "var(--text-base)",
"line-height": "1.5"
}
},
"@layer components": {
"button": {
"background-color": "var(--color-primary)",
"color": "var(--color-white)"
}
},
"@utility text-magic": {
"font-size": "var(--text-base)",
"line-height": "1.5"
},
"@keyframes wiggle": {
"0%, 100%": {
"transform": "rotate(-3deg)"
},
"50%": {
"transform": "rotate(3deg)"
}
}
}
}
```
### docs
Use `docs` to show custom documentation or message when installing your registry item via the CLI.
```json title="registry-item.json" showLineNumbers
{
"docs": "Remember to add the FOO_BAR environment variable to your .env file."
}
```
### categories
Use `categories` to organize your registry item.
```json title="registry-item.json" showLineNumbers
{
"categories": ["sidebar", "dashboard"]
}
```
### meta
Use `meta` to add additional metadata to your registry item. You can add any key/value pair that you want to be available to the registry item.
```json title="registry-item.json" showLineNumbers
{
"meta": { "foo": "bar" }
}
```
================================================
FILE: apps/v4/content/docs/registry/registry-json.mdx
================================================
---
title: registry.json
description: Schema for running your own component registry.
---
The `registry.json` schema is used to define your custom component registry.
```json title="registry.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry.json",
"name": "shadcn",
"homepage": "https://ui.shadcn.com",
"items": [
{
"name": "hello-world",
"type": "registry:block",
"title": "Hello World",
"description": "A simple hello world component.",
"files": [
{
"path": "registry/new-york/hello-world/hello-world.tsx",
"type": "registry:component"
}
]
}
]
}
```
## Definitions
You can see the JSON Schema for `registry.json` [here](https://ui.shadcn.com/schema/registry.json).
### $schema
The `$schema` property is used to specify the schema for the `registry.json` file.
```json title="registry.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry.json"
}
```
### name
The `name` property is used to specify the name of your registry. This is used for data attributes and other metadata.
```json title="registry.json" showLineNumbers
{
"name": "acme"
}
```
### homepage
The homepage of your registry. This is used for data attributes and other metadata.
```json title="registry.json" showLineNumbers
{
"homepage": "https://acme.com"
}
```
### items
The `items` in your registry. Each item must implement the [registry-item schema specification](https://ui.shadcn.com/schema/registry-item.json).
```json title="registry.json" showLineNumbers
{
"items": [
{
"name": "hello-world",
"type": "registry:block",
"title": "Hello World",
"description": "A simple hello world component.",
"files": [
{
"path": "registry/new-york/hello-world/hello-world.tsx",
"type": "registry:component"
}
]
}
]
}
```
See the [registry-item schema documentation](/docs/registry/registry-item-json) for more information.