{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "team-bios",
  "title": "Team Bios",
  "description": "Bio-forward Payload team block: two-up member cards with avatar, role, and biography.",
  "registryDependencies": [
    "badge"
  ],
  "files": [
    {
      "path": "payload-components/source/blocks/shared/teamFields.ts",
      "content": "import type { Field } from 'payload'\n\n/**\n * Shared field core for the Team component family.\n *\n * Every team variant (team-roster, team-grid, …) spreads `teamFields` first for\n * the shared heading, then appends its own variant-specific shape — the grouped\n * department roster or the flat member grid that differs per layout. Editing the\n * shared eyebrow/title shape here updates every installed team block at once, so\n * the family never drifts field-by-field across a repo.\n *\n * `teamMemberFields` is the one-person shape (avatar upload, name, role, optional\n * link) reused by both variants — team-roster nests it inside each group, while\n * team-grid uses it for a single flat `members` array — so a member looks the\n * same everywhere it appears. Each avatar is an editable Media upload, so editors\n * manage the team from the admin instead of shipping hardcoded image URLs.\n *\n * Installed once per repo at `src/blocks/shared/teamFields.ts`; re-running\n * `payload-components add team-*` never overwrites a copy you have already edited.\n */\nexport const teamFields: Field[] = [\n  {\n    name: 'eyebrow',\n    type: 'text',\n  },\n  {\n    name: 'title',\n    type: 'text',\n    required: true,\n  },\n]\n\nexport const teamMemberFields: Field[] = [\n  {\n    name: 'avatar',\n    type: 'upload',\n    relationTo: 'media',\n    required: true,\n  },\n  {\n    name: 'name',\n    type: 'text',\n    required: true,\n  },\n  {\n    name: 'role',\n    type: 'text',\n    required: true,\n  },\n  {\n    name: 'href',\n    type: 'text',\n  },\n]\n",
      "type": "registry:file",
      "target": "~/src/blocks/shared/teamFields.ts"
    },
    {
      "path": "payload-components/source/blocks/TeamBios/config.ts",
      "content": "import type { Block } from 'payload'\n\nimport { teamFields, teamMemberFields } from '@/blocks/shared/teamFields'\n\nexport const TeamBios: Block = {\n  slug: 'teamBios',\n  // Existing apps must migrate stored data before adopting this identifier:\n  // https://www.payload-components.xyz/docs/registry#installed-source-and-migrations\n  dbName: 'pc_tea_bio',\n  interfaceName: 'TeamBiosBlock',\n  fields: [\n    // Shared team core (eyebrow, title). Variant-specific fields follow; edit the\n    // shared shape in @/blocks/shared/teamFields.\n    ...teamFields,\n    {\n      name: 'description',\n      type: 'textarea',\n    },\n    {\n      name: 'members',\n      type: 'array',\n      required: true,\n      minRows: 1,\n      maxRows: 8,\n      admin: {\n        initCollapsed: true,\n      },\n      // Shared member shape plus the bio this variant renders — see\n      // @/blocks/shared/teamFields. Appending here keeps `bio` off the compact\n      // team-grid and team-roster schemas, which have no room to show it.\n      fields: [\n        ...teamMemberFields,\n        {\n          name: 'bio',\n          type: 'textarea',\n          required: true,\n        },\n      ],\n    },\n  ],\n  labels: {\n    plural: 'Team Bios Blocks',\n    singular: 'Team Bios',\n  },\n}\n",
      "type": "registry:file",
      "target": "~/src/blocks/TeamBios/config.ts"
    },
    {
      "path": "payload-components/source/blocks/TeamBios/Component.tsx",
      "content": "import React from 'react'\n\nimport type { TeamBiosBlock as TeamBiosBlockData } from '@/payload-types'\n\nimport { Media } from '@/components/Media'\nimport { Badge } from '@/components/ui/badge'\nimport { cn } from '@/utilities/ui'\n\ntype Props = TeamBiosBlockData & {\n  id?: string\n  className?: string\n  disableInnerContainer?: boolean\n}\n\nexport const TeamBiosBlock: React.FC<Props> = ({\n  className,\n  description,\n  disableInnerContainer,\n  eyebrow,\n  id,\n  members,\n  title,\n}) => {\n  return (\n    <section className={cn('container', className)} id={id ? `block-${id}` : undefined}>\n      <div className=\"overflow-hidden rounded-frame border border-border/70 bg-card/35 px-6 py-10 sm:px-8 lg:px-12 lg:py-14\">\n        <div\n          className={cn('flex flex-col gap-12', {\n            'mx-auto max-w-5xl': !disableInnerContainer,\n          })}\n        >\n          <div className=\"flex max-w-2xl flex-col gap-4\">\n            {eyebrow ? (\n              <Badge\n                variant=\"outline\"\n                className=\"w-fit rounded-full px-3 py-1 uppercase tracking-eyebrow\"\n              >\n                {eyebrow}\n              </Badge>\n            ) : null}\n\n            <h2 className=\"text-3xl font-medium tracking-title text-balance sm:text-4xl\">\n              {title}\n            </h2>\n\n            {description ? (\n              <p className=\"text-base leading-7 text-muted-foreground\">{description}</p>\n            ) : null}\n          </div>\n\n          {members && members.length > 0 ? (\n            <div className=\"grid gap-x-8 gap-y-10 sm:grid-cols-2\">\n              {members.map((member, index) => (\n                <article\n                  className=\"flex flex-col gap-4 rounded-panel border border-border/70 bg-background/70 p-6\"\n                  key={member.id ?? index}\n                >\n                  <div className=\"flex items-center gap-4\">\n                    <div className=\"size-14 shrink-0 overflow-hidden rounded-full border border-border/70 bg-card p-0.5\">\n                      <Media\n                        resource={member.avatar}\n                        imgClassName=\"h-full w-full rounded-full object-cover object-top\"\n                      />\n                    </div>\n\n                    <div className=\"flex min-w-0 flex-col\">\n                      <h3 className=\"truncate text-base font-medium text-foreground\">\n                        {member.name}\n                      </h3>\n                      <span className=\"truncate text-sm text-muted-foreground\">{member.role}</span>\n                    </div>\n                  </div>\n\n                  <p className=\"text-sm leading-6 text-muted-foreground\">{member.bio}</p>\n\n                  {member.href ? (\n                    <a\n                      className=\"mt-auto w-fit text-sm font-medium text-foreground underline-offset-4 hover:underline\"\n                      href={member.href}\n                    >\n                      Read more\n                    </a>\n                  ) : null}\n                </article>\n              ))}\n            </div>\n          ) : null}\n        </div>\n      </div>\n    </section>\n  )\n}\n",
      "type": "registry:file",
      "target": "~/src/blocks/TeamBios/Component.tsx"
    }
  ],
  "meta": {
    "payloadComponent": {
      "installCommand": "payload-components add team-bios",
      "postInstall": [
        "generate:types",
        "generate:importmap"
      ],
      "requiresPayloadComponentWrapper": true,
      "supportedTargets": [
        "payload-website-starter",
        "payload-blocks-app"
      ]
    }
  },
  "docs": "Payload Components installs this as a Payload CMS block for the Payload website starter shape.\n\nRecommended install:\n\n```bash\npnpm payload-components add team-bios\n```\n\nDirect shadcn install URL:\n\n```bash\npnpm dlx shadcn@latest add https://www.payload-components.xyz/r/team-bios.json\n```\n\nDirect shadcn installs only copy the block source files and shadcn UI dependencies. Use `payload-components add team-bios` when you also want Payload layout registration, `RenderBlocks` wiring, `generate:types`, and `generate:importmap` handled for you.",
  "type": "registry:block"
}