mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-06-21 14:51:33 +00:00
Compare commits
14 Commits
shadcn@2.1
...
shadcn@2.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8c4027b6b | ||
|
|
699195ba77 | ||
|
|
9643db42cf | ||
|
|
dd71498762 | ||
|
|
ddf761e802 | ||
|
|
5f7957ab51 | ||
|
|
f07c7ad5d0 | ||
|
|
d5aa527f0b | ||
|
|
5ec990a474 | ||
|
|
cb742e9825 | ||
|
|
254198b4bf | ||
|
|
1081536246 | ||
|
|
811bb59a8f | ||
|
|
ea677cc74e |
8
.eslintignore
Normal file
8
.eslintignore
Normal file
@@ -0,0 +1,8 @@
|
||||
node_modules/
|
||||
target/
|
||||
.next/
|
||||
build/
|
||||
dist/
|
||||
|
||||
/templates/
|
||||
/fixtures/
|
||||
9
.github/workflows/code-check.yml
vendored
9
.github/workflows/code-check.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: 20
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
name: Install pnpm
|
||||
@@ -52,7 +52,7 @@ jobs:
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: 20
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
name: Install pnpm
|
||||
@@ -90,7 +90,7 @@ jobs:
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: 20
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
name: Install pnpm
|
||||
@@ -113,4 +113,7 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Build packages
|
||||
run: pnpm --filter=shadcn build
|
||||
|
||||
- run: pnpm typecheck
|
||||
|
||||
2
.github/workflows/prerelease-comment.yml
vendored
2
.github/workflows/prerelease-comment.yml
vendored
@@ -49,7 +49,7 @@ jobs:
|
||||
A new prerelease is available for testing:
|
||||
|
||||
```sh
|
||||
npx shadcn@${{ env.BETA_PACKAGE_VERSION }}
|
||||
pnpm dlx shadcn@${{ env.BETA_PACKAGE_VERSION }}
|
||||
```
|
||||
|
||||
- name: "Remove the autorelease label once published"
|
||||
|
||||
11
apps/www/.eslintrc.json
Normal file
11
apps/www/.eslintrc.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/eslintrc",
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["scripts/**/*.{ts,mts}"],
|
||||
"parserOptions": {
|
||||
"project": "tsconfig.scripts.json"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
134
apps/www/__registry__/default/block/sidebar-16/page.tsx
Normal file
134
apps/www/__registry__/default/block/sidebar-16/page.tsx
Normal file
@@ -0,0 +1,134 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import { Command, Sidebar } from "lucide-react"
|
||||
|
||||
import { AppSidebar } from "@/registry/default/block/sidebar-16/components/app-sidebar"
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbItem,
|
||||
BreadcrumbLink,
|
||||
BreadcrumbList,
|
||||
BreadcrumbPage,
|
||||
BreadcrumbSeparator,
|
||||
} from "@/registry/default/ui/breadcrumb"
|
||||
import { Button } from "@/registry/default/ui/button"
|
||||
import { Separator } from "@/registry/default/ui/separator"
|
||||
import {
|
||||
SidebarInset,
|
||||
SidebarProvider,
|
||||
SidebarTrigger,
|
||||
} from "@/registry/default/ui/sidebar"
|
||||
|
||||
export const iframeHeight = "800px"
|
||||
|
||||
export const description = "An inset sidebar with site header navigation."
|
||||
|
||||
const HEADER_HEIGHT = "4rem"
|
||||
|
||||
export default function Page() {
|
||||
const [open, setOpen] = React.useState(true)
|
||||
|
||||
return (
|
||||
<div
|
||||
style={
|
||||
{
|
||||
"--header-height": HEADER_HEIGHT,
|
||||
} as React.CSSProperties
|
||||
}
|
||||
>
|
||||
<header className="bg-sidebar sticky h-[--header-height] top-0 z-50 w-full border-b border-border/40 backdrop-blur">
|
||||
<div className="flex h-14 items-center px-4">
|
||||
<div className="mr-4 hidden md:flex">
|
||||
<Button
|
||||
className="hidden md:flex"
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={() => setOpen(!open)}
|
||||
>
|
||||
<Sidebar />
|
||||
</Button>
|
||||
<a href="#" className="mr-4 flex items-center gap-2 lg:mr-6">
|
||||
<div className="flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground">
|
||||
<Command className="size-4" />
|
||||
</div>
|
||||
</a>
|
||||
<nav className="flex items-center gap-4 text-sm xl:gap-6">
|
||||
<a
|
||||
href="#"
|
||||
className="transition-colors hover:text-foreground/80"
|
||||
>
|
||||
Docs
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
className="transition-colors hover:text-foreground/80"
|
||||
>
|
||||
Components
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
className="transition-colors hover:text-foreground/80"
|
||||
>
|
||||
Blocks
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
className="transition-colors hover:text-foreground/80"
|
||||
>
|
||||
Charts
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
className="transition-colors hover:text-foreground/80"
|
||||
>
|
||||
Themes
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
className="transition-colors hover:text-foreground/80"
|
||||
>
|
||||
Colors
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<SidebarProvider open={open} onOpenChange={setOpen}>
|
||||
<AppSidebar />
|
||||
|
||||
<SidebarInset>
|
||||
<header className=" flex shrink-0 items-center gap-2 border-b py-2">
|
||||
<div className="flex items-center gap-2 px-4 py-2">
|
||||
<div className="flex md:hidden items-center gap-2">
|
||||
<SidebarTrigger />
|
||||
<Separator orientation="vertical" className="mr-2 h-4" />
|
||||
</div>
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList>
|
||||
<BreadcrumbItem className="hidden md:block">
|
||||
<BreadcrumbLink href="#">
|
||||
Building Your Application
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator className="hidden md:block" />
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbPage>Data Fetching</BreadcrumbPage>
|
||||
</BreadcrumbItem>
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
</div>
|
||||
</header>
|
||||
<div className="flex flex-1 flex-col gap-4 p-4">
|
||||
<div className="grid auto-rows-min gap-4 md:grid-cols-3">
|
||||
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||
</div>
|
||||
<div className="min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min" />
|
||||
</div>
|
||||
</SidebarInset>
|
||||
</SidebarProvider>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
30
apps/www/__registry__/default/blocks/sidebar-16/page.tsx
Normal file
30
apps/www/__registry__/default/blocks/sidebar-16/page.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import { AppSidebar } from "@/registry/default/blocks/sidebar-16/components/app-sidebar"
|
||||
import { SiteHeader } from "@/registry/default/blocks/sidebar-16/components/site-header"
|
||||
import { SidebarInset, SidebarProvider } from "@/registry/default/ui/sidebar"
|
||||
|
||||
export const iframeHeight = "800px"
|
||||
|
||||
export const description = "A sidebar with a header and a search form."
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<div className="[--header-height:calc(theme(spacing.14))]">
|
||||
<SidebarProvider className="flex flex-col">
|
||||
<SiteHeader />
|
||||
<div className="flex flex-1">
|
||||
<AppSidebar />
|
||||
<SidebarInset>
|
||||
<div className="flex flex-1 flex-col gap-4 p-4">
|
||||
<div className="grid auto-rows-min gap-4 md:grid-cols-3">
|
||||
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||
</div>
|
||||
<div className="min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min" />
|
||||
</div>
|
||||
</SidebarInset>
|
||||
</div>
|
||||
</SidebarProvider>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1139,6 +1139,49 @@ export const Index: Record<string, any> = {
|
||||
source: "__registry__/new-york/blocks/sidebar-15/page.tsx",
|
||||
meta: undefined,
|
||||
},
|
||||
"sidebar-16": {
|
||||
name: "sidebar-16",
|
||||
description: "A sidebar with a sticky site header.",
|
||||
type: "registry:block",
|
||||
registryDependencies: ["sidebar","breadcrumb","separator","collapsible","dropdown-menu","avatar","button"],
|
||||
files: [{
|
||||
path: "registry/new-york/blocks/sidebar-16/page.tsx",
|
||||
type: "registry:page",
|
||||
target: "app/dashboard/page.tsx"
|
||||
},{
|
||||
path: "registry/new-york/blocks/sidebar-16/components/app-sidebar.tsx",
|
||||
type: "registry:component",
|
||||
target: ""
|
||||
},{
|
||||
path: "registry/new-york/blocks/sidebar-16/components/nav-main.tsx",
|
||||
type: "registry:component",
|
||||
target: ""
|
||||
},{
|
||||
path: "registry/new-york/blocks/sidebar-16/components/nav-projects.tsx",
|
||||
type: "registry:component",
|
||||
target: ""
|
||||
},{
|
||||
path: "registry/new-york/blocks/sidebar-16/components/nav-secondary.tsx",
|
||||
type: "registry:component",
|
||||
target: ""
|
||||
},{
|
||||
path: "registry/new-york/blocks/sidebar-16/components/nav-user.tsx",
|
||||
type: "registry:component",
|
||||
target: ""
|
||||
},{
|
||||
path: "registry/new-york/blocks/sidebar-16/components/search-form.tsx",
|
||||
type: "registry:component",
|
||||
target: ""
|
||||
},{
|
||||
path: "registry/new-york/blocks/sidebar-16/components/site-header.tsx",
|
||||
type: "registry:component",
|
||||
target: ""
|
||||
}],
|
||||
categories: ["sidebar","dashboard"],
|
||||
component: React.lazy(() => import("@/registry/new-york/blocks/sidebar-16/page.tsx")),
|
||||
source: "__registry__/new-york/blocks/sidebar-16/page.tsx",
|
||||
meta: undefined,
|
||||
},
|
||||
"login-01": {
|
||||
name: "login-01",
|
||||
description: "A simple login form.",
|
||||
@@ -6394,6 +6437,49 @@ export const Index: Record<string, any> = {
|
||||
source: "__registry__/default/blocks/sidebar-15/page.tsx",
|
||||
meta: undefined,
|
||||
},
|
||||
"sidebar-16": {
|
||||
name: "sidebar-16",
|
||||
description: "A sidebar with a sticky site header.",
|
||||
type: "registry:block",
|
||||
registryDependencies: ["sidebar","breadcrumb","separator","collapsible","dropdown-menu","avatar","button"],
|
||||
files: [{
|
||||
path: "registry/default/blocks/sidebar-16/page.tsx",
|
||||
type: "registry:page",
|
||||
target: "app/dashboard/page.tsx"
|
||||
},{
|
||||
path: "registry/default/blocks/sidebar-16/components/app-sidebar.tsx",
|
||||
type: "registry:component",
|
||||
target: ""
|
||||
},{
|
||||
path: "registry/default/blocks/sidebar-16/components/nav-main.tsx",
|
||||
type: "registry:component",
|
||||
target: ""
|
||||
},{
|
||||
path: "registry/default/blocks/sidebar-16/components/nav-projects.tsx",
|
||||
type: "registry:component",
|
||||
target: ""
|
||||
},{
|
||||
path: "registry/default/blocks/sidebar-16/components/nav-secondary.tsx",
|
||||
type: "registry:component",
|
||||
target: ""
|
||||
},{
|
||||
path: "registry/default/blocks/sidebar-16/components/nav-user.tsx",
|
||||
type: "registry:component",
|
||||
target: ""
|
||||
},{
|
||||
path: "registry/default/blocks/sidebar-16/components/search-form.tsx",
|
||||
type: "registry:component",
|
||||
target: ""
|
||||
},{
|
||||
path: "registry/default/blocks/sidebar-16/components/site-header.tsx",
|
||||
type: "registry:component",
|
||||
target: ""
|
||||
}],
|
||||
categories: ["sidebar","dashboard"],
|
||||
component: React.lazy(() => import("@/registry/default/blocks/sidebar-16/page.tsx")),
|
||||
source: "__registry__/default/blocks/sidebar-16/page.tsx",
|
||||
meta: undefined,
|
||||
},
|
||||
"login-01": {
|
||||
name: "login-01",
|
||||
description: "A simple login form.",
|
||||
|
||||
134
apps/www/__registry__/new-york/block/sidebar-16/page.tsx
Normal file
134
apps/www/__registry__/new-york/block/sidebar-16/page.tsx
Normal file
@@ -0,0 +1,134 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import { Command, Sidebar } from "lucide-react"
|
||||
|
||||
import { AppSidebar } from "@/registry/new-york/block/sidebar-16/components/app-sidebar"
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbItem,
|
||||
BreadcrumbLink,
|
||||
BreadcrumbList,
|
||||
BreadcrumbPage,
|
||||
BreadcrumbSeparator,
|
||||
} from "@/registry/new-york/ui/breadcrumb"
|
||||
import { Button } from "@/registry/new-york/ui/button"
|
||||
import { Separator } from "@/registry/new-york/ui/separator"
|
||||
import {
|
||||
SidebarInset,
|
||||
SidebarProvider,
|
||||
SidebarTrigger,
|
||||
} from "@/registry/new-york/ui/sidebar"
|
||||
|
||||
export const iframeHeight = "800px"
|
||||
|
||||
export const description = "An inset sidebar with site header navigation."
|
||||
|
||||
const HEADER_HEIGHT = "4rem"
|
||||
|
||||
export default function Page() {
|
||||
const [open, setOpen] = React.useState(true)
|
||||
|
||||
return (
|
||||
<div
|
||||
style={
|
||||
{
|
||||
"--header-height": HEADER_HEIGHT,
|
||||
} as React.CSSProperties
|
||||
}
|
||||
>
|
||||
<header className="bg-sidebar sticky h-[--header-height] top-0 z-50 w-full border-b border-border/40 backdrop-blur">
|
||||
<div className="flex h-14 items-center px-4">
|
||||
<div className="mr-4 hidden md:flex">
|
||||
<Button
|
||||
className="hidden md:flex"
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={() => setOpen(!open)}
|
||||
>
|
||||
<Sidebar />
|
||||
</Button>
|
||||
<a href="#" className="mr-4 flex items-center gap-2 lg:mr-6">
|
||||
<div className="flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground">
|
||||
<Command className="size-4" />
|
||||
</div>
|
||||
</a>
|
||||
<nav className="flex items-center gap-4 text-sm xl:gap-6">
|
||||
<a
|
||||
href="#"
|
||||
className="transition-colors hover:text-foreground/80"
|
||||
>
|
||||
Docs
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
className="transition-colors hover:text-foreground/80"
|
||||
>
|
||||
Components
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
className="transition-colors hover:text-foreground/80"
|
||||
>
|
||||
Blocks
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
className="transition-colors hover:text-foreground/80"
|
||||
>
|
||||
Charts
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
className="transition-colors hover:text-foreground/80"
|
||||
>
|
||||
Themes
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
className="transition-colors hover:text-foreground/80"
|
||||
>
|
||||
Colors
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<SidebarProvider open={open} onOpenChange={setOpen}>
|
||||
<AppSidebar />
|
||||
|
||||
<SidebarInset>
|
||||
<header className=" flex shrink-0 items-center gap-2 border-b py-2">
|
||||
<div className="flex items-center gap-2 px-4 py-2">
|
||||
<div className="flex md:hidden items-center gap-2">
|
||||
<SidebarTrigger />
|
||||
<Separator orientation="vertical" className="mr-2 h-4" />
|
||||
</div>
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList>
|
||||
<BreadcrumbItem className="hidden md:block">
|
||||
<BreadcrumbLink href="#">
|
||||
Building Your Application
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator className="hidden md:block" />
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbPage>Data Fetching</BreadcrumbPage>
|
||||
</BreadcrumbItem>
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
</div>
|
||||
</header>
|
||||
<div className="flex flex-1 flex-col gap-4 p-4">
|
||||
<div className="grid auto-rows-min gap-4 md:grid-cols-3">
|
||||
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||
</div>
|
||||
<div className="min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min" />
|
||||
</div>
|
||||
</SidebarInset>
|
||||
</SidebarProvider>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
30
apps/www/__registry__/new-york/blocks/sidebar-16/page.tsx
Normal file
30
apps/www/__registry__/new-york/blocks/sidebar-16/page.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import { AppSidebar } from "@/registry/new-york/blocks/sidebar-16/components/app-sidebar"
|
||||
import { SiteHeader } from "@/registry/new-york/blocks/sidebar-16/components/site-header"
|
||||
import { SidebarInset, SidebarProvider } from "@/registry/new-york/ui/sidebar"
|
||||
|
||||
export const iframeHeight = "800px"
|
||||
|
||||
export const description = "A sidebar with a header and a search form."
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<div className="[--header-height:calc(theme(spacing.14))]">
|
||||
<SidebarProvider className="flex flex-col">
|
||||
<SiteHeader />
|
||||
<div className="flex flex-1">
|
||||
<AppSidebar />
|
||||
<SidebarInset>
|
||||
<div className="flex flex-1 flex-col gap-4 p-4">
|
||||
<div className="grid auto-rows-min gap-4 md:grid-cols-3">
|
||||
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||
</div>
|
||||
<div className="min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min" />
|
||||
</div>
|
||||
</SidebarInset>
|
||||
</div>
|
||||
</SidebarProvider>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -34,6 +34,9 @@ export async function editInV0({
|
||||
// Remove v0 prefix from the name
|
||||
registryItem.name = registryItem.name.replace(/^v0-/, "")
|
||||
|
||||
const projectName = capitalCase(name.replace(/\d+/g, ""))
|
||||
registryItem.description = registryItem.description || projectName
|
||||
|
||||
// Replace `@/registry/new-york/` in files.
|
||||
registryItem.files = registryItem.files?.map((file) => {
|
||||
if (file.content?.includes("@/registry/new-york/ui")) {
|
||||
@@ -53,7 +56,7 @@ export async function editInV0({
|
||||
url,
|
||||
},
|
||||
meta: {
|
||||
project: capitalCase(name.replace(/\d+/g, "")),
|
||||
project: projectName,
|
||||
file: `${name}.tsx`,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
import { Button } from "@/registry/new-york/ui/button"
|
||||
|
||||
import "@/styles/mdx.css"
|
||||
import Link from "next/link"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Building Blocks.",
|
||||
@@ -37,12 +38,7 @@ export default function BlocksLayout({
|
||||
<a href="#blocks">Browse Blocks</a>
|
||||
</Button>
|
||||
<Button asChild variant="ghost" size="sm">
|
||||
<a
|
||||
href="https://github.com/shadcn-ui/ui/discussions/new?category=blocks-request"
|
||||
target="_blank"
|
||||
>
|
||||
Request a block
|
||||
</a>
|
||||
<Link href="/docs/blocks">Add a block</Link>
|
||||
</Button>
|
||||
</PageActions>
|
||||
</PageHeader>
|
||||
|
||||
@@ -4,11 +4,11 @@ import { ArrowRight } from "lucide-react"
|
||||
export function Announcement() {
|
||||
return (
|
||||
<Link
|
||||
href="/docs/components/sidebar"
|
||||
href="/docs/blocks"
|
||||
className="group mb-2 inline-flex items-center px-0.5 text-sm font-medium"
|
||||
>
|
||||
<span className="underline-offset-4 group-hover:underline">
|
||||
New sidebar component
|
||||
Blocks are open for contributions
|
||||
</span>
|
||||
<ArrowRight className="ml-1 h-4 w-4" />
|
||||
</Link>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as React from "react"
|
||||
import { registryItemFileSchema } from "shadcn/registry"
|
||||
import { z } from "zod"
|
||||
|
||||
import { highlightCode } from "@/lib/highlight-code"
|
||||
@@ -7,7 +8,6 @@ import {
|
||||
getRegistryItem,
|
||||
} from "@/lib/registry"
|
||||
import { BlockViewer } from "@/components/block-viewer"
|
||||
import { registryItemFileSchema } from "@/registry/schema"
|
||||
|
||||
export async function BlockDisplay({ name }: { name: string }) {
|
||||
const item = await getCachedRegistryItem(name)
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
Terminal,
|
||||
} from "lucide-react"
|
||||
import { ImperativePanelHandle } from "react-resizable-panels"
|
||||
import { registryItemFileSchema, registryItemSchema } from "shadcn/registry"
|
||||
import { z } from "zod"
|
||||
|
||||
import { trackEvent } from "@/lib/events"
|
||||
@@ -51,7 +52,6 @@ import {
|
||||
ToggleGroupItem,
|
||||
} from "@/registry/new-york/ui/toggle-group"
|
||||
import { Style } from "@/registry/registry-styles"
|
||||
import { registryItemFileSchema, registryItemSchema } from "@/registry/schema"
|
||||
|
||||
type BlockViewerContext = {
|
||||
item: z.infer<typeof registryItemSchema>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import * as React from "react"
|
||||
import { registryItemSchema } from "shadcn/registry"
|
||||
import { z } from "zod"
|
||||
|
||||
import { highlightCode } from "@/lib/highlight-code"
|
||||
import { getRegistryItem } from "@/lib/registry"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { ChartToolbar } from "@/components/chart-toolbar"
|
||||
import { registryItemSchema } from "@/registry/schema"
|
||||
|
||||
export type Chart = z.infer<typeof registryItemSchema> & {
|
||||
highlightedCode: string
|
||||
|
||||
@@ -17,7 +17,12 @@ export function DocsNav({ config }: { config: DocsConfig }) {
|
||||
{items.map((item, index) => (
|
||||
<div key={index} className="flex flex-col gap-1">
|
||||
<h4 className="rounded-md px-2 py-1 text-sm font-semibold">
|
||||
{item.title}
|
||||
{item.title}{" "}
|
||||
{item.label && (
|
||||
<span className="ml-2 rounded-md bg-[#adfa1d] px-1.5 py-0.5 text-xs font-normal leading-none text-[#000000] no-underline group-hover:no-underline">
|
||||
{item.label}
|
||||
</span>
|
||||
)}
|
||||
</h4>
|
||||
{item?.items?.length && (
|
||||
<DocsNavItems items={item.items} pathname={pathname} />
|
||||
|
||||
@@ -71,6 +71,12 @@ export const docsConfig: DocsConfig = {
|
||||
href: "/docs/cli",
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
title: "Monorepo",
|
||||
href: "/docs/monorepo",
|
||||
items: [],
|
||||
label: "New",
|
||||
},
|
||||
{
|
||||
title: "Next.js 15 + React 19",
|
||||
href: "/docs/react-19",
|
||||
@@ -86,6 +92,12 @@ export const docsConfig: DocsConfig = {
|
||||
href: "/docs/v0",
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
title: "Blocks",
|
||||
href: "/docs/blocks",
|
||||
items: [],
|
||||
label: "New",
|
||||
},
|
||||
{
|
||||
title: "Figma",
|
||||
href: "/docs/figma",
|
||||
@@ -141,12 +153,6 @@ export const docsConfig: DocsConfig = {
|
||||
{
|
||||
title: "Components",
|
||||
items: [
|
||||
{
|
||||
title: "Sidebar",
|
||||
href: "/docs/components/sidebar",
|
||||
items: [],
|
||||
label: "New",
|
||||
},
|
||||
{
|
||||
title: "Accordion",
|
||||
href: "/docs/components/accordion",
|
||||
@@ -337,6 +343,11 @@ export const docsConfig: DocsConfig = {
|
||||
href: "/docs/components/sheet",
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
title: "Sidebar",
|
||||
href: "/docs/components/sidebar",
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
title: "Skeleton",
|
||||
href: "/docs/components/skeleton",
|
||||
@@ -394,6 +405,42 @@ export const docsConfig: DocsConfig = {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Registry",
|
||||
label: "New",
|
||||
items: [
|
||||
{
|
||||
title: "Introduction",
|
||||
href: "/docs/registry",
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
title: "Getting Started",
|
||||
href: "/docs/registry/getting-started",
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
title: "Open in v0",
|
||||
href: "/docs/registry/open-in-v0",
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
title: "FAQ",
|
||||
href: "/docs/registry/faq",
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
title: "registry.json",
|
||||
href: "/docs/registry/registry-json",
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
title: "registry-item.json",
|
||||
href: "/docs/registry/registry-item-json",
|
||||
items: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
chartsNav: [
|
||||
{
|
||||
|
||||
238
apps/www/content/docs/blocks.mdx
Normal file
238
apps/www/content/docs/blocks.mdx
Normal file
@@ -0,0 +1,238 @@
|
||||
---
|
||||
title: Add a block
|
||||
description: Contribute components to the blocks library.
|
||||
---
|
||||
|
||||
We are inviting the community to contribute to the [blocks library](/blocks). Share your components and blocks with other developers and help build a library of high-quality, reusable components.
|
||||
|
||||
We'd love to see all types of blocks: applications, marketing, products, and more.
|
||||
|
||||
## Setup your workspace
|
||||
|
||||
<Steps>
|
||||
|
||||
### Fork the repository
|
||||
|
||||
```bash
|
||||
git clone https://github.com/shadcn-ui/ui.git
|
||||
```
|
||||
|
||||
### Create a new branch
|
||||
|
||||
```bash
|
||||
git checkout -b username/my-new-block
|
||||
```
|
||||
|
||||
### Install dependencies
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
```
|
||||
|
||||
### Start the dev server
|
||||
|
||||
```bash
|
||||
pnpm www:dev
|
||||
```
|
||||
|
||||
</Steps>
|
||||
|
||||
## Add a block
|
||||
|
||||
A block can be a single component (eg. a variation of a ui component) or a complex component (eg. a dashboard) with multiple components, hooks, and utils.
|
||||
|
||||
<Steps>
|
||||
|
||||
### Create a new block
|
||||
|
||||
Create a new folder in the `apps/www/registry/new-york/blocks` directory. Make sure the folder is named in kebab-case and under `new-york`.
|
||||
|
||||
```txt
|
||||
apps
|
||||
└── www
|
||||
└── registry
|
||||
└── new-york
|
||||
└── blocks
|
||||
└── dashboard-01
|
||||
```
|
||||
|
||||
<Callout className="mt-6">
|
||||
|
||||
**Note:** The build script will take care of building the block for the `default` style.
|
||||
|
||||
</Callout>
|
||||
|
||||
### Add your block files
|
||||
|
||||
Add your files to the block folder. Here is an example of a block with a page, components, hooks, and utils.
|
||||
|
||||
```txt
|
||||
dashboard-01
|
||||
└── page.tsx
|
||||
└── components
|
||||
└── hello-world.tsx
|
||||
└── example-card.tsx
|
||||
└── hooks
|
||||
└── use-hello-world.ts
|
||||
└── lib
|
||||
└── format-date.ts
|
||||
```
|
||||
|
||||
<Callout className="mt-6">
|
||||
|
||||
**Note:** You can start with one file and add more files later.
|
||||
|
||||
</Callout>
|
||||
|
||||
</Steps>
|
||||
|
||||
## Add your block to the registry
|
||||
|
||||
<Steps>
|
||||
|
||||
### Add your block definition to `registry-blocks.tsx`
|
||||
|
||||
To add your block to the registry, you need to add your block definition to `registry-blocks.tsx`.
|
||||
|
||||
This follows the registry schema at [https://ui.shadcn.com/schema/registry-item.json](https://ui.shadcn.com/schema/registry-item.json).
|
||||
|
||||
```tsx title="apps/www/registry/registry-blocks.tsx"
|
||||
export const blocks = [
|
||||
// ...
|
||||
{
|
||||
name: "dashboard-01",
|
||||
author: "shadcn (https://ui.shadcn.com)",
|
||||
title: "Dashboard",
|
||||
description: "A simple dashboard with a hello world component.",
|
||||
type: "registry:block",
|
||||
registryDependencies: ["input", "button", "card"],
|
||||
dependencies: ["zod"],
|
||||
files: [
|
||||
{
|
||||
path: "blocks/dashboard-01/page.tsx",
|
||||
type: "registry:page",
|
||||
target: "app/dashboard/page.tsx",
|
||||
},
|
||||
{
|
||||
path: "blocks/dashboard-01/components/hello-world.tsx",
|
||||
type: "registry:component",
|
||||
},
|
||||
{
|
||||
path: "blocks/dashboard-01/components/example-card.tsx",
|
||||
type: "registry:component",
|
||||
},
|
||||
{
|
||||
path: "blocks/dashboard-01/hooks/use-hello-world.ts",
|
||||
type: "registry:hook",
|
||||
},
|
||||
{
|
||||
path: "blocks/dashboard-01/lib/format-date.ts",
|
||||
type: "registry:lib",
|
||||
},
|
||||
],
|
||||
categories: ["dashboard"],
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
Make sure you add a name, description, type, registryDependencies, dependencies, files, and categories. We'll go over each of these in more detail in the schema docs (coming soon).
|
||||
|
||||
### Run the build script
|
||||
|
||||
```bash
|
||||
pnpm registry:build
|
||||
```
|
||||
|
||||
<Callout className="mt-6">
|
||||
|
||||
**Note:** you do not need to run this script for every change. You only need to run it when you update the block definition.
|
||||
|
||||
</Callout>
|
||||
|
||||
### View your block
|
||||
|
||||
Once the build script is finished, you can view your block at `http://localhost:3333/blocks/[CATEGORY]` or a full screen preview at `http://localhost:3333/view/styles/new-york/dashboard-01`.
|
||||
|
||||
<Image
|
||||
src="/images/block-preview-light.png"
|
||||
width="1432"
|
||||
height="960"
|
||||
alt="Block preview"
|
||||
className="border dark:hidden shadow-sm rounded-lg overflow-hidden mt-6 w-full"
|
||||
/>
|
||||
<Image
|
||||
src="/images/block-preview-dark.png"
|
||||
width="1432"
|
||||
height="960"
|
||||
alt="Block preview"
|
||||
className="border hidden dark:block shadow-sm rounded-lg overflow-hidden mt-6 w-full"
|
||||
/>
|
||||
|
||||
### Build your block
|
||||
|
||||
You can now build your block by editing the files in the block folder and viewing the changes in the browser.
|
||||
|
||||
If you add more files, make sure to add them to the `files` array in the block definition.
|
||||
|
||||
</Steps>
|
||||
|
||||
## Publish your block
|
||||
|
||||
Once you're ready to publish your block, you can submit a pull request to the main repository.
|
||||
|
||||
<Steps>
|
||||
|
||||
### Run the build script
|
||||
|
||||
```bash
|
||||
pnpm registry:build
|
||||
```
|
||||
|
||||
### Capture a screenshot
|
||||
|
||||
```bash
|
||||
pnpm registry:capture
|
||||
```
|
||||
|
||||
<Callout className="mt-6">
|
||||
|
||||
**Note:** If you've run the capture script before, you might need to delete the existing screenshots (both light and dark) at `apps/www/public/r/styles/new-york` and run the script again.
|
||||
|
||||
</Callout>
|
||||
|
||||
### Submit a pull request
|
||||
|
||||
Commit your changes and submit a pull request to the main repository.
|
||||
|
||||
Your block will be reviewed and merged. Once merged it will be published to the website and available to be installed via the CLI.
|
||||
|
||||
</Steps>
|
||||
|
||||
## Categories
|
||||
|
||||
The `categories` property is used to organize your block in the registry.
|
||||
|
||||
### Add a category
|
||||
|
||||
If you need to add a new category, you can do so by adding it to the `registryCategories` array in `apps/www/registry/registry-categories.ts`.
|
||||
|
||||
```tsx title="apps/www/registry/registry-categories.ts"
|
||||
export const registryCategories = [
|
||||
// ...
|
||||
{
|
||||
name: "Input",
|
||||
slug: "input",
|
||||
hidden: false,
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
## Guidelines
|
||||
|
||||
Here are some guidelines to follow when contributing to the blocks library.
|
||||
|
||||
- The following properties are required for the block definition: `name`, `description`, `type`, `files`, and `categories`.
|
||||
- Make sure to list all registry dependencies in `registryDependencies`. A registry dependency is the name of the component in the registry eg. `input`, `button`, `card`, etc.
|
||||
- Make sure to list all dependencies in `dependencies`. A dependency is the name of the package in the registry eg. `zod`, `sonner`, etc.
|
||||
- If your block has a page (optional), it should be the first entry in the `files` array and it should have a `target` property. This helps the CLI place the page in the correct location for file-based routing.
|
||||
- **Imports should always use the `@/registry` path.** eg. `import { Input } from "@/registry/new-york/input"`
|
||||
@@ -90,16 +90,33 @@ Options:
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
## Monorepo
|
||||
## build
|
||||
|
||||
In a monorepo, you can specify the path to your workspace with the `-c` or `--cwd` option.
|
||||
Use the `build` command to generate the registry JSON files.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest init -c ./apps/www
|
||||
npx shadcn@latest build
|
||||
```
|
||||
|
||||
or
|
||||
This command reads the `registry.json` file and generates the registry JSON files in the `public/r` directory.
|
||||
|
||||
```txt
|
||||
Usage: shadcn build [options] [registry]
|
||||
|
||||
build components for a shadcn registry
|
||||
|
||||
Arguments:
|
||||
registry path to registry.json file (default: "./registry.json")
|
||||
|
||||
Options:
|
||||
-o, --output <path> destination directory for json files (default: "./public/r")
|
||||
-c, --cwd <cwd> the working directory. defaults to the current directory. (default:
|
||||
"/Users/shadcn/Code/shadcn/ui/packages/shadcn")
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
To customize the output directory, use the `--output` option.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add alert-dialog -c ./apps/www
|
||||
npx shadcn@latest build --output ./public/registry
|
||||
```
|
||||
|
||||
175
apps/www/content/docs/monorepo.mdx
Normal file
175
apps/www/content/docs/monorepo.mdx
Normal file
@@ -0,0 +1,175 @@
|
||||
---
|
||||
title: Monorepo
|
||||
description: Using shadcn/ui components and CLI in a monorepo.
|
||||
---
|
||||
|
||||
<Callout>
|
||||
**Note:** We're releasing monorepo support in the CLI as __experimental__.
|
||||
Help us improve it by testing it out and sending feedback. If you have any
|
||||
questions, please [reach out to
|
||||
us](https://github.com/shadcn-ui/ui/discussions).
|
||||
</Callout>
|
||||
|
||||
Until now, using shadcn/ui in a monorepo was a bit of a pain. You could add
|
||||
components using the CLI, but you had to manage where the components
|
||||
were installed and manually fix import paths.
|
||||
|
||||
With the new monorepo support in the CLI, we've made it a lot easier to use
|
||||
shadcn/ui in a monorepo.
|
||||
|
||||
The CLI now understands the monorepo structure and will install the components,
|
||||
dependencies and registry dependencies to the correct paths and handle imports
|
||||
for you.
|
||||
|
||||
## Getting started
|
||||
|
||||
<Steps>
|
||||
|
||||
### Create a new monorepo project
|
||||
|
||||
To create a new monorepo project, run the `init` command. 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.
|
||||
|
||||
### 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"
|
||||
```
|
||||
|
||||
</Steps>
|
||||
|
||||
## File Structure
|
||||
|
||||
When you create a new monorepo project, the CLI will create the following file structure:
|
||||
|
||||
```txt
|
||||
apps
|
||||
└── web # Your app goes here.
|
||||
├── app
|
||||
│ └── page.tsx
|
||||
├── components
|
||||
│ └── login-form.tsx
|
||||
├── components.json
|
||||
└── package.json
|
||||
packages
|
||||
└── ui # Your components and dependencies are installed here.
|
||||
├── src
|
||||
│ ├── components
|
||||
│ │ └── button.tsx
|
||||
│ ├── hooks
|
||||
│ ├── lib
|
||||
│ │ └── utils.ts
|
||||
│ └── styles
|
||||
│ └── globals.css
|
||||
├── components.json
|
||||
└── package.json
|
||||
package.json
|
||||
turbo.json
|
||||
```
|
||||
|
||||
## Requirements
|
||||
|
||||
1. Every workspace must have a `components.json` file. A `package.json` file tells npm how to install the dependencies. A `components.json` file tells the CLI how and where to install components.
|
||||
|
||||
2. The `components.json` file must properly define aliases for the workspace. This tells the CLI how to import components, hooks, utilities, etc.
|
||||
|
||||
```json title="apps/web/components.json"
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema.json",
|
||||
"style": "new-york",
|
||||
"rsc": true,
|
||||
"tsx": true,
|
||||
"tailwind": {
|
||||
"config": "../../packages/ui/tailwind.config.ts",
|
||||
"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 title="packages/ui/components.json"
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema.json",
|
||||
"style": "new-york",
|
||||
"rsc": true,
|
||||
"tsx": true,
|
||||
"tailwind": {
|
||||
"config": "tailwind.config.ts",
|
||||
"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.
|
||||
|
||||
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.
|
||||
|
||||
## Help us improve monorepo support
|
||||
|
||||
We're releasing monorepo support in the CLI as **experimental**. Help us improve it by testing it out and sending feedback.
|
||||
|
||||
If you have any questions, please reach out to us on [GitHub Discussions](https://github.com/shadcn-ui/ui/discussions).
|
||||
125
apps/www/content/docs/registry/faq.mdx
Normal file
125
apps/www/content/docs/registry/faq.mdx
Normal file
@@ -0,0 +1,125 @@
|
||||
---
|
||||
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/hello-world/page.tsx",
|
||||
"type": "registry:page",
|
||||
"target": "app/hello/page.tsx"
|
||||
},
|
||||
{
|
||||
"path": "registry/hello-world/components/hello-world.tsx",
|
||||
"type": "registry:component"
|
||||
},
|
||||
{
|
||||
"path": "registry/hello-world/components/formatted-message.tsx",
|
||||
"type": "registry:component"
|
||||
},
|
||||
{
|
||||
"path": "registry/hello-world/hooks/use-hello.ts",
|
||||
"type": "registry:hook"
|
||||
},
|
||||
{
|
||||
"path": "registry/hello-world/lib/format-date.ts",
|
||||
"type": "registry:utils"
|
||||
},
|
||||
{
|
||||
"path": "registry/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` and `tailwind.config.theme.extend.colors`.
|
||||
|
||||
```json showLineNumbers {10-19} {24-29}
|
||||
{
|
||||
"$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%"
|
||||
}
|
||||
},
|
||||
"tailwind": {
|
||||
"config": {
|
||||
"theme": {
|
||||
"extend": {
|
||||
"colors": {
|
||||
"brand": {
|
||||
"DEFAULT": "hsl(var(--brand-background))",
|
||||
"accent": "hsl(var(--brand-accent))"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The CLI will update the project CSS file and tailwind.config.js 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 a Tailwind animation?
|
||||
|
||||
To add a new animation you add it to `tailwind.config.theme.extend.animation` and `tailwind.config.theme.extend.keyframes`.
|
||||
|
||||
```json showLineNumbers {14-22}
|
||||
{
|
||||
"$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": [
|
||||
// ...
|
||||
],
|
||||
"tailwind": {
|
||||
"config": {
|
||||
"theme": {
|
||||
"extend": {
|
||||
"keyframes": {
|
||||
"wiggle": {
|
||||
"0%, 100%": { "transform": "rotate(-3deg)" },
|
||||
"50%": { "transform": "rotate(3deg)" }
|
||||
}
|
||||
},
|
||||
"animation": {
|
||||
"wiggle": "wiggle 1s ease-in-out infinite"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
186
apps/www/content/docs/registry/getting-started.mdx
Normal file
186
apps/www/content/docs/registry/getting-started.mdx
Normal file
@@ -0,0 +1,186 @@
|
||||
---
|
||||
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).
|
||||
|
||||
<Steps>
|
||||
|
||||
### 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).
|
||||
|
||||
</Steps>
|
||||
|
||||
## Add a registry item
|
||||
|
||||
<Steps>
|
||||
|
||||
### Create your component
|
||||
|
||||
Add your first component. Here's an example of a simple `<HelloWorld />` component:
|
||||
|
||||
```tsx title="registry/hello-world/hello-world.tsx" showLineNumbers
|
||||
import { Button } from "@/components/ui/button"
|
||||
|
||||
export function HelloWorld() {
|
||||
return <Button>Hello World</Button>
|
||||
}
|
||||
```
|
||||
|
||||
<Callout className="mt-6">
|
||||
**Note:** This example places the component in the `registry` directory. You
|
||||
can place it anywhere in your project as long as you set the correct path in
|
||||
the `registry.json` file.
|
||||
</Callout>
|
||||
|
||||
```txt
|
||||
registry
|
||||
└── hello-world
|
||||
└── hello-world.tsx
|
||||
```
|
||||
|
||||
<Callout className="mt-6 [&_[data-rehype-pretty-code-title]]:pt-1 [&_pre]:mb-0">
|
||||
**Important:** If you're placing your component in a custom directory, make
|
||||
sure it is configured in your `tailwind.config.ts` file.
|
||||
|
||||
```ts showLineNumbers
|
||||
// tailwind.config.ts
|
||||
export default {
|
||||
content: ["./registry/**/*.{js,ts,jsx,tsx}"],
|
||||
}
|
||||
```
|
||||
|
||||
</Callout>
|
||||
|
||||
### 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/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).
|
||||
|
||||
</Steps>
|
||||
|
||||
## Build your registry
|
||||
|
||||
<Steps>
|
||||
|
||||
### 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
|
||||
```
|
||||
|
||||
<Callout className="mt-6">
|
||||
**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.
|
||||
|
||||
</Callout>
|
||||
|
||||
</Steps>
|
||||
|
||||
## 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.
|
||||
|
||||
## Guidelines
|
||||
|
||||
Here are some guidelines to follow when building components for a registry.
|
||||
|
||||
- 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/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
|
||||
```
|
||||
40
apps/www/content/docs/registry/index.mdx
Normal file
40
apps/www/content/docs/registry/index.mdx
Normal file
@@ -0,0 +1,40 @@
|
||||
---
|
||||
title: Registry
|
||||
description: Run your own component registry.
|
||||
---
|
||||
|
||||
<Callout>
|
||||
**Note:** This feature is currently experimental. Help us improve it by
|
||||
testing it out and sending feedback. If you have any questions, please [reach
|
||||
out to us](https://github.com/shadcn-ui/ui/discussions).
|
||||
</Callout>
|
||||
|
||||
You can use the `shadcn` CLI to run your own component registry. Running your own registry allows you to distribute your custom components, hooks, pages, and other files to any React project.
|
||||
|
||||
<figure className="flex flex-col gap-4">
|
||||
<Image
|
||||
src="/images/registry-light.png"
|
||||
width="1432"
|
||||
height="960"
|
||||
alt="Registry"
|
||||
className="border dark:hidden shadow-sm rounded-lg overflow-hidden mt-6 w-full"
|
||||
/>
|
||||
<Image
|
||||
src="/images/registry-dark.png"
|
||||
width="1432"
|
||||
height="960"
|
||||
alt="Registry"
|
||||
className="border hidden dark:block shadow-sm rounded-lg overflow-hidden mt-6 w-full"
|
||||
/>
|
||||
<figcaption className="text-center text-sm text-gray-500">
|
||||
Distribute code to any React project.
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
Registry items are automatically compatible with the `shadcn` CLI and `Open in v0`.
|
||||
|
||||
## 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.
|
||||
59
apps/www/content/docs/registry/open-in-v0.mdx
Normal file
59
apps/www/content/docs/registry/open-in-v0.mdx
Normal file
@@ -0,0 +1,59 @@
|
||||
---
|
||||
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://example.com/r/hello-world.json](https://v0.dev/chat/api/open?url=https://example.com/r/hello-world.json)
|
||||
|
||||
## Button
|
||||
|
||||
You can copy and paste the following code to add a `Open in v0` button to your site.
|
||||
|
||||
```jsx
|
||||
import { Button } from "@/components/ui/button"
|
||||
|
||||
export function OpenInV0Button({ url }: { url: string }) {
|
||||
return (
|
||||
<Button
|
||||
aria-label="Open in v0"
|
||||
className="h-8 gap-1 rounded-[6px] bg-black px-3 text-xs text-white hover:bg-black hover:text-white dark:bg-white dark:text-black"
|
||||
asChild
|
||||
>
|
||||
<a
|
||||
href={`https://v0.dev/chat/api/open?url=${url}`}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
Open in{" "}
|
||||
<svg
|
||||
viewBox="0 0 40 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="h-5 w-5 text-current"
|
||||
>
|
||||
<path
|
||||
d="M23.3919 0H32.9188C36.7819 0 39.9136 3.13165 39.9136 6.99475V16.0805H36.0006V6.99475C36.0006 6.90167 35.9969 6.80925 35.9898 6.71766L26.4628 16.079C26.4949 16.08 26.5272 16.0805 26.5595 16.0805H36.0006V19.7762H26.5595C22.6964 19.7762 19.4788 16.6139 19.4788 12.7508V3.68923H23.3919V12.7508C23.3919 12.9253 23.4054 13.0977 23.4316 13.2668L33.1682 3.6995C33.0861 3.6927 33.003 3.68923 32.9188 3.68923H23.3919V0Z"
|
||||
fill="currentColor"
|
||||
></path>
|
||||
<path
|
||||
d="M13.7688 19.0956L0 3.68759H5.53933L13.6231 12.7337V3.68759H17.7535V17.5746C17.7535 19.6705 15.1654 20.6584 13.7688 19.0956Z"
|
||||
fill="currentColor"
|
||||
></path>
|
||||
</svg>
|
||||
</a>
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```jsx
|
||||
<OpenInV0Button url="https://example.com/r/hello-world.json" />
|
||||
```
|
||||
|
||||
## Known issues
|
||||
|
||||
- The `Open in v0` button does not support `cssVars` and `tailwind` properties.
|
||||
272
apps/www/content/docs/registry/registry-item-json.mdx
Normal file
272
apps/www/content/docs/registry/registry-item-json.mdx
Normal file
@@ -0,0 +1,272 @@
|
||||
---
|
||||
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/hello-world/hello-world.tsx",
|
||||
"type": "registry:component"
|
||||
},
|
||||
{
|
||||
"path": "registry/hello-world/use-hello-world.ts",
|
||||
"type": "registry:hook"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 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` property is used to specify the name of your registry item.
|
||||
|
||||
```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.
|
||||
|
||||
```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. |
|
||||
|
||||
### 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 <john@doe.com>"
|
||||
}
|
||||
```
|
||||
|
||||
### 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.
|
||||
|
||||
- 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/hello-world/page.tsx",
|
||||
"type": "registry:page",
|
||||
"target": "app/hello/page.tsx"
|
||||
},
|
||||
{
|
||||
"path": "registry/hello-world/hello-world.tsx",
|
||||
"type": "registry:component"
|
||||
},
|
||||
{
|
||||
"path": "registry/hello-world/use-hello-world.ts",
|
||||
"type": "registry:hook"
|
||||
},
|
||||
{
|
||||
"path": "registry/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
|
||||
|
||||
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": {
|
||||
"light": {
|
||||
"brand": "20 14.3% 4.1%",
|
||||
"radius": "0.5rem"
|
||||
},
|
||||
"dark": {
|
||||
"brand": "20 14.3% 4.1%"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<Callout>
|
||||
**Note:** When adding colors, make sure to also add them to the
|
||||
`tailwind.config.theme.extend.colors` property.
|
||||
</Callout>
|
||||
|
||||
### 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" }
|
||||
}
|
||||
```
|
||||
87
apps/www/content/docs/registry/registry-json.mdx
Normal file
87
apps/www/content/docs/registry/registry-json.mdx
Normal file
@@ -0,0 +1,87 @@
|
||||
---
|
||||
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/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/hello-world/hello-world.tsx",
|
||||
"type": "registry:component"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
See the [registry-item schema documentation](/docs/registry/registry-item) for more information.
|
||||
@@ -1,9 +1,9 @@
|
||||
"use server"
|
||||
|
||||
import { registryItemSchema } from "shadcn/registry"
|
||||
import { z } from "zod"
|
||||
|
||||
import { Style } from "@/registry/registry-styles"
|
||||
import { registryItemSchema } from "@/registry/schema"
|
||||
|
||||
export async function getAllBlockIds(
|
||||
types: z.infer<typeof registryItemSchema>["type"][] = [
|
||||
|
||||
@@ -11,6 +11,7 @@ const colorSchema = z.object({
|
||||
rgb: z.string(),
|
||||
hsl: z.string(),
|
||||
foreground: z.string(),
|
||||
oklch: z.string(),
|
||||
})
|
||||
|
||||
const colorPaletteSchema = z.object({
|
||||
@@ -26,6 +27,7 @@ export function getColorFormat(color: Color) {
|
||||
hex: color.hex,
|
||||
rgb: color.rgb,
|
||||
hsl: color.hsl,
|
||||
oklch: color.oklch,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +59,10 @@ export function getColors() {
|
||||
/^hsl\(([\d.]+),([\d.]+%),([\d.]+%)\)$/,
|
||||
"$1 $2 $3"
|
||||
),
|
||||
oklch: color.oklch.replace(
|
||||
/^oklch\(([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\)$/,
|
||||
"$1 $2 $3"
|
||||
),
|
||||
foreground: getForegroundFromBackground(rgb),
|
||||
}
|
||||
}),
|
||||
|
||||
@@ -2,11 +2,11 @@ import { promises as fs } from "fs"
|
||||
import { tmpdir } from "os"
|
||||
import path from "path"
|
||||
import { Index } from "@/__registry__"
|
||||
import { registryItemFileSchema, registryItemSchema } from "shadcn/registry"
|
||||
import { Project, ScriptKind, SourceFile, SyntaxKind } from "ts-morph"
|
||||
import { z } from "zod"
|
||||
|
||||
import { Style } from "@/registry/registry-styles"
|
||||
import { registryItemFileSchema, registryItemSchema } from "@/registry/schema"
|
||||
|
||||
export const DEFAULT_REGISTRY_STYLE = "new-york" satisfies Style["name"]
|
||||
|
||||
@@ -157,7 +157,7 @@ function getFileTarget(file: z.infer<typeof registryItemFileSchema>) {
|
||||
}
|
||||
}
|
||||
|
||||
return target
|
||||
return target ?? ""
|
||||
}
|
||||
|
||||
async function createTempSourceFile(filename: string) {
|
||||
|
||||
@@ -79,6 +79,21 @@ export function rehypeNpmCommand() {
|
||||
"bunx --bun"
|
||||
)
|
||||
}
|
||||
|
||||
// npm run.
|
||||
if (node.properties?.["__rawString__"]?.startsWith("npm run")) {
|
||||
const npmCommand = node.properties?.["__rawString__"]
|
||||
node.properties["__npmCommand__"] = npmCommand
|
||||
node.properties["__yarnCommand__"] = npmCommand.replace(
|
||||
"npm run",
|
||||
"yarn"
|
||||
)
|
||||
node.properties["__pnpmCommand__"] = npmCommand.replace(
|
||||
"npm run",
|
||||
"pnpm"
|
||||
)
|
||||
node.properties["__bunCommand__"] = npmCommand.replace("npm run", "bun")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@
|
||||
"react-resizable-panels": "^2.0.22",
|
||||
"react-wrap-balancer": "^0.4.1",
|
||||
"recharts": "2.12.7",
|
||||
"shadcn": "2.3.0",
|
||||
"sharp": "^0.31.3",
|
||||
"sonner": "^1.2.3",
|
||||
"swr": "2.2.6-beta.3",
|
||||
|
||||
BIN
apps/www/public/images/block-preview-dark.png
Normal file
BIN
apps/www/public/images/block-preview-dark.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 53 KiB |
BIN
apps/www/public/images/block-preview-light.png
Normal file
BIN
apps/www/public/images/block-preview-light.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 55 KiB |
BIN
apps/www/public/images/registry-dark.png
Normal file
BIN
apps/www/public/images/registry-dark.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
BIN
apps/www/public/images/registry-light.png
Normal file
BIN
apps/www/public/images/registry-light.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
File diff suppressed because it is too large
Load Diff
20
apps/www/public/r/facebook.json
Normal file
20
apps/www/public/r/facebook.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/registry.json",
|
||||
"name": "facebook",
|
||||
"type": "registry:block",
|
||||
"registryDependencies": [],
|
||||
"dependencies": ["motion"],
|
||||
"devDependencies": [],
|
||||
"tailwind": {},
|
||||
"cssVars": {
|
||||
"light": {},
|
||||
"dark": {}
|
||||
},
|
||||
"files": [
|
||||
{
|
||||
"path": "facebook.tsx",
|
||||
"content": "'use client';\n\nimport type { Variants } from 'motion/react';\nimport { motion, useAnimation } from 'motion/react';\n\nconst facebookVariants: Variants = {\n normal: {\n opacity: 1,\n pathLength: 1,\n pathOffset: 0,\n transition: {\n duration: 0.4,\n opacity: { duration: 0.1 },\n },\n },\n animate: {\n opacity: [0, 1],\n pathLength: [0, 1],\n pathOffset: [1, 0],\n transition: {\n duration: 0.6,\n ease: 'linear',\n opacity: { duration: 0.1 },\n },\n },\n};\n\nconst FacebookIcon = () => {\n const controls = useAnimation();\n\n return (\n <div\n className=\"cursor-pointer select-none p-2 hover:bg-accent rounded-md transition-colors duration-200 flex items-center justify-center\"\n onMouseEnter={() => {\n controls.start('animate');\n }}\n onMouseLeave={() => {\n controls.start('normal');\n }}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <motion.path\n variants={facebookVariants}\n animate={controls}\n initial=\"normal\"\n d=\"M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z\"\n />\n </svg>\n </div>\n );\n};\n\nexport { FacebookIcon };\n",
|
||||
"type": "registry:ui"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "accordion-demo",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"accordion"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "accordion",
|
||||
"type": "registry:ui",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"dependencies": [
|
||||
"@radix-ui/react-accordion"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "alert-demo",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"alert"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "alert-destructive",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"alert"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "alert-dialog-demo",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"alert-dialog",
|
||||
"button"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "alert-dialog",
|
||||
"type": "registry:ui",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"dependencies": [
|
||||
"@radix-ui/react-alert-dialog"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "alert",
|
||||
"type": "registry:ui",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"files": [
|
||||
{
|
||||
"path": "ui/alert.tsx",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "aspect-ratio-demo",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"aspect-ratio"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "aspect-ratio",
|
||||
"type": "registry:ui",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"dependencies": [
|
||||
"@radix-ui/react-aspect-ratio"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "avatar-demo",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"avatar"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "avatar",
|
||||
"type": "registry:ui",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"dependencies": [
|
||||
"@radix-ui/react-avatar"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "badge-demo",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"badge"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "badge-destructive",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"badge"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "badge-outline",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"badge"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "badge-secondary",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"badge"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "badge",
|
||||
"type": "registry:ui",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"files": [
|
||||
{
|
||||
"path": "ui/badge.tsx",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "breadcrumb-demo",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"breadcrumb"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "breadcrumb-dropdown",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"breadcrumb"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "breadcrumb-ellipsis",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"breadcrumb"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "breadcrumb-link",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"breadcrumb"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "breadcrumb-responsive",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"breadcrumb"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "breadcrumb-separator",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"breadcrumb"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "breadcrumb",
|
||||
"type": "registry:ui",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"dependencies": [
|
||||
"@radix-ui/react-slot"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "button-as-child",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"button"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "button-demo",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"button"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "button-destructive",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"button"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "button-ghost",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"button"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "button-icon",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"button"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "button-link",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"button"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "button-loading",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"button"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "button-outline",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"button"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "button-secondary",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"button"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "button-with-icon",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"button"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "button",
|
||||
"type": "registry:ui",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"dependencies": [
|
||||
"@radix-ui/react-slot"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-demo",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-form",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"form",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar",
|
||||
"type": "registry:ui",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"dependencies": [
|
||||
"react-day-picker@8.10.1",
|
||||
"date-fns"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "card-demo",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"card",
|
||||
"button",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "card-with-form",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"button",
|
||||
"card",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "card",
|
||||
"type": "registry:ui",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"files": [
|
||||
{
|
||||
"path": "ui/card.tsx",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "carousel-api",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"carousel"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "carousel-demo",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"carousel"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "carousel-orientation",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"carousel"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "carousel-plugin",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"carousel"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "carousel-size",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"carousel"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "carousel-spacing",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"carousel"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "carousel",
|
||||
"type": "registry:ui",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"dependencies": [
|
||||
"embla-carousel-react"
|
||||
],
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "chart-area-axes",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"card",
|
||||
"chart"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "chart-area-default",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"card",
|
||||
"chart"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "chart-area-gradient",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"card",
|
||||
"chart"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "chart-area-icons",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"card",
|
||||
"chart"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "chart-area-interactive",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"card",
|
||||
"chart",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "chart-area-legend",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"card",
|
||||
"chart"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "chart-area-linear",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"card",
|
||||
"chart"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "chart-area-stacked-expand",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"card",
|
||||
"chart"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "chart-area-stacked",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"card",
|
||||
"chart"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "chart-area-step",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"card",
|
||||
"chart"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "chart-bar-active",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"card",
|
||||
"chart"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "chart-bar-default",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"registryDependencies": [
|
||||
"card",
|
||||
"chart"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "chart-bar-demo-axis",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"files": [
|
||||
{
|
||||
"path": "examples/chart-bar-demo-axis.tsx",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "chart-bar-demo-grid",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"files": [
|
||||
{
|
||||
"path": "examples/chart-bar-demo-grid.tsx",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "chart-bar-demo-legend",
|
||||
"type": "registry:example",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"files": [
|
||||
{
|
||||
"path": "examples/chart-bar-demo-legend.tsx",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user