{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"page-header","type":"registry:ui","title":"Page Header","description":"The top of an admin page: breadcrumb, title, description, actions and tabs.","dependencies":["lucide-react"],"registryDependencies":["https://dashral.com/r/utils.json","https://dashral.com/r/breadcrumb.json"],"files":[{"path":"registry/dashral/page-header.tsx","type":"registry:file","target":"components/dashral/page-header.tsx","content":"import * as React from \"react\"\nimport { ArrowLeftIcon } from \"lucide-react\"\n\nimport { cn } from \"./lib/utils\"\nimport { Breadcrumb, type BreadcrumbItem } from \"./breadcrumb\"\n\ntype PageHeaderProps = Omit<React.ComponentProps<\"header\">, \"title\"> & {\n  /** The page's name, as its heading. */\n  title: React.ReactNode\n  /** A line under the title: what the page is for. */\n  description?: React.ReactNode\n  /** The heading's level: h1 (default) for the page, h2 for a section with a header of its own. */\n  titleAs?: \"h1\" | \"h2\"\n  /** Above the title: the trail to this page, drawn with Breadcrumb. */\n  breadcrumb?: BreadcrumbItem[]\n  /** Above the title instead of a breadcrumb: a link back, \"← Invoices\". */\n  back?: { href: string; label: React.ReactNode }\n  /** Beside the title, e.g. a status badge. */\n  badge?: React.ReactNode\n  /** A row under the title: who made it, when, a few badges. */\n  meta?: React.ReactNode\n  /** At the end: the page's buttons. On a phone they move under the title. */\n  actions?: React.ReactNode\n  /** Under everything, e.g. Tabs with variant=\"line\"; with divided, the line runs under them. */\n  tabs?: React.ReactNode\n  /** A line under the header. */\n  divided?: boolean\n  /** sm for a page inside a panel or a settings section. */\n  size?: \"sm\" | \"default\"\n  /** Your router's link, for the breadcrumb and the back link. */\n  linkAs?: React.ElementType\n  classNames?: { title?: string; description?: string; meta?: string; actions?: string }\n}\n\n/**\n * The top of an admin page, in one tag: a breadcrumb or a back link, the title (a real heading) with a badge, a\n * description, a row of details, the page's actions and tabs. On a phone the actions wrap under the title.\n */\nfunction PageHeader({\n  title,\n  description,\n  titleAs: Title = \"h1\",\n  breadcrumb,\n  back,\n  badge,\n  meta,\n  actions,\n  tabs,\n  divided = false,\n  size = \"default\",\n  linkAs: Link = \"a\",\n  className,\n  classNames,\n  ...props\n}: PageHeaderProps) {\n  const sm = size === \"sm\"\n  return (\n    <header data-slot=\"page-header\" className={cn(\"grid grid-cols-1 gap-4\", divided && !tabs && (sm ? \"border-b pb-4\" : \"border-b pb-6\"), className)} {...props}>\n      {(breadcrumb || back) && (\n        <div className=\"-mb-1\">\n          {breadcrumb ? (\n            <Breadcrumb items={breadcrumb} linkAs={Link} />\n          ) : (\n            back && (\n              <Link\n                href={back.href}\n                className=\"inline-flex items-center gap-1.5 rounded-sm text-sm text-muted-foreground outline-none transition-colors hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring/50\"\n              >\n                <ArrowLeftIcon aria-hidden className=\"size-4 rtl:-scale-x-100\" />\n                {back.label}\n              </Link>\n            )\n          )}\n        </div>\n      )}\n      <div className=\"flex flex-col gap-4 sm:flex-row sm:items-end sm:justify-between\">\n        <div className=\"grid min-w-0 gap-1.5\">\n          <div className=\"flex min-w-0 flex-wrap items-center gap-x-3 gap-y-1\">\n            <Title\n              className={cn(\n                \"min-w-0 font-heading font-medium text-balance\",\n                sm ? \"text-lg leading-snug tracking-tight\" : \"text-2xl leading-tight tracking-[-0.03em] sm:text-[28px]\",\n                classNames?.title\n              )}\n            >\n              {title}\n            </Title>\n            {badge}\n          </div>\n          {description && (\n            <p className={cn(\"max-w-2xl text-sm leading-[1.55] text-pretty text-muted-foreground\", classNames?.description)}>{description}</p>\n          )}\n          {meta && (\n            <div className={cn(\"mt-1 flex flex-wrap items-center gap-x-4 gap-y-1.5 text-xs text-muted-foreground [&_svg]:size-3.5\", classNames?.meta)}>\n              {meta}\n            </div>\n          )}\n        </div>\n        {actions && <div className={cn(\"flex shrink-0 flex-wrap items-center gap-2\", classNames?.actions)}>{actions}</div>}\n      </div>\n      {tabs && <div className={cn(divided && \"border-b\")}>{tabs}</div>}\n    </header>\n  )\n}\n\nexport { PageHeader, type PageHeaderProps }\n"}],"cssVars":{"theme":{"font-heading":"var(--font-geist, \"Geist\"), var(--font-inter, \"Inter\"), var(--font-arabic, \"IBM Plex Sans Arabic\"), ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif"},"light":{},"dark":{}}}