{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "feature-interactive-tabs",
  "title": "Feature Interactive Tabs",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/feature-interactive-tabs/feature-interactive-tabs.component.ts",
      "content": "// Master-detail architectural feature workbench: a navigation rail of feature tabs on\n// the left and an interactive detail sandbox (tag, headline, copyable source snippet,\n// telemetry stats, verified checks) on the right. Port of the React block 1:1.\nimport { ChangeDetectionStrategy, Component, DestroyRef, Input, computed, inject, signal } from '@angular/core'\nimport {\n  Activity,\n  Check,\n  CheckCircle2,\n  Code2,\n  Copy,\n  LayoutGrid,\n  LucideAngularModule,\n  Terminal,\n  Zap,\n  type LucideIconData,\n} from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiBadgeComponent } from '@/ui/badge/badge.component'\nimport { UiCardComponent } from '@/ui/card/card.component'\n\nexport interface FeatureTab {\n  id: string\n  title: string\n  subtitle: string\n  icon: LucideIconData\n  tag: string\n  headline: string\n  description: string\n  codeSnippet: string\n  stats: { label: string; value: string }[]\n  checks: string[]\n}\n\nconst tabs: FeatureTab[] = [\n  {\n    id: 'unbundled',\n    title: 'Zero-Package Registry',\n    subtitle: 'Direct AST source ownership',\n    icon: Code2,\n    tag: 'No Node Modules Bloat',\n    headline: 'You own 100% of the source code. No semver breaking changes.',\n    description:\n      'Unlike monolithic component packages that lock you into inflexible dependency trees, UIPKGE copies pristine, tree-shakeable source files directly into your project repository.',\n    codeSnippet: `// Terminal command:\\nnpx shadcn@latest add https://uipkge.dev/r/react/hero-developer-terminal.json\\n\\n// Output in your repo:\\n// ✔ Placed components/blocks/HeroDeveloperTerminal.tsx\\n// ✔ Installed zero runtime wrapper overhead`,\n    stats: [\n      { label: 'Bundle Size Overhead', value: '0.0 kB' },\n      { label: 'Semver Breakage Risk', value: '0%' },\n      { label: 'Customization Freedom', value: '100%' },\n    ],\n    checks: [\n      'Raw SFC/TSX files living right in your /components directory',\n      'Edit Tailwind tokens, props, or behavior anytime without forking',\n      'Never wait on upstream maintainers for critical hotfixes or styling tweaks',\n    ],\n  },\n  {\n    id: 'parity',\n    title: 'Dual-Framework Parity',\n    subtitle: 'Synchronized Vue 3.5 & React 19',\n    icon: LayoutGrid,\n    tag: '1:1 AST Parity',\n    headline: 'One design system, identical aesthetics across Vue and React.',\n    description:\n      'Whether your engineering organization uses Nuxt 3, Vite, Next.js, or Astro, every primitive and block shares identical OKLCH color spaces, CVA variant tokens, and spring transition curves.',\n    codeSnippet: `// Vue 3.5 SFC:\\n<Button variant=\"default\" size=\"sm\">Deploy</Button>\\n\\n// React 19 JSX:\\n<Button variant=\"default\" size=\"sm\">Deploy</Button>\\n\\n// Both generate identical DOM attributes & micro-interactions`,\n    stats: [\n      { label: 'Token Parity', value: '100.0%' },\n      { label: 'Supported Frameworks', value: 'Vue 3.5 + React 19' },\n      { label: 'Shared CVA Tokens', value: '31 Primitives' },\n    ],\n    checks: [\n      'Reka UI (Vue) and Radix UI (React) accessible headless engines',\n      'Automated CI check verifying cross-framework class string equality',\n      'Identical behavior in Vue and React microfrontends',\n    ],\n  },\n  {\n    id: 'telemetry',\n    title: 'Interactive Workbenches',\n    subtitle: 'Beyond static cards & fluff',\n    icon: Activity,\n    tag: 'Dense & Functional',\n    headline: 'Real-time controls, telemetry, and live interactive state.',\n    description:\n      'Every UIPKGE marketing block functions as a live interactive workbench with stateful sliders, timeframe toggles, and reactive calculation engines.',\n    codeSnippet: `// Composing live reactive telemetry in your blocks:\\nconst [activeCohort, setActiveCohort] = React.useState<'enterprise' | 'growth'>('enterprise')\\nconst liveThroughput = activeCohort === 'enterprise' ? '1.2M QPS' : '45k QPS'`,\n    stats: [\n      { label: 'Interactive Demos', value: '450+ Blocks' },\n      { label: 'Keyboard Ergonomics', value: 'WCAG AA' },\n      { label: 'Telemetry Visualizers', value: 'Real SVG Sparklines' },\n    ],\n    checks: [\n      'Functional master-detail views and comparative toggles',\n      'Integrated mock API testers, terminal sandboxes, and pricing calculators',\n      'Zero placeholder text or dummy lorum ipsum shapes',\n    ],\n  },\n  {\n    id: 'performance',\n    title: 'Sub-Millisecond Speed',\n    subtitle: 'OKLCH Tailwind v4 Engine',\n    icon: Zap,\n    tag: 'Lighthouse 100',\n    headline: 'Engineered for zero-latency interactions and pristine Lighthouse scores.',\n    description:\n      'Built on modern CSS custom properties and lightweight headless primitives, our blocks avoid hefty client-side runtime libraries, keeping your First Contentful Paint blazing fast.',\n    codeSnippet: `@theme inline {\\n  --color-primary: oklch(0.205 0 0);\\n  --color-primary-foreground: oklch(0.985 0 0);\\n  --ease-spring: cubic-bezier(0.16, 1, 0.3, 1);\\n}`,\n    stats: [\n      { label: 'Interaction to Next Paint (INP)', value: '< 16ms' },\n      { label: 'Lighthouse Score', value: '100 / 100' },\n      { label: 'CSS Engine', value: 'Tailwind CSS v4' },\n    ],\n    checks: [\n      'OKLCH native color spaces with automatic light/dark mode adaptation',\n      'Hardware-accelerated transforms and calibrated spring physics',\n      'Zero runtime JavaScript CSS parsing or CSS-in-JS style injection',\n    ],\n  },\n]\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-feature-interactive-tabs, [ui-feature-interactive-tabs]',\n  standalone: true,\n  // React renders the root <section> itself: the host stays out of layout and `class` goes to the root.\n  host: { '[attr.class]': '\"contents\"' },\n  imports: [LucideAngularModule, UiBadgeComponent, UiCardComponent],\n  template: `\n    <section data-slot=\"feature-interactive-tabs\" [class]=\"rootClass\">\n      <!-- Subtle Radial Glow -->\n      <div\n        class=\"bg-primary/5 pointer-events-none absolute top-1/2 left-1/2 -z-10 h-80 w-full max-w-5xl -translate-x-1/2 -translate-y-1/2 rounded-full blur-xl\"\n      ></div>\n\n      <div class=\"mx-auto max-w-7xl space-y-12\">\n        <!-- Section Header -->\n        <div class=\"mx-auto max-w-3xl space-y-4 text-center\">\n          <span ui-badge variant=\"secondary\" class=\"gap-1.5 px-3 py-1 font-mono text-xs shadow-xs\">\n            <lucide-icon [img]=\"LayoutGrid\" class=\"text-primary size-3.5\" />\n            Architecture Differentiation\n          </span>\n          <h2 class=\"text-foreground text-3xl font-bold tracking-tight sm:text-4xl\">\n            Why engineering teams choose UIPKGE.\n          </h2>\n          <p class=\"text-muted-foreground text-base\">\n            Explore the architectural pillars behind our unbundled component registry.\n          </p>\n        </div>\n\n        <!-- Feature Interactive Tabs Workbench -->\n        <div class=\"grid grid-cols-1 items-start gap-6 lg:grid-cols-12\">\n          <!-- Left Column: Master Feature Navigation Rail (4 Cols) -->\n          <div class=\"flex flex-col gap-2.5 lg:col-span-4\">\n            @for (tab of allTabs; track tab.id) {\n              <button type=\"button\" [class]=\"railButtonClass(tab.id)\" (click)=\"setActiveTab(tab.id)\">\n                <span class=\"flex items-start gap-3.5\">\n                  <span [class]=\"railIconClass(tab.id)\">\n                    <lucide-icon [img]=\"tab.icon\" class=\"size-4\" />\n                  </span>\n\n                  <span class=\"min-w-0 space-y-0.5\">\n                    <span class=\"flex items-center justify-between gap-2\">\n                      <span class=\"text-foreground truncate font-mono text-xs font-bold\">{{ tab.title }}</span>\n                      <span\n                        [class]=\"\n                          cn(\n                            'size-1.5 shrink-0 rounded-full',\n                            activeTabId() === tab.id ? 'bg-primary animate-pulse' : 'bg-transparent'\n                          )\n                        \"\n                      ></span>\n                    </span>\n                    <span class=\"text-muted-foreground block truncate text-xs\">{{ tab.subtitle }}</span>\n                  </span>\n                </span>\n              </button>\n            }\n          </div>\n\n          <!-- Right Column: Interactive Detail Sandbox Panel (8 Cols) -->\n          <div\n            ui-card\n            class=\"border-border bg-card/95 space-y-6 rounded-2xl p-6 text-left shadow-sm sm:p-8 lg:col-span-8\"\n          >\n            <!-- Detail Header -->\n            <div class=\"border-border/80 space-y-3 border-b pb-6\">\n              <div class=\"flex flex-wrap items-center justify-between gap-2\">\n                <span ui-badge variant=\"outline\" class=\"text-primary bg-primary/5 border-primary/20 font-mono text-xs\">\n                  {{ currentTab().tag }}\n                </span>\n                <span class=\"text-muted-foreground font-mono text-xs\">Architectural Specification</span>\n              </div>\n              <h3 class=\"text-foreground text-xl font-bold tracking-tight sm:text-2xl\">\n                {{ currentTab().headline }}\n              </h3>\n              <p class=\"text-muted-foreground text-xs leading-relaxed sm:text-sm\">\n                {{ currentTab().description }}\n              </p>\n            </div>\n\n            <!-- Code Snippet Sandbox Preview -->\n            <div class=\"space-y-2\">\n              <div class=\"text-muted-foreground flex items-center justify-between font-mono text-xs\">\n                <span class=\"flex items-center gap-1.5\">\n                  <lucide-icon [img]=\"Terminal\" class=\"text-primary size-3.5\" /> Source Implementation\n                </span>\n                <button\n                  type=\"button\"\n                  class=\"text-primary flex items-center gap-1 hover:underline\"\n                  (click)=\"copySnippet()\"\n                >\n                  @if (copiedCode()) {\n                    <lucide-icon [img]=\"Check\" class=\"text-success size-3\" />\n                  } @else {\n                    <lucide-icon [img]=\"Copy\" class=\"size-3\" />\n                  }\n                  <span>{{ copiedCode() ? 'Copied' : 'Copy Snippet' }}</span>\n                </button>\n              </div>\n              <pre\n                class=\"border-border bg-muted/40 text-foreground overflow-x-auto rounded-xl border p-4 font-mono text-xs leading-relaxed\"\n              ><code>{{ currentTab().codeSnippet }}</code></pre>\n            </div>\n\n            <!-- 3-Pillar Telemetry Metrics Bar -->\n            <div class=\"grid grid-cols-1 gap-3 pt-2 sm:grid-cols-3\">\n              @for (st of currentTab().stats; track st.label) {\n                <div class=\"border-border bg-background/50 space-y-0.5 rounded-xl border p-3.5\">\n                  <p class=\"text-muted-foreground font-mono text-xs tracking-wider uppercase\">{{ st.label }}</p>\n                  <p class=\"text-foreground font-mono text-base font-bold\">{{ st.value }}</p>\n                </div>\n              }\n            </div>\n\n            <!-- Technical Checkmarks List -->\n            <div class=\"border-border/60 space-y-2 border-t pt-2\">\n              <p class=\"text-muted-foreground font-mono text-xs tracking-wider uppercase\">Verified Enforcements</p>\n              <ul class=\"space-y-2\">\n                @for (chk of currentTab().checks; track chk) {\n                  <li class=\"text-foreground/90 flex items-start gap-2 text-xs\">\n                    <lucide-icon [img]=\"CheckCircle2\" class=\"text-success mt-0.5 size-4 shrink-0\" />\n                    <span>{{ chk }}</span>\n                  </li>\n                }\n              </ul>\n            </div>\n          </div>\n        </div>\n      </div>\n    </section>\n  `,\n})\nexport class UiFeatureInteractiveTabsComponent {\n  protected readonly cn = cn\n  protected readonly Check = Check\n  protected readonly CheckCircle2 = CheckCircle2\n  protected readonly Copy = Copy\n  protected readonly LayoutGrid = LayoutGrid\n  protected readonly Terminal = Terminal\n\n  protected readonly allTabs = tabs\n\n  @Input() set initialTab(v: string) {\n    if (tabs.some((t) => t.id === v)) this.activeTabId.set(v)\n  }\n  @Input('class') className?: string\n\n  readonly activeTabId = signal('unbundled')\n  readonly copiedCode = signal(false)\n  private copyTimer: ReturnType<typeof setTimeout> | undefined\n\n  constructor() {\n    inject(DestroyRef).onDestroy(() => clearTimeout(this.copyTimer))\n  }\n\n  readonly currentTab = computed(() => tabs.find((t) => t.id === this.activeTabId()) ?? tabs[0]!)\n\n  get rootClass(): string {\n    return cn('bg-background relative overflow-hidden px-4 py-16 sm:px-6 sm:py-24 lg:px-8', this.className)\n  }\n\n  railButtonClass(id: string): string {\n    return cn(\n      'group relative overflow-hidden rounded-2xl border p-4 text-left transition-[colors,box-shadow,transform] duration-150 active:scale-[0.98]',\n      this.activeTabId() === id\n        ? 'border-primary/80 bg-card ring-primary/20 shadow-sm ring-1'\n        : 'border-border bg-card/60 hover:border-border hover:bg-card',\n    )\n  }\n\n  railIconClass(id: string): string {\n    return cn(\n      'flex size-9 shrink-0 items-center justify-center rounded-lg font-mono transition-colors',\n      this.activeTabId() === id\n        ? 'bg-primary text-primary-foreground font-bold shadow-xs'\n        : 'bg-muted text-muted-foreground group-hover:text-foreground',\n    )\n  }\n\n  setActiveTab(id: string): void {\n    this.activeTabId.set(id)\n  }\n\n  async copySnippet(): Promise<void> {\n    try {\n      await navigator.clipboard.writeText(this.currentTab().codeSnippet)\n      this.copiedCode.set(true)\n      clearTimeout(this.copyTimer)\n      this.copyTimer = setTimeout(() => this.copiedCode.set(false), 2000)\n    } catch {\n      // Clipboard unavailable (e.g. insecure context): leave the label unchanged.\n    }\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/feature-interactive-tabs/feature-interactive-tabs.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/feature-interactive-tabs/index.ts",
      "content": "export { UiFeatureInteractiveTabsComponent, type FeatureTab } from './feature-interactive-tabs.component'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/feature-interactive-tabs/index.ts"
    }
  ],
  "dependencies": [
    "lucide-angular"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/angular/badge.json",
    "https://uipkge.dev/r/angular/card.json"
  ],
  "description": "Master-detail architectural feature workbench with interactive source snippets, copy action, telemetry stats, and verified technical checks.",
  "categories": [
    "marketing"
  ]
}