源码
这里展示 registry 中会被 shadcn 安装到目标项目的组件源码。
import { BellIcon, GlobeIcon, LockIcon } from "lucide-react"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Checkbox } from "@/components/ui/checkbox"
import {
Field,
FieldContent,
FieldDescription,
FieldGroup,
FieldLabel,
FieldLegend,
FieldSet,
} from "@/components/ui/field"
import { Input } from "@/components/ui/input"
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
import { Separator } from "@/components/ui/separator"
import { Switch } from "@/components/ui/switch"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { Textarea } from "@/components/ui/textarea"
type SettingsFormCopy = {
title: string
description: string
tabs: [string, string, string]
projectName: string
projectNamePlaceholder: string
region: string
regions: [string, string, string]
descriptionLabel: string
descriptionPlaceholder: string
emailAlerts: string
emailAlertsDescription: string
deployAlerts: string
deployAlertsDescription: string
visibility: string
visibilityOptions: [string, string]
requireReview: string
requireReviewDescription: string
save: string
}
type SettingsFormProps = {
copy?: SettingsFormCopy
}
const defaultCopy: SettingsFormCopy = {
title: "Project settings",
description: "A form layout for product settings, account pages, and onboarding flows.",
tabs: ["General", "Notifications", "Security"],
projectName: "Project name",
projectNamePlaceholder: "Registry UI",
region: "Region",
regions: ["US East", "Europe", "Asia Pacific"],
descriptionLabel: "Description",
descriptionPlaceholder: "Describe how this workspace should be used.",
emailAlerts: "Email alerts",
emailAlertsDescription: "Send critical updates to workspace owners.",
deployAlerts: "Deploy notifications",
deployAlertsDescription: "Notify the team when registry builds finish.",
visibility: "Visibility",
visibilityOptions: ["Team only", "Public preview"],
requireReview: "Require review before publishing",
requireReviewDescription: "New registry items must be approved before release.",
save: "Save changes",
}
export function SettingsForm({ copy = defaultCopy }: SettingsFormProps) {
return (
<Card className="w-full max-w-2xl">
<CardHeader>
<CardTitle>{copy.title}</CardTitle>
<CardDescription>{copy.description}</CardDescription>
</CardHeader>
<CardContent>
<Tabs defaultValue="general">
<TabsList>
<TabsTrigger value="general">
<GlobeIcon data-icon="inline-start" />
{copy.tabs[0]}
</TabsTrigger>
<TabsTrigger value="notifications">
<BellIcon data-icon="inline-start" />
{copy.tabs[1]}
</TabsTrigger>
<TabsTrigger value="security">
<LockIcon data-icon="inline-start" />
{copy.tabs[2]}
</TabsTrigger>
</TabsList>
<TabsContent value="general" className="pt-4">
<FieldGroup>
<Field>
<FieldLabel htmlFor="project-name">{copy.projectName}</FieldLabel>
<Input id="project-name" placeholder={copy.projectNamePlaceholder} />
</Field>
<Field>
<FieldLabel>{copy.region}</FieldLabel>
<Select defaultValue="us-east">
<SelectTrigger className="w-full">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectItem value="us-east">{copy.regions[0]}</SelectItem>
<SelectItem value="europe">{copy.regions[1]}</SelectItem>
<SelectItem value="asia-pacific">{copy.regions[2]}</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</Field>
<Field>
<FieldLabel htmlFor="project-description">
{copy.descriptionLabel}
</FieldLabel>
<Textarea
id="project-description"
placeholder={copy.descriptionPlaceholder}
/>
</Field>
</FieldGroup>
</TabsContent>
<TabsContent value="notifications" className="pt-4">
<FieldGroup>
<Field orientation="horizontal">
<Switch id="email-alerts" defaultChecked />
<FieldContent>
<FieldLabel htmlFor="email-alerts">
{copy.emailAlerts}
</FieldLabel>
<FieldDescription>
{copy.emailAlertsDescription}
</FieldDescription>
</FieldContent>
</Field>
<Separator />
<Field orientation="horizontal">
<Checkbox id="deploy-alerts" defaultChecked />
<FieldContent>
<FieldLabel htmlFor="deploy-alerts">
{copy.deployAlerts}
</FieldLabel>
<FieldDescription>
{copy.deployAlertsDescription}
</FieldDescription>
</FieldContent>
</Field>
</FieldGroup>
</TabsContent>
<TabsContent value="security" className="pt-4">
<FieldGroup>
<FieldSet>
<FieldLegend>{copy.visibility}</FieldLegend>
<RadioGroup defaultValue="team">
<Field orientation="horizontal">
<RadioGroupItem id="visibility-team" value="team" />
<FieldLabel htmlFor="visibility-team">
{copy.visibilityOptions[0]}
</FieldLabel>
</Field>
<Field orientation="horizontal">
<RadioGroupItem id="visibility-public" value="public" />
<FieldLabel htmlFor="visibility-public">
{copy.visibilityOptions[1]}
</FieldLabel>
</Field>
</RadioGroup>
</FieldSet>
<Separator />
<Field orientation="horizontal">
<Switch id="require-review" defaultChecked />
<FieldContent>
<FieldLabel htmlFor="require-review">
{copy.requireReview}
</FieldLabel>
<FieldDescription>
{copy.requireReviewDescription}
</FieldDescription>
</FieldContent>
</Field>
</FieldGroup>
</TabsContent>
</Tabs>
<div className="mt-5 flex justify-end">
<Button>{copy.save}</Button>
</div>
</CardContent>
</Card>
)
}