{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "before-after-side-by-side",
  "title": "Before & After — Side by Side",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/before-after-side-by-side/before-after-side-by-side.component.ts",
      "content": "// Two labelled panels set side by side at equal height with a shared annotation\n// row beneath, for comparisons a slider would make harder rather than clearer.\n// Port of the Vue/React block 1:1 — same Before/After file rows, same numbered\n// annotations referenced from both panels, same case-study CTA.\nimport { ChangeDetectionStrategy, Component, Input } from '@angular/core'\nimport { UiBadgeComponent } from '@/ui/badge/badge.component'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport { UiCardComponent, UiCardContentComponent } from '@/ui/card/card.component'\nimport { UiSeparatorComponent } from '@/ui/separator/separator.component'\nimport { cn } from '@/lib/utils'\n\ninterface BeforeAfterRow {\n  text: string\n  note: string\n}\n\ninterface BeforeAfterPanel {\n  label: string\n  caption: string\n  rows: BeforeAfterRow[]\n}\n\ninterface BeforeAfterAnnotation {\n  id: string\n  text: string\n}\n\n// Annotations are numbered and referenced from both panels, which is what makes\n// a side-by-side legible where a drag slider hides half the evidence.\nconst panels: BeforeAfterPanel[] = [\n  {\n    label: 'Before',\n    caption: 'Four exports reconciled by hand',\n    rows: [\n      { text: 'revenue_q1_final_v3.xlsx', note: '1' },\n      { text: 'revenue_q1_FINAL_v3b.xlsx', note: '1' },\n      { text: 'refunds_manual_adj.csv', note: '2' },\n      { text: 'fx_rates_pasted.csv', note: '3' },\n    ],\n  },\n  {\n    label: 'After',\n    caption: 'One certified definition',\n    rows: [\n      { text: 'metrics/revenue_net.yml', note: '1' },\n      { text: '  joins: refunds, fx_rates', note: '2' },\n      { text: '  owner: finance-analytics', note: '3' },\n      { text: '  reconciled: 4 quarters', note: '' },\n    ],\n  },\n]\n\nconst annotations: BeforeAfterAnnotation[] = [\n  { id: '1', text: 'Two files claiming to be final, differing by 40k in net revenue.' },\n  { id: '2', text: 'Refund adjustments applied by hand, with no record of who applied them.' },\n  { id: '3', text: 'FX rates pasted from a second system on a date nobody logged.' },\n]\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-before-after-side-by-side, [ui-before-after-side-by-side]',\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: [UiBadgeComponent, UiButtonComponent, UiCardComponent, UiCardContentComponent, UiSeparatorComponent],\n  template: `\n    <section data-slot=\"before-after-side-by-side\" [class]=\"rootClass\">\n      <div class=\"mx-auto max-w-5xl px-6 py-20 lg:py-28\">\n        <span ui-badge variant=\"secondary\">Before and after</span>\n        <h2 class=\"mt-4 text-3xl font-semibold tracking-tight sm:text-4xl\">The same close, two quarters apart</h2>\n\n        <!-- items-stretch so both panels share a height; a slider would hide one\n             side at a time and make the annotations unreadable. -->\n        <div class=\"mt-10 grid items-stretch gap-4 md:grid-cols-2\">\n          @for (panel of panels; track panel.label) {\n            <div ui-card>\n              <div ui-card-content class=\"flex h-full flex-col p-0\">\n                <div class=\"border-border flex items-center justify-between gap-3 border-b px-4 py-2.5\">\n                  <span class=\"text-sm font-semibold\">{{ panel.label }}</span>\n                  <span class=\"text-muted-foreground text-xs\">{{ panel.caption }}</span>\n                </div>\n                <ul class=\"flex-1 space-y-2 p-4\">\n                  @for (row of panel.rows; track row.text) {\n                    <li class=\"flex items-start gap-2\">\n                      @if (row.note) {\n                        <span\n                          class=\"border-border text-muted-foreground mt-px flex size-4 shrink-0 items-center justify-center rounded-full border font-mono text-xs\"\n                        >\n                          {{ row.note }}\n                        </span>\n                      } @else {\n                        <span class=\"size-4 shrink-0\" aria-hidden=\"true\"></span>\n                      }\n                      <span class=\"min-w-0 font-mono text-xs break-all\">{{ row.text }}</span>\n                    </li>\n                  }\n                </ul>\n              </div>\n            </div>\n          }\n        </div>\n\n        <ui-separator class=\"my-8\" />\n\n        <ol class=\"space-y-3\">\n          @for (annotation of annotations; track annotation.id) {\n            <li class=\"flex items-start gap-3 text-sm\">\n              <span\n                class=\"border-border text-muted-foreground mt-0.5 flex size-5 shrink-0 items-center justify-center rounded-full border font-mono text-xs\"\n              >\n                {{ annotation.id }}\n              </span>\n              <span class=\"text-muted-foreground leading-relaxed\">{{ annotation.text }}</span>\n            </li>\n          }\n        </ol>\n\n        <button ui-button class=\"mt-8\">Read the full case study</button>\n      </div>\n    </section>\n  `,\n})\nexport class UiBeforeAfterSideBySideComponent {\n  protected readonly panels = panels\n  protected readonly annotations = annotations\n\n  @Input('class') className?: string\n\n  get rootClass(): string {\n    return cn('bg-background', this.className)\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/before-after-side-by-side/before-after-side-by-side.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/before-after-side-by-side/index.ts",
      "content": "export { UiBeforeAfterSideBySideComponent } from './before-after-side-by-side.component'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/before-after-side-by-side/index.ts"
    }
  ],
  "dependencies": [],
  "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/separator.json"
  ],
  "description": "Two labelled panels set side by side at equal height with a shared annotation row beneath, for comparisons a slider would make harder rather than clearer.",
  "categories": [
    "marketing"
  ]
}