{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "dashboard-shell",
  "title": "Dashboard Shell",
  "description": "Global navigation, page hierarchy, actions, key metrics, and a layout that stacks on narrow screens.",
  "dependencies": [
    "class-variance-authority"
  ],
  "registryDependencies": [
    "button",
    "https://uaiblocks.dev/r/uai-theme.json",
    "https://uaiblocks.dev/r/app-sidebar.json",
    "https://uaiblocks.dev/r/breadcrumb-trail.json",
    "https://uaiblocks.dev/r/metric-card.json",
    "https://uaiblocks.dev/r/uai-utils.json"
  ],
  "files": [
    {
      "path": "src/registry/uai/blocks/dashboard-shell.tsx",
      "content": "\"use client\";\n\nimport { cva } from \"class-variance-authority\";\nimport { type ComponentProps, createContext, useContext, useId } from \"react\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n  AppSidebar,\n  type AppSidebarProps,\n  type AppSidebarVariant,\n} from \"@/components/ui/uai/app-sidebar\";\nimport {\n  BreadcrumbTrail,\n  type BreadcrumbTrailProps,\n  type BreadcrumbTrailVariant,\n} from \"@/components/ui/uai/breadcrumb-trail\";\nimport {\n  MetricCard,\n  type MetricCardProps,\n  type MetricCardVariant,\n} from \"@/components/ui/uai/metric-card\";\nimport { cn } from \"@/lib/uai-utils\";\n\nexport const DASHBOARD_SHELL_VARIANTS = [\"split\", \"inset\", \"compact\"] as const;\nexport type DashboardShellVariant = (typeof DASHBOARD_SHELL_VARIANTS)[number];\nexport type DashboardShellProps = ComponentProps<\"div\"> & { variant?: DashboardShellVariant };\n\ntype ShellContext = { id: string; variant: DashboardShellVariant };\nconst Context = createContext<ShellContext | null>(null);\nfunction useShell(part: string) {\n  const context = useContext(Context);\n  if (!context) throw new Error(`${part} must be used within DashboardShell`);\n  return context;\n}\nconst PanelContext = createContext<string | null>(null);\n\nconst sidebarVariants: Record<DashboardShellVariant, AppSidebarVariant> = {\n  split: \"panel\",\n  inset: \"inset\",\n  compact: \"compact\",\n};\nconst breadcrumbVariants: Record<DashboardShellVariant, BreadcrumbTrailVariant> = {\n  split: \"chevron\",\n  inset: \"chevron\",\n  compact: \"slash\",\n};\nconst metricVariants: Record<DashboardShellVariant, MetricCardVariant> = {\n  split: \"card\",\n  inset: \"card\",\n  compact: \"compact\",\n};\n\nconst dashboardShellVariants = cva(\n  \"flex min-w-0 flex-wrap items-stretch text-[13px]/[18px] text-foreground\",\n  {\n    variants: {\n      variant: {\n        split: \"gap-4 rounded-none bg-transparent p-0\",\n        inset: \"gap-2 rounded-[20px] bg-muted p-1.5\",\n        compact: \"gap-2 rounded-none bg-transparent p-0\",\n      },\n    },\n  },\n);\n\nconst dashboardShellActionVariants = cva(\n  \"inline-flex cursor-pointer items-center gap-1.5 rounded-full border-0 font-medium whitespace-nowrap transition-[background-color,filter,scale] duration-[120ms,120ms,140ms] ease-[ease-out,ease-out,cubic-bezier(0.23,1,0.32,1)] py-0 focus-visible:ring-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:outline-solid enabled:active:scale-[0.97] motion-reduce:transition-none motion-reduce:enabled:active:scale-100 [&_svg:not([class*='size-'])]:size-3.5\",\n  {\n    variants: {\n      emphasis: {\n        primary: \"bg-primary text-primary-foreground hover:bg-primary enabled:hover:brightness-108\",\n        secondary:\n          \"bg-secondary text-secondary-foreground enabled:hover:bg-[color-mix(in_oklab,var(--secondary)_85%,var(--foreground))]\",\n      },\n      compact: {\n        true: \"h-[26px] px-2.5 has-[>svg]:px-2.5 text-[12px]\",\n        false: \"h-7.5 px-[13px] has-[>svg]:px-[13px] text-[12.5px]\",\n      },\n    },\n  },\n);\n\n/** Page frame: global navigation beside a labelled main region. Wraps below the sidebar on narrow screens. */\nexport function DashboardShell({\n  variant = \"split\",\n  className,\n  children,\n  ...props\n}: DashboardShellProps) {\n  const id = useId();\n  return (\n    <Context.Provider value={{ id, variant }}>\n      <div\n        data-slot=\"dashboard-shell\"\n        className={cn(dashboardShellVariants({ variant }), className)}\n        {...props}\n        data-variant={variant}\n      >\n        {children}\n      </div>\n    </Context.Provider>\n  );\n}\n\n/** Global navigation. Compose App Sidebar parts inside it. */\nexport function DashboardShellSidebar({ className, ...props }: Omit<AppSidebarProps, \"variant\">) {\n  const context = useShell(\"DashboardShellSidebar\");\n  return (\n    <AppSidebar\n      {...props}\n      variant={sidebarVariants[context.variant]}\n      className={cn(\"h-auto shrink-0\", className)}\n    />\n  );\n}\n\nexport function DashboardShellMain({ className, ...props }: ComponentProps<\"section\">) {\n  const context = useShell(\"DashboardShellMain\");\n  const { variant } = context;\n  return (\n    <section\n      data-slot=\"dashboard-shell-main\"\n      aria-labelledby={`${context.id}-title`}\n      className={cn(\n        \"grid min-w-0 flex-[1_1_360px] content-start border-0\",\n        variant === \"compact\" ? \"gap-3\" : \"gap-5\",\n        variant === \"inset\"\n          ? \"rounded-[14px] bg-card px-[22px] py-5 ring-1 ring-border\"\n          : cn(\"rounded-none bg-transparent px-0\", variant === \"compact\" ? \"py-1\" : \"py-2\"),\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\n/** Page hierarchy and page actions. Actions wrap below the heading on narrow widths. */\nexport function DashboardShellHeader({ className, ...props }: ComponentProps<\"div\">) {\n  useShell(\"DashboardShellHeader\");\n  return (\n    <div\n      data-slot=\"dashboard-shell-header\"\n      className={cn(\"flex min-w-0 flex-wrap items-end justify-between gap-3\", className)}\n      {...props}\n    />\n  );\n}\n\nexport function DashboardShellHeading({ className, ...props }: ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"dashboard-shell-heading\"\n      className={cn(\"grid min-w-0 flex-[1_1_240px] gap-1\", className)}\n      {...props}\n    />\n  );\n}\n\nexport function DashboardShellBreadcrumb({\n  className,\n  ...props\n}: Omit<BreadcrumbTrailProps, \"variant\">) {\n  const context = useShell(\"DashboardShellBreadcrumb\");\n  return (\n    <BreadcrumbTrail\n      {...props}\n      variant={breadcrumbVariants[context.variant]}\n      className={cn(\"-ml-1.5\", className)}\n    />\n  );\n}\n\nexport function DashboardShellTitle({ className, ...props }: ComponentProps<\"h2\">) {\n  const context = useShell(\"DashboardShellTitle\");\n  return (\n    <h2\n      data-slot=\"dashboard-shell-title\"\n      className={cn(\n        \"m-0 font-semibold tracking-[-0.01em] wrap-anywhere\",\n        context.variant === \"compact\" ? \"text-[15px]/5\" : \"text-[18px]/6\",\n        className,\n      )}\n      {...props}\n      id={`${context.id}-title`}\n    />\n  );\n}\n\nexport function DashboardShellDescription({ className, ...props }: ComponentProps<\"p\">) {\n  return (\n    <p\n      data-slot=\"dashboard-shell-description\"\n      className={cn(\"m-0 text-pretty text-muted-foreground\", className)}\n      {...props}\n    />\n  );\n}\n\nexport function DashboardShellActions({ className, ...props }: ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"dashboard-shell-actions\"\n      className={cn(\"flex flex-wrap items-center gap-1.5\", className)}\n      {...props}\n    />\n  );\n}\n\nexport function DashboardShellAction({\n  emphasis = \"secondary\",\n  type = \"button\",\n  className,\n  ...props\n}: ComponentProps<\"button\"> & { emphasis?: \"primary\" | \"secondary\" }) {\n  const context = useShell(\"DashboardShellAction\");\n  return (\n    <Button\n      data-slot=\"dashboard-shell-action\"\n      variant={emphasis === \"primary\" ? \"default\" : \"secondary\"}\n      data-emphasis={emphasis}\n      className={cn(\n        dashboardShellActionVariants({ emphasis, compact: context.variant === \"compact\" }),\n        className,\n      )}\n      {...props}\n      type={type}\n    />\n  );\n}\n\n/** Key figures. Cards reflow from four columns to one without media queries. */\nexport function DashboardShellMetrics({ className, ...props }: ComponentProps<\"div\">) {\n  const context = useShell(\"DashboardShellMetrics\");\n  const compact = context.variant === \"compact\";\n  return (\n    <div\n      data-slot=\"dashboard-shell-metrics\"\n      className={cn(\n        \"grid min-w-0\",\n        compact\n          ? \"grid-cols-[repeat(auto-fit,minmax(min(100%,150px),1fr))] gap-2\"\n          : \"grid-cols-[repeat(auto-fit,minmax(min(100%,180px),1fr))] gap-3\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nexport function DashboardShellMetric(props: Omit<MetricCardProps, \"variant\">) {\n  const context = useShell(\"DashboardShellMetric\");\n  return <MetricCard {...props} variant={metricVariants[context.variant]} />;\n}\n\nexport function DashboardShellContent({ className, ...props }: ComponentProps<\"div\">) {\n  const context = useShell(\"DashboardShellContent\");\n  return (\n    <div\n      data-slot=\"dashboard-shell-content\"\n      className={cn(\n        \"grid min-w-0 grid-cols-[repeat(auto-fit,minmax(min(100%,280px),1fr))]\",\n        context.variant === \"compact\" ? \"gap-2\" : \"gap-3\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nexport function DashboardShellPanel({ className, ...props }: ComponentProps<\"section\">) {\n  const context = useShell(\"DashboardShellPanel\");\n  const labelId = useId();\n  const compact = context.variant === \"compact\";\n  return (\n    <PanelContext.Provider value={labelId}>\n      <section\n        data-slot=\"dashboard-shell-panel\"\n        aria-labelledby={labelId}\n        className={cn(\n          \"grid min-w-0 content-start border-0\",\n          compact ? \"gap-2 rounded-xl p-3\" : \"gap-3 rounded-[14px] p-4\",\n          context.variant === \"inset\"\n            ? \"bg-[color-mix(in_oklab,var(--muted)_55%,var(--card))]\"\n            : \"bg-card ring-1 ring-border\",\n          className,\n        )}\n        {...props}\n      />\n    </PanelContext.Provider>\n  );\n}\n\nexport function DashboardShellPanelTitle({ className, ...props }: ComponentProps<\"h3\">) {\n  const labelId = useContext(PanelContext);\n  if (!labelId) throw new Error(\"DashboardShellPanelTitle must be used within DashboardShellPanel\");\n  return (\n    <h3\n      data-slot=\"dashboard-shell-panel-title\"\n      className={cn(\"m-0 text-[13px]/[18px] font-medium\", className)}\n      {...props}\n      id={labelId}\n    />\n  );\n}\n",
      "type": "registry:component",
      "target": "@components/uai/dashboard-shell.tsx"
    }
  ],
  "categories": [
    "application"
  ],
  "type": "registry:block"
}