{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "comparison-table",
  "title": "Comparison Table",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/comparison-table/comparison-table.component.ts",
      "content": "// Plan comparison feature matrix (Starter / Pro / Enterprise) with a monthly/yearly\n// toggle that flips prices live, grouped feature rows, and check / minus / value cells.\n// The Pro column is highlighted with a \"Popular\" badge and a primary tint. Port of the React block 1:1.\nimport { ChangeDetectionStrategy, Component, Input, signal } from '@angular/core'\nimport { Check, LucideAngularModule, Minus } from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiBadgeComponent } from '@/ui/badge/badge.component'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport { UiToggleGroupComponent, UiToggleGroupItemComponent } from '@/ui/toggle-group/toggle-group.component'\n\nexport type BillingCycle = 'monthly' | 'yearly'\nexport type ComparisonCell = boolean | string | number\n\nexport interface ComparisonPlan {\n  name: string\n  monthly: number\n  yearly: number\n  cta: string\n  popular?: boolean\n}\n\nexport interface ComparisonFeature {\n  label: string\n  cells: [ComparisonCell, ComparisonCell, ComparisonCell]\n}\n\nexport interface ComparisonGroup {\n  label: string\n  features: ComparisonFeature[]\n}\n\nconst defaultPlans: ComparisonPlan[] = [\n  { name: 'Starter', monthly: 9, yearly: 7, cta: 'Start free' },\n  { name: 'Pro', monthly: 29, yearly: 24, cta: 'Start 14-day trial', popular: true },\n  { name: 'Enterprise', monthly: 79, yearly: 65, cta: 'Talk to sales' },\n]\n\nconst defaultGroups: ComparisonGroup[] = [\n  {\n    label: 'Core',\n    features: [\n      { label: 'Projects', cells: [3, 'Unlimited', 'Unlimited'] },\n      { label: 'Team seats', cells: ['5 seats', '20 seats', 'Custom'] },\n      { label: 'API access', cells: [false, true, true] },\n    ],\n  },\n  {\n    label: 'Collaboration',\n    features: [\n      { label: 'Shared workspaces', cells: [false, true, true] },\n      { label: 'Guest reviewers', cells: [false, '5 guests', 'Unlimited'] },\n      { label: 'Roles & permissions', cells: [true, true, true] },\n      { label: 'Audit log', cells: [false, false, true] },\n    ],\n  },\n  {\n    label: 'Support',\n    features: [\n      { label: 'Support channel', cells: ['Email', 'Priority email', 'Dedicated CSM'] },\n      { label: 'Guided onboarding', cells: [false, true, true] },\n      { label: 'Uptime SLA', cells: [false, false, '99.9%'] },\n    ],\n  },\n]\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-comparison-table, [ui-comparison-table]',\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: [\n    LucideAngularModule,\n    UiBadgeComponent,\n    UiButtonComponent,\n    UiToggleGroupComponent,\n    UiToggleGroupItemComponent,\n  ],\n  template: `\n    <section data-slot=\"comparison-table\" [class]=\"rootClass\">\n      <div class=\"mx-auto max-w-5xl px-6 py-16\">\n        <div class=\"mb-8 flex flex-col items-center gap-4 text-center\">\n          <h2 class=\"text-2xl font-semibold tracking-tight sm:text-3xl\">Compare plans</h2>\n          <ui-toggle-group type=\"single\" [value]=\"cycle()\" (valueChange)=\"setCycle($event)\">\n            <button ui-toggle-group-item value=\"monthly\">Monthly</button>\n            <button ui-toggle-group-item value=\"yearly\">\n              Yearly\n              <span ui-badge variant=\"secondary\" class=\"ml-2\">−20%</span>\n            </button>\n          </ui-toggle-group>\n        </div>\n\n        <div class=\"overflow-x-auto rounded-lg border\">\n          <table class=\"w-full max-w-[640px] min-w-full border-separate border-spacing-0 text-sm\">\n            <caption class=\"sr-only\">\n              Feature comparison across Starter, Pro, and Enterprise plans\n            </caption>\n\n            <thead>\n              <tr>\n                <th\n                  scope=\"col\"\n                  class=\"bg-background/95 supports-[backdrop-filter]:bg-background/80 text-muted-foreground sticky top-0 left-0 z-10 w-1/4 border-b p-4 text-left font-medium backdrop-blur\"\n                >\n                  <span class=\"sr-only\">Feature</span>\n                </th>\n                @for (plan of plans; track plan.name) {\n                  <th\n                    scope=\"col\"\n                    [class]=\"\n                      plan.popular\n                        ? 'bg-primary/10 supports-[backdrop-filter]:bg-primary/10 sticky top-0 z-10 border-b p-4 text-center align-bottom backdrop-blur'\n                        : 'bg-background/95 supports-[backdrop-filter]:bg-background/80 sticky top-0 z-10 border-b p-4 text-center align-bottom backdrop-blur'\n                    \"\n                  >\n                    <div class=\"flex flex-col items-center gap-1.5\">\n                      @if (plan.popular) {\n                        <span ui-badge>Popular</span>\n                      }\n                      <span class=\"text-base font-semibold tracking-tight\">{{ plan.name }}</span>\n                      <span class=\"tabular-nums\">\n                        <span class=\"text-2xl font-semibold\">\\${{ priceFor(plan) }}</span>\n                        <span class=\"text-muted-foreground text-xs\"> /mo</span>\n                      </span>\n                      <button ui-button size=\"sm\" [variant]=\"plan.popular ? 'default' : 'outline'\" class=\"mt-1 w-full\">\n                        {{ plan.cta }}\n                      </button>\n                    </div>\n                  </th>\n                }\n              </tr>\n            </thead>\n\n            @for (group of groups; track group.label) {\n              <tbody>\n                <tr>\n                  <th\n                    colspan=\"4\"\n                    scope=\"colgroup\"\n                    class=\"bg-muted/50 text-muted-foreground border-b p-3 text-left text-xs font-semibold tracking-widest uppercase\"\n                  >\n                    {{ group.label }}\n                  </th>\n                </tr>\n                @for (feature of group.features; track feature.label) {\n                  <tr class=\"hover:bg-muted/30\">\n                    <th scope=\"row\" class=\"border-b p-4 text-left align-middle font-normal\">\n                      {{ feature.label }}\n                    </th>\n                    @for (cell of feature.cells; track $index) {\n                      <td\n                        [class]=\"\n                          'border-b p-4 text-center align-middle' + (plans[$index].popular ? ' bg-primary/5' : '')\n                        \"\n                      >\n                        @if (cell === true) {\n                          <lucide-icon [img]=\"Check\" class=\"text-foreground mx-auto size-4\" aria-label=\"Included\" />\n                        } @else if (cell === false) {\n                          <lucide-icon\n                            [img]=\"Minus\"\n                            class=\"text-muted-foreground/50 mx-auto size-4\"\n                            aria-label=\"Not included\"\n                          />\n                        } @else {\n                          <span class=\"text-xs font-medium\">{{ cell }}</span>\n                        }\n                      </td>\n                    }\n                  </tr>\n                }\n              </tbody>\n            }\n          </table>\n        </div>\n      </div>\n    </section>\n  `,\n})\nexport class UiComparisonTableComponent {\n  protected readonly Check = Check\n  protected readonly Minus = Minus\n\n  @Input() plans: ComparisonPlan[] = defaultPlans\n  @Input() groups: ComparisonGroup[] = defaultGroups\n  @Input() set initialCycle(v: BillingCycle | undefined) {\n    if (v) this.cycle.set(v)\n  }\n  @Input('class') className?: string\n\n  readonly cycle = signal<BillingCycle>('monthly')\n\n  get rootClass(): string {\n    return cn('bg-background w-full', this.className)\n  }\n\n  setCycle(v: unknown): void {\n    if (v === 'monthly' || v === 'yearly') this.cycle.set(v)\n  }\n\n  priceFor(plan: ComparisonPlan): number {\n    return this.cycle() === 'monthly' ? plan.monthly : plan.yearly\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/comparison-table/comparison-table.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/comparison-table/index.ts",
      "content": "export {\n  UiComparisonTableComponent,\n  type BillingCycle,\n  type ComparisonCell,\n  type ComparisonPlan,\n  type ComparisonFeature,\n  type ComparisonGroup,\n} from './comparison-table.component'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/comparison-table/index.ts"
    }
  ],
  "dependencies": [
    "lucide-angular"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/angular/badge.json",
    "https://uipkge.dev/r/angular/button.json",
    "https://uipkge.dev/r/angular/toggle-group.json"
  ],
  "description": "Plan comparison feature matrix (Starter / Pro / Enterprise) with a sticky header row, monthly/yearly toggle that flips prices live, grouped feature rows (Core / Collaboration / Support), and check / minus / short-value cells. The Pro column is highlighted with a \"Popular\" badge and a primary tint down the whole column.",
  "categories": [
    "marketing",
    "pricing"
  ]
}