源码
这里展示 registry 中会被 shadcn 安装到目标项目的组件源码。
import {
BoxesIcon,
FileJsonIcon,
MonitorCheckIcon,
} from "lucide-react"
import { Badge } from "@/components/ui/badge"
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card"
const features = [
{
icon: BoxesIcon,
},
{
icon: FileJsonIcon,
},
{
icon: MonitorCheckIcon,
},
] as const
type FeatureListItem = {
title: string
description: string
}
type FeatureListCopy = {
badge: string
title: string
description: string
features: [FeatureListItem, FeatureListItem, FeatureListItem]
}
type FeatureListProps = {
copy?: FeatureListCopy
}
const defaultCopy: FeatureListCopy = {
badge: "System",
title: "Library building blocks",
description:
"Use this pattern for feature summaries, capability lists, or onboarding sections.",
features: [
{
title: "Composable blocks",
description: "Ship source-level components that can be edited in every consuming app.",
},
{
title: "Registry output",
description: "Build installable JSON artifacts that shadcn CLI can consume by URL.",
},
{
title: "Preview first",
description: "Keep a visual workbench so humans and AI tools can inspect available UI.",
},
],
}
export function FeatureList({ copy = defaultCopy }: FeatureListProps) {
return (
<Card className="w-full max-w-2xl">
<CardHeader>
<Badge className="w-fit" variant="secondary">
{copy.badge}
</Badge>
<CardTitle>{copy.title}</CardTitle>
<CardDescription>
{copy.description}
</CardDescription>
</CardHeader>
<CardContent className="grid gap-3 md:grid-cols-3">
{features.map((feature, index) => {
const Icon = feature.icon
const featureCopy = copy.features[index]
return (
<div
key={featureCopy.title}
className="flex min-w-0 flex-col gap-3 rounded-lg border bg-background p-4"
>
<div className="flex size-8 items-center justify-center rounded-lg bg-muted text-foreground">
<Icon />
</div>
<div className="flex flex-col gap-1">
<h3 className="text-sm font-medium">{featureCopy.title}</h3>
<p className="text-sm leading-6 text-muted-foreground">
{featureCopy.description}
</p>
</div>
</div>
)
})}
</CardContent>
</Card>
)
}