mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-06-11 09:51:40 +00:00
fix
This commit is contained in:
@@ -195,6 +195,346 @@ On `npx shadcn add`, the following will:
|
||||
}
|
||||
```
|
||||
|
||||
## registry:ui
|
||||
|
||||
### UI component
|
||||
|
||||
A `registry:ui` item is a reusable UI component. It can have dependencies, registry dependencies, and CSS variables.
|
||||
|
||||
```json title="button.json" showLineNumbers
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "button",
|
||||
"type": "registry:ui",
|
||||
"dependencies": ["radix-ui"],
|
||||
"files": [
|
||||
{
|
||||
"path": "ui/button.tsx",
|
||||
"content": "...",
|
||||
"type": "registry:ui"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### UI component with CSS variables
|
||||
|
||||
```json title="sidebar.json" showLineNumbers
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "sidebar",
|
||||
"type": "registry:ui",
|
||||
"dependencies": ["radix-ui"],
|
||||
"registryDependencies": ["button", "separator", "sheet", "tooltip"],
|
||||
"files": [
|
||||
{
|
||||
"path": "ui/sidebar.tsx",
|
||||
"content": "...",
|
||||
"type": "registry:ui"
|
||||
}
|
||||
],
|
||||
"cssVars": {
|
||||
"light": {
|
||||
"sidebar-background": "oklch(0.985 0 0)",
|
||||
"sidebar-foreground": "oklch(0.141 0.005 285.823)",
|
||||
"sidebar-border": "oklch(0.92 0.004 286.32)"
|
||||
},
|
||||
"dark": {
|
||||
"sidebar-background": "oklch(0.141 0.005 285.823)",
|
||||
"sidebar-foreground": "oklch(0.985 0 0)",
|
||||
"sidebar-border": "oklch(0.274 0.006 286.033)"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## registry:lib
|
||||
|
||||
### Utility library
|
||||
|
||||
A `registry:lib` item is a utility library. Use it to share helper functions, constants, or other non-component code.
|
||||
|
||||
```json title="utils.json" showLineNumbers
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "utils",
|
||||
"type": "registry:lib",
|
||||
"dependencies": ["clsx", "tailwind-merge"],
|
||||
"files": [
|
||||
{
|
||||
"path": "lib/utils.ts",
|
||||
"content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}",
|
||||
"type": "registry:lib"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## registry:hook
|
||||
|
||||
### Custom hook
|
||||
|
||||
A `registry:hook` item is a custom React hook.
|
||||
|
||||
```json title="use-mobile.json" showLineNumbers
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "use-mobile",
|
||||
"type": "registry:hook",
|
||||
"files": [
|
||||
{
|
||||
"path": "hooks/use-mobile.ts",
|
||||
"content": "...",
|
||||
"type": "registry:hook"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Hook with dependencies
|
||||
|
||||
```json title="use-debounce.json" showLineNumbers
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "use-debounce",
|
||||
"type": "registry:hook",
|
||||
"dependencies": ["react"],
|
||||
"files": [
|
||||
{
|
||||
"path": "hooks/use-debounce.ts",
|
||||
"content": "...",
|
||||
"type": "registry:hook"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## registry:font
|
||||
|
||||
### Custom font
|
||||
|
||||
A `registry:font` item installs a Google Font. The `font` field is required and configures the font family, provider, import name, and CSS variable.
|
||||
|
||||
```json title="font-inter.json" showLineNumbers
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "font-inter",
|
||||
"type": "registry:font",
|
||||
"font": {
|
||||
"family": "'Inter Variable', sans-serif",
|
||||
"provider": "google",
|
||||
"import": "Inter",
|
||||
"variable": "--font-sans",
|
||||
"subsets": ["latin"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Monospace font
|
||||
|
||||
```json title="font-jetbrains-mono.json" showLineNumbers
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "font-jetbrains-mono",
|
||||
"type": "registry:font",
|
||||
"font": {
|
||||
"family": "'JetBrains Mono Variable', monospace",
|
||||
"provider": "google",
|
||||
"import": "JetBrains_Mono",
|
||||
"variable": "--font-mono",
|
||||
"weight": ["400", "500", "600", "700"],
|
||||
"subsets": ["latin"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Serif font
|
||||
|
||||
```json title="font-lora.json" showLineNumbers
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "font-lora",
|
||||
"type": "registry:font",
|
||||
"font": {
|
||||
"family": "'Lora Variable', serif",
|
||||
"provider": "google",
|
||||
"import": "Lora",
|
||||
"variable": "--font-serif",
|
||||
"subsets": ["latin"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## registry:base
|
||||
|
||||
### Custom base
|
||||
|
||||
A `registry:base` item is a complete design system base. It defines the full set of dependencies, CSS variables, and configuration for a project. The `config` field is unique to `registry:base` items.
|
||||
|
||||
The `config` field accepts the following properties (all optional):
|
||||
|
||||
| Property | Type | Description |
|
||||
| -------------------- | ---------------------------------- | --------------------------------------------------------------- |
|
||||
| `style` | `string` | The style name for the base. |
|
||||
| `iconLibrary` | `string` | The icon library to use (e.g. `lucide`). |
|
||||
| `rsc` | `boolean` | Whether to enable React Server Components. Defaults to `false`. |
|
||||
| `tsx` | `boolean` | Whether to use TypeScript. Defaults to `true`. |
|
||||
| `rtl` | `boolean` | Whether to enable right-to-left support. Defaults to `false`. |
|
||||
| `menuColor` | `"default" \| "inverted"` | The menu color scheme. Defaults to `"default"`. |
|
||||
| `menuAccent` | `"subtle" \| "bold"` | The menu accent style. Defaults to `"subtle"`. |
|
||||
| `tailwind.baseColor` | `string` | The base color name (e.g. `neutral`, `slate`, `zinc`). |
|
||||
| `tailwind.css` | `string` | Path to the Tailwind CSS file. |
|
||||
| `tailwind.prefix` | `string` | A prefix to add to all Tailwind classes. |
|
||||
| `aliases.components` | `string` | Import alias for components. |
|
||||
| `aliases.utils` | `string` | Import alias for utilities. |
|
||||
| `aliases.ui` | `string` | Import alias for UI components. |
|
||||
| `aliases.lib` | `string` | Import alias for lib. |
|
||||
| `aliases.hooks` | `string` | Import alias for hooks. |
|
||||
| `registries` | `Record<string, string \| object>` | Custom registry URLs. Keys must start with `@`. |
|
||||
|
||||
```json title="custom-base.json" showLineNumbers
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "custom-base",
|
||||
"type": "registry:base",
|
||||
"config": {
|
||||
"style": "custom-base",
|
||||
"iconLibrary": "lucide",
|
||||
"tailwind": {
|
||||
"baseColor": "neutral"
|
||||
}
|
||||
},
|
||||
"dependencies": [
|
||||
"class-variance-authority",
|
||||
"tw-animate-css",
|
||||
"lucide-react"
|
||||
],
|
||||
"registryDependencies": ["utils", "font-inter"],
|
||||
"cssVars": {
|
||||
"light": {
|
||||
"background": "oklch(1 0 0)",
|
||||
"foreground": "oklch(0.141 0.005 285.823)",
|
||||
"primary": "oklch(0.21 0.006 285.885)",
|
||||
"primary-foreground": "oklch(0.985 0 0)"
|
||||
},
|
||||
"dark": {
|
||||
"background": "oklch(0.141 0.005 285.823)",
|
||||
"foreground": "oklch(0.985 0 0)",
|
||||
"primary": "oklch(0.985 0 0)",
|
||||
"primary-foreground": "oklch(0.21 0.006 285.885)"
|
||||
}
|
||||
},
|
||||
"css": {
|
||||
"@import \"tw-animate-css\"": {},
|
||||
"@layer base": {
|
||||
"*": {
|
||||
"@apply border-border outline-ring/50": {}
|
||||
},
|
||||
"body": {
|
||||
"@apply bg-background text-foreground": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Base from scratch
|
||||
|
||||
Use `extends: none` to create a base that doesn't extend shadcn/ui defaults.
|
||||
|
||||
```json title="custom-base.json" showLineNumbers
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "my-design-system",
|
||||
"extends": "none",
|
||||
"type": "registry:base",
|
||||
"config": {
|
||||
"style": "my-design-system",
|
||||
"iconLibrary": "lucide",
|
||||
"tailwind": {
|
||||
"baseColor": "slate"
|
||||
}
|
||||
},
|
||||
"dependencies": ["tailwind-merge", "clsx", "tw-animate-css", "lucide-react"],
|
||||
"registryDependencies": ["utils", "font-geist"],
|
||||
"cssVars": {
|
||||
"light": {
|
||||
"background": "oklch(1 0 0)",
|
||||
"foreground": "oklch(0.141 0.005 285.823)"
|
||||
},
|
||||
"dark": {
|
||||
"background": "oklch(0.141 0.005 285.823)",
|
||||
"foreground": "oklch(0.985 0 0)"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Common Fields
|
||||
|
||||
### Author
|
||||
|
||||
Use the `author` field to add attribution to your registry items.
|
||||
|
||||
```json title="example-item.json" showLineNumbers {5}
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "custom-component",
|
||||
"type": "registry:ui",
|
||||
"author": "shadcn",
|
||||
"files": [
|
||||
{
|
||||
"path": "ui/custom-component.tsx",
|
||||
"content": "...",
|
||||
"type": "registry:ui"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Dev dependencies
|
||||
|
||||
Use the `devDependencies` field to install packages as dev dependencies.
|
||||
|
||||
```json title="example-item.json" showLineNumbers {5}
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "custom-item",
|
||||
"type": "registry:item",
|
||||
"devDependencies": ["@types/mdx"],
|
||||
"files": [
|
||||
{
|
||||
"path": "lib/mdx.ts",
|
||||
"content": "...",
|
||||
"type": "registry:lib"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Metadata
|
||||
|
||||
Use the `meta` field to attach arbitrary metadata to your registry items. This can be used to store custom data that your tools or scripts can use.
|
||||
|
||||
```json title="example-item.json" showLineNumbers {5-8}
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "custom-component",
|
||||
"type": "registry:ui",
|
||||
"meta": {
|
||||
"category": "forms",
|
||||
"version": "2.0.0"
|
||||
},
|
||||
"files": [
|
||||
{
|
||||
"path": "ui/custom-component.tsx",
|
||||
"content": "...",
|
||||
"type": "registry:ui"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## CSS Variables
|
||||
|
||||
### Custom Theme Variables
|
||||
|
||||
@@ -67,7 +67,7 @@ These rules are **always enforced**. Each links to a file with Incorrect/Correct
|
||||
The injected project context contains these key fields:
|
||||
|
||||
- **`aliases`** → use the actual alias prefix for imports (e.g. `@/`, `~/`), never hardcode.
|
||||
- **`isRSC`** → when `true`, components using `useState`, `useEffect`, event handlers, or browser APIs need `"use client"`.
|
||||
- **`isRSC`** → when `true`, components using `useState`, `useEffect`, event handlers, or browser APIs need `"use client"` at the top of the file. Always reference this field when advising on the directive.
|
||||
- **`tailwindVersion`** → `"v4"` uses `@theme inline` blocks; `"v3"` uses `tailwind.config.js`.
|
||||
- **`tailwindCssFile`** → the global CSS file where custom CSS variables are defined. Always edit this file, never create a new one.
|
||||
- **`style`** → component visual treatment (e.g. `nova`, `vega`).
|
||||
|
||||
@@ -95,15 +95,17 @@ Don't build custom empty state markup.
|
||||
**Correct:**
|
||||
|
||||
```tsx
|
||||
import { Empty, EmptyIcon, EmptyTitle, EmptyDescription, EmptyActions } from "@/components/ui/empty"
|
||||
import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "@/components/ui/empty"
|
||||
|
||||
<Empty>
|
||||
<EmptyIcon><FolderIcon /></EmptyIcon>
|
||||
<EmptyTitle>No projects yet</EmptyTitle>
|
||||
<EmptyDescription>Get started by creating a new project.</EmptyDescription>
|
||||
<EmptyActions>
|
||||
<EmptyHeader>
|
||||
<EmptyMedia variant="icon"><FolderIcon /></EmptyMedia>
|
||||
<EmptyTitle>No projects yet</EmptyTitle>
|
||||
<EmptyDescription>Get started by creating a new project.</EmptyDescription>
|
||||
</EmptyHeader>
|
||||
<EmptyContent>
|
||||
<Button>Create Project</Button>
|
||||
</EmptyActions>
|
||||
</EmptyContent>
|
||||
</Empty>
|
||||
```
|
||||
|
||||
@@ -141,7 +143,7 @@ toast("File deleted.", {
|
||||
|
||||
## Choosing between overlay components
|
||||
|
||||
Don't default to `Dialog` for everything.
|
||||
Don't default to `Dialog` for everything. **When recommending an overlay, always show the full component structure with all required subcomponents.**
|
||||
|
||||
**Incorrect:**
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Icons
|
||||
|
||||
**Always use the project's configured `iconLibrary` for imports.** Check the `iconLibrary` field from project context: `lucide` → `lucide-react`, `tabler` → `@tabler/icons-react`, etc. Never assume `lucide-react`.
|
||||
|
||||
---
|
||||
|
||||
## Icons in Button use data-icon attribute
|
||||
|
||||
@@ -44,6 +44,8 @@ See [customization.md](../customization.md) for theming, CSS variables, and addi
|
||||
|
||||
## className for layout only
|
||||
|
||||
Use `className` for layout (e.g. `max-w-md`, `mx-auto`, `mt-4`), **not** for overriding component colors or typography. To change colors, use semantic tokens, built-in variants, or CSS variables.
|
||||
|
||||
**Incorrect:**
|
||||
|
||||
```tsx
|
||||
@@ -59,3 +61,8 @@ See [customization.md](../customization.md) for theming, CSS variables, and addi
|
||||
<CardContent>Dashboard</CardContent>
|
||||
</Card>
|
||||
```
|
||||
|
||||
To customize a component's appearance, prefer these approaches in order:
|
||||
1. **Built-in variants** — `variant="outline"`, `variant="destructive"`, etc.
|
||||
2. **Semantic color tokens** — `bg-primary`, `text-muted-foreground`.
|
||||
3. **CSS variables** — define custom colors in the global CSS file (see [customization.md](../customization.md)).
|
||||
|
||||
Reference in New Issue
Block a user