返回组件列表
人员

资料卡片

适合团队成员、负责人和账号信息的紧凑资料卡。

页面预览
源码
这里展示 registry 中会被 shadcn 安装到目标项目的组件源码。
registry/default/profile-card/profile-card.tsx
import { MailIcon, MoreHorizontalIcon } from "lucide-react"

import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import {
  Card,
  CardContent,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/ui/card"
import { Separator } from "@/components/ui/separator"

type ProfileCardCopy = {
  initials: string
  name: string
  role: string
  status: string
  description: string
  primaryAction: string
  secondaryAction: string
}

type ProfileCardProps = {
  copy?: ProfileCardCopy
}

const defaultCopy: ProfileCardCopy = {
  initials: "CN",
  name: "Chen Ning",
  role: "Design systems lead",
  status: "Available",
  description:
    "Owns component quality, preview coverage, and reusable product patterns.",
  primaryAction: "Message",
  secondaryAction: "More",
}

export function ProfileCard({ copy = defaultCopy }: ProfileCardProps) {
  return (
    <Card className="w-full max-w-sm">
      <CardHeader>
        <div className="flex items-start gap-3">
          <div className="flex size-12 shrink-0 items-center justify-center rounded-full bg-muted text-sm font-medium text-foreground">
            {copy.initials}
          </div>
          <div className="flex min-w-0 flex-1 flex-col gap-1">
            <div className="flex flex-wrap items-center gap-2">
              <CardTitle className="text-base">{copy.name}</CardTitle>
              <Badge variant="outline">{copy.status}</Badge>
            </div>
            <p className="text-sm text-muted-foreground">{copy.role}</p>
          </div>
        </div>
      </CardHeader>
      <CardContent className="flex flex-col gap-4">
        <p className="text-sm leading-6 text-muted-foreground">
          {copy.description}
        </p>
        <Separator />
        <div className="flex flex-wrap gap-2">
          <Badge variant="secondary">Registry</Badge>
          <Badge variant="secondary">Preview</Badge>
          <Badge variant="secondary">QA</Badge>
        </div>
      </CardContent>
      <CardFooter className="flex gap-2">
        <Button className="flex-1">
          <MailIcon data-icon="inline-start" />
          {copy.primaryAction}
        </Button>
        <Button size="icon" variant="outline" aria-label={copy.secondaryAction}>
          <MoreHorizontalIcon data-icon="inline-start" />
        </Button>
      </CardFooter>
    </Card>
  )
}