{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "ratings-star-summary",
  "title": "Ratings — Star Summary",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/ratings-star-summary/ratings-star-summary.component.ts",
      "content": "// Aggregate rating summary pairing a large score and partial-star row with a per-star\n// distribution and the review count each bar represents. Port of the React block 1:1.\nimport { ChangeDetectionStrategy, Component, Input } from '@angular/core'\nimport { LucideAngularModule, Star } from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiBadgeComponent } from '@/ui/badge/badge.component'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport { UiCardComponent, UiCardContentComponent } from '@/ui/card/card.component'\nimport { UiProgressComponent } from '@/ui/progress/progress.component'\nimport { UiSeparatorComponent } from '@/ui/separator/separator.component'\n\ninterface DistributionRow {\n  stars: number\n  count: number\n}\n\nconst score = 4.7\nconst total = 2117\n\nconst distribution: DistributionRow[] = [\n  { stars: 5, count: 1587 },\n  { stars: 4, count: 381 },\n  { stars: 3, count: 97 },\n  { stars: 2, count: 31 },\n  { stars: 1, count: 21 },\n]\n\nconst STAR_SLOTS = [1, 2, 3, 4, 5]\n\n/** Fill percentage for one slot, so 4.7 draws a real partial star. */\nfunction fillFor(slot: number): string {\n  return `${Math.min(Math.max(score - (slot - 1), 0), 1) * 100}%`\n}\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-ratings-star-summary, [ui-ratings-star-summary]',\n  standalone: true,\n  // The block renders its own root <section>: keep this wrapper out of the layout.\n  host: { '[attr.class]': '\"contents\"' },\n  imports: [\n    LucideAngularModule,\n    UiBadgeComponent,\n    UiButtonComponent,\n    UiCardComponent,\n    UiCardContentComponent,\n    UiProgressComponent,\n    UiSeparatorComponent,\n  ],\n  template: `\n    <section data-slot=\"ratings-star-summary\" [class]=\"rootClass\">\n      <div class=\"mx-auto max-w-4xl px-6 py-20 lg:py-28\">\n        <span ui-badge variant=\"secondary\">Reviews</span>\n        <h2 class=\"mt-4 text-3xl font-semibold tracking-tight sm:text-4xl\">What {{ total }} people say</h2>\n\n        <div ui-card class=\"mt-8\">\n          <div ui-card-content class=\"grid gap-8 p-6 sm:grid-cols-[auto_1fr] sm:gap-12 sm:p-8\">\n            <div class=\"text-center sm:text-left\">\n              <p class=\"font-display text-5xl font-bold tracking-tight\">{{ score }}</p>\n              <div\n                class=\"mt-2 flex items-center justify-center gap-0.5 sm:justify-start\"\n                role=\"img\"\n                [attr.aria-label]=\"score + ' out of 5'\"\n              >\n                @for (slot of starSlots; track slot) {\n                  <span class=\"relative inline-flex\">\n                    <lucide-icon [img]=\"Star\" class=\"text-muted-foreground/30 size-4\" aria-hidden=\"true\" />\n                    <span\n                      class=\"absolute inset-y-0 left-0 overflow-hidden\"\n                      [style.width]=\"fillFor(slot)\"\n                      aria-hidden=\"true\"\n                    >\n                      <lucide-icon [img]=\"Star\" class=\"fill-primary text-primary size-4\" />\n                    </span>\n                  </span>\n                }\n              </div>\n              <p class=\"text-muted-foreground mt-2 text-xs\">{{ total }} verified reviews</p>\n            </div>\n\n            <ui-separator orientation=\"vertical\" class=\"hidden h-auto sm:block\" />\n\n            <dl class=\"space-y-2.5\">\n              @for (row of distribution; track row.stars) {\n                <div class=\"flex items-center gap-4\">\n                  <dt class=\"text-muted-foreground w-12 shrink-0 font-mono text-xs\">{{ row.stars }} star</dt>\n                  <dd class=\"flex min-w-0 grow items-center gap-4\">\n                    <div\n                      ui-progress\n                      [value]=\"barShare(row)\"\n                      class=\"h-1.5\"\n                      [aria-label]=\"row.stars + ' star reviews'\"\n                    ></div>\n                    <span class=\"text-muted-foreground w-12 shrink-0 text-right font-mono text-xs\">\n                      {{ row.count }}\n                    </span>\n                  </dd>\n                </div>\n              }\n            </dl>\n          </div>\n        </div>\n\n        <div class=\"mt-6 flex flex-wrap items-center gap-4\">\n          <button ui-button variant=\"outline\">Read the one-star reviews</button>\n          <p class=\"text-muted-foreground text-sm\">They are the useful ones, and we have not hidden them.</p>\n        </div>\n      </div>\n    </section>\n  `,\n})\nexport class UiRatingsStarSummaryComponent {\n  protected readonly Star = Star\n  protected readonly score = score.toFixed(1)\n  protected readonly total = total.toLocaleString()\n  protected readonly distribution = distribution\n  protected readonly starSlots = STAR_SLOTS\n\n  @Input('class') className?: string\n\n  get rootClass(): string {\n    return cn('bg-background', this.className)\n  }\n\n  fillFor(slot: number): string {\n    return fillFor(slot)\n  }\n\n  barShare(row: DistributionRow): number {\n    return Math.round((row.count / total) * 100)\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/ratings-star-summary/ratings-star-summary.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/ratings-star-summary/index.ts",
      "content": "export { UiRatingsStarSummaryComponent } from './ratings-star-summary.component'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/ratings-star-summary/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/card.json",
    "https://uipkge.dev/r/angular/progress.json",
    "https://uipkge.dev/r/angular/separator.json"
  ],
  "description": "Aggregate rating summary pairing a large score and partial-star row with a per-star distribution and the review count each bar represents.",
  "categories": [
    "marketing"
  ]
}