{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "record-detail-page",
  "title": "Record Detail Page",
  "type": "registry:page",
  "description": "Admin record detail page: breadcrumb header with status badge and Edit / Delete actions, two-column layout with a summary card (avatar, identity, key metrics), Details / Activity tabs (labeled description-list sections and an icon timeline feed), plus a side panel with owner metadata, relative timestamps, tag badges, and a recent-orders mini list. All data is hardcoded inline for you to replace.",
  "categories": [
    "layout",
    "app"
  ],
  "files": [
    {
      "path": "packages/elements-lit/src/blocks/record-detail-page/record-detail-page.ts",
      "content": "import { LitElement, css, html } from 'lit'\nimport {\n  Building2,\n  ChevronRight,\n  CreditCard,\n  FileText,\n  Mail,\n  MessageSquare,\n  Pencil,\n  Plus,\n  ReceiptText,\n  Trash2,\n  UserPlus,\n  type IconNode,\n} from 'lucide'\nimport { tailwind } from '../../lib/styles'\nimport { ThemeController } from '../../lib/theme'\nimport { icon } from '../../lib/icon'\n// Side-effect imports: register the composed elements for standalone use\n// (consumers who install only this block still get working primitives).\nimport '../../components/avatar/avatar'\nimport '../../components/badge/badge'\nimport '../../components/button/button'\nimport '../../components/card/card'\nimport '../../components/separator/separator'\nimport '../../components/tabs/tabs'\n\ninterface DataListRow {\n  label: string\n  value: string\n}\n\ninterface Section {\n  heading: string\n  icon: IconNode\n  iconName: string\n  rows: DataListRow[]\n}\n\ninterface ActivityEvent {\n  icon: IconNode\n  iconName: string\n  sentence: string\n  time: string\n}\n\ninterface Order {\n  id: string\n  amount: string\n  status: 'Paid' | 'Pending' | 'Refunded'\n}\n\nconst summaryRows: DataListRow[] = [\n  { label: 'Account ID', value: 'CUS-004182' },\n  { label: 'Plan', value: 'Business annual' },\n  { label: 'Lifetime value', value: '$48,200' },\n]\n\nconst sections: Section[] = [\n  {\n    heading: 'Contact',\n    icon: Mail,\n    iconName: 'mail',\n    rows: [\n      { label: 'Email', value: 'billing@acmecorp.com' },\n      { label: 'Phone', value: '+1 (415) 555-0134' },\n      { label: 'Website', value: 'acmecorp.com' },\n      { label: 'Address', value: '500 Market St, San Francisco, CA' },\n    ],\n  },\n  {\n    heading: 'Company',\n    icon: Building2,\n    iconName: 'building-2',\n    rows: [\n      { label: 'Industry', value: 'Logistics & supply chain' },\n      { label: 'Employees', value: '240–500' },\n      { label: 'Tax ID', value: 'US-84-2917365' },\n      { label: 'Payment terms', value: 'Net 30' },\n    ],\n  },\n]\n\nconst activity: ActivityEvent[] = [\n  { icon: ReceiptText, iconName: 'receipt-text', sentence: 'Invoice INV-2091 paid — $12,400', time: '2h ago' },\n  { icon: MessageSquare, iconName: 'message-square', sentence: 'Priya left a note on the renewal deal', time: 'Yesterday' },\n  { icon: UserPlus, iconName: 'user-plus', sentence: 'Dana Whitfield added as billing contact', time: '3d ago' },\n  { icon: FileText, iconName: 'file-text', sentence: 'Contract Q3-amendment.pdf uploaded', time: '1w ago' },\n]\n\nconst tags = ['enterprise', 'renewal-q4', 'priority-support']\n\nconst orders: Order[] = [\n  { id: 'ORD-8841', amount: '$12,400.00', status: 'Paid' },\n  { id: 'ORD-8790', amount: '$3,180.50', status: 'Pending' },\n  { id: 'ORD-8612', amount: '$940.00', status: 'Refunded' },\n]\n\n/**\n * <uip-record-detail-page> — the registry RecordDetailPage block as a web\n * component.\n *\n * Class strings are React's RecordDetailPage verbatim: breadcrumb header,\n * summary card, Details / Activity tabs, meta + recent-orders side panel.\n * All data is hardcoded inline for you to replace. No props, no events: edit\n * the markup in place.\n *\n * Deviation: React's `className` on Card parts reaches the shadow DOM via\n * `[&::part(base)]:…` on the host (their utilities only exist in the shadow\n * sheet); the separator's `mb-4` likewise becomes\n * `[&::part(base)]:mb-4` (its host is `display: contents`).\n */\nexport class UipRecordDetailPage extends LitElement {\n  static shadowRootOptions = { ...LitElement.shadowRootOptions, delegatesFocus: true }\n  // :host display can't be a utility class (the host has no template of its own).\n  static styles = [tailwind, css`:host { display: block; }`]\n\n  constructor() {\n    super()\n    new ThemeController(this)\n  }\n\n  connectedCallback() {\n    super.connectedCallback()\n    this.setAttribute('data-uipkge', '')\n    this.setAttribute('data-slot', 'record-detail-page')\n  }\n\n  render() {\n    return html`\n      <div data-slot=\"record-detail-page\" class=\"bg-background text-foreground w-full\">\n        <div class=\"flex flex-wrap items-center justify-between gap-4\">\n          <div class=\"flex min-w-0 items-center gap-1.5\">\n            <uip-button variant=\"link\" size=\"sm\" class=\"text-muted-foreground h-auto min-h-6 px-0\">\n              Customers\n            </uip-button>\n            ${icon(ChevronRight, 'chevron-right', 'text-muted-foreground size-4 shrink-0')}\n            <span class=\"truncate text-sm font-semibold\">Acme Corp</span>\n            <uip-badge variant=\"secondary\" class=\"ml-2\"> Active </uip-badge>\n          </div>\n          <div class=\"flex items-center gap-2\">\n            <uip-button variant=\"outline\" size=\"sm\">\n              ${icon(Pencil, 'pencil', 'size-4')} Edit\n            </uip-button>\n            <uip-button variant=\"outline\" size=\"sm\" class=\"text-destructive hover:text-destructive\">\n              ${icon(Trash2, 'trash-2', 'size-4')} Delete\n            </uip-button>\n          </div>\n        </div>\n\n        <div class=\"mt-6 grid gap-6 lg:grid-cols-3\">\n          <div class=\"space-y-6 lg:col-span-2\">\n            <uip-card>\n              <uip-card-header\n                class=\"[&::part(base)]:flex-row [&::part(base)]:items-center [&::part(base)]:gap-4 [&::part(base)]:space-y-0\"\n              >\n                <uip-avatar class=\"[&::part(base)]:size-14\">\n                  <uip-avatar-image src=\"https://i.pravatar.cc/112?img=32\" alt=\"Acme Corp logo\"></uip-avatar-image>\n                  <uip-avatar-fallback>AC</uip-avatar-fallback>\n                </uip-avatar>\n                <div class=\"min-w-0\">\n                  <uip-card-title class=\"[&::part(base)]:text-lg\">Acme Corp</uip-card-title>\n                  <uip-card-description class=\"[&::part(base)]:truncate\">\n                    billing@acmecorp.com · Customer since March 2023\n                  </uip-card-description>\n                </div>\n              </uip-card-header>\n              <uip-card-content>\n                <uip-separator class=\"[&::part(base)]:mb-4\"></uip-separator>\n                <dl class=\"grid gap-x-8 gap-y-3 sm:grid-cols-3\">\n                  ${summaryRows.map(\n                    (row) => html`\n                      <div>\n                        <dt class=\"text-muted-foreground text-xs\">${row.label}</dt>\n                        <dd class=\"mt-0.5 text-sm font-medium\">${row.value}</dd>\n                      </div>\n                    `,\n                  )}\n                </dl>\n              </uip-card-content>\n            </uip-card>\n\n            <uip-tabs value=\"details\">\n              <span slot=\"trigger\" data-value=\"details\">Details</span>\n              <span slot=\"trigger\" data-value=\"activity\">Activity</span>\n\n              <div slot=\"content\" data-value=\"details\" class=\"space-y-6 pt-4\">\n                ${sections.map(\n                  (section) => html`\n                    <section>\n                      <h3 class=\"flex items-center gap-2 text-sm font-semibold\">\n                        ${icon(section.icon, section.iconName, 'text-muted-foreground size-4')} ${section.heading}\n                      </h3>\n                      <dl class=\"border-border mt-3 divide-y rounded-lg border\">\n                        ${section.rows.map(\n                          (row) => html`\n                            <div class=\"px-4 py-2.5 sm:flex sm:items-center sm:gap-4\">\n                              <dt class=\"text-muted-foreground text-xs sm:w-36 sm:text-sm\">${row.label}</dt>\n                              <dd class=\"mt-0.5 text-sm font-medium sm:mt-0\">${row.value}</dd>\n                            </div>\n                          `,\n                        )}\n                      </dl>\n                    </section>\n                  `,\n                )}\n              </div>\n\n              <div slot=\"content\" data-value=\"activity\" class=\"pt-4\">\n                <ol class=\"before:bg-border relative space-y-6 before:absolute before:inset-y-1 before:left-[15px] before:w-px\">\n                  ${activity.map(\n                    (event) => html`\n                      <li class=\"relative flex items-start gap-4 pl-0\">\n                        <span\n                          class=\"bg-background ring-border relative z-10 flex size-8 shrink-0 items-center justify-center rounded-full ring-1\"\n                        >\n                          ${icon(event.icon, event.iconName, 'text-muted-foreground size-4')}\n                        </span>\n                        <div class=\"min-w-0 pt-1\">\n                          <p class=\"truncate text-sm\">${event.sentence}</p>\n                          <time class=\"text-muted-foreground text-xs\">${event.time}</time>\n                        </div>\n                      </li>\n                    `,\n                  )}\n                </ol>\n              </div>\n            </uip-tabs>\n          </div>\n\n          <div class=\"space-y-6\">\n            <uip-card>\n              <uip-card-header>\n                <uip-card-title class=\"[&::part(base)]:text-sm [&::part(base)]:font-medium\">Record meta</uip-card-title>\n              </uip-card-header>\n              <uip-card-content class=\"[&::part(base)]:space-y-4\">\n                <div class=\"flex items-center gap-3\">\n                  <uip-avatar class=\"size-8\">\n                    <uip-avatar-image src=\"https://i.pravatar.cc/64?img=47\" alt=\"Priya Raman\"></uip-avatar-image>\n                    <uip-avatar-fallback>PR</uip-avatar-fallback>\n                  </uip-avatar>\n                  <div class=\"min-w-0\">\n                    <p class=\"text-muted-foreground text-xs\">Owner</p>\n                    <p class=\"truncate text-sm font-medium\">Priya Raman</p>\n                  </div>\n                </div>\n                <uip-separator></uip-separator>\n                <dl class=\"space-y-3\">\n                  <div class=\"flex items-center justify-between gap-4\">\n                    <dt class=\"text-muted-foreground text-xs\">Created</dt>\n                    <dd class=\"text-sm font-medium\">Mar 14, 2023</dd>\n                  </div>\n                  <div class=\"flex items-center justify-between gap-4\">\n                    <dt class=\"text-muted-foreground text-xs\">Updated</dt>\n                    <dd class=\"text-sm font-medium\">2 hours ago</dd>\n                  </div>\n                </dl>\n                <uip-separator></uip-separator>\n                <div>\n                  <p class=\"text-muted-foreground mb-2 text-xs\">Tags</p>\n                  <div class=\"flex flex-wrap gap-1.5\">\n                    ${tags.map((tag) => html`<uip-badge variant=\"secondary\">${tag}</uip-badge>`)}\n                  </div>\n                </div>\n              </uip-card-content>\n            </uip-card>\n\n            <uip-card>\n              <uip-card-header\n                class=\"[&::part(base)]:flex-row [&::part(base)]:items-center [&::part(base)]:justify-between [&::part(base)]:space-y-0\"\n              >\n                <uip-card-title class=\"[&::part(base)]:text-sm [&::part(base)]:font-medium\">Recent orders</uip-card-title>\n                <uip-button variant=\"ghost\" size=\"icon\" aria-label=\"View all orders\">\n                  ${icon(CreditCard, 'credit-card', 'size-4')}\n                </uip-button>\n              </uip-card-header>\n              <uip-card-content>\n                <ul class=\"divide-y\">\n                  ${orders.map(\n                    (order) => html`\n                      <li class=\"flex items-center gap-3 py-2.5 first:pt-0 last:pb-0\">\n                        <span class=\"font-mono text-xs\">${order.id}</span>\n                        <span class=\"text-muted-foreground ml-auto text-sm tabular-nums\">${order.amount}</span>\n                        <uip-badge\n                          variant=${order.status === 'Paid' ? 'default' : order.status === 'Pending' ? 'secondary' : 'outline'}\n                          class=\"[&::part(base)]:min-w-[72px] [&::part(base)]:justify-center\"\n                        >\n                          ${order.status}\n                        </uip-badge>\n                      </li>\n                    `,\n                  )}\n                </ul>\n                <uip-button variant=\"outline\" size=\"sm\" class=\"mt-4 w-full\">\n                  ${icon(Plus, 'plus', 'size-4')} New order\n                </uip-button>\n              </uip-card-content>\n            </uip-card>\n          </div>\n        </div>\n      </div>\n    `\n  }\n}\n\ncustomElements.get('uip-record-detail-page') || customElements.define('uip-record-detail-page', UipRecordDetailPage)\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    'uip-record-detail-page': UipRecordDetailPage\n  }\n}\n",
      "type": "registry:file",
      "target": "src/uip/blocks/record-detail-page/record-detail-page.ts"
    }
  ],
  "dependencies": [
    "lit",
    "lucide"
  ],
  "registryDependencies": [
    "https://uipkge.dev/r/lit/avatar.json",
    "https://uipkge.dev/r/lit/badge.json",
    "https://uipkge.dev/r/lit/button.json",
    "https://uipkge.dev/r/lit/card.json",
    "https://uipkge.dev/r/lit/lit-core.json",
    "https://uipkge.dev/r/lit/separator.json",
    "https://uipkge.dev/r/lit/tabs.json"
  ]
}
