{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"diff-view","type":"registry:component","title":"Diff View","description":"A line-by-line diff with an added or removed mark in the gutter and a tinted row for each side. Renders a diff, doesn't compute one.","author":"Ryan","dependencies":["clsx","lucide-react","tailwind-merge"],"registryDependencies":[],"files":[{"path":"components/motion/diff-view.tsx","type":"registry:component","target":"@components/motion/diff-view.tsx","content":"// easeui.dev/components/motion/diff-view\nimport { FileCode, Minus, Plus } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\n\nexport type DiffLineType = \"add\" | \"remove\" | \"context\";\nexport type DiffLine = { type: DiffLineType; content: string };\n\nexport interface DiffViewProps {\n  /** Pre-computed diff lines. This renders a diff, it doesn't compute one. */\n  lines: DiffLine[];\n  /** Shown in the header, such as a filename. Default \"diff\". */\n  label?: string;\n  className?: string;\n}\n\nconst LINE_CLASS: Record<DiffLineType, string> = {\n  add: \"bg-success/10 text-foreground\",\n  remove: \"bg-destructive/10 text-foreground\",\n  context: \"text-muted-foreground\",\n};\n\nconst MARK: Record<DiffLineType, React.ReactNode> = {\n  add: <Plus aria-hidden=\"true\" className=\"h-3 w-3 text-success\" strokeWidth={3} />,\n  remove: <Minus aria-hidden=\"true\" className=\"h-3 w-3 text-destructive\" strokeWidth={3} />,\n  context: null,\n};\n\n/** A line-by-line diff, with an added or removed gutter mark and a tinted row for each side. */\nexport function DiffView({ lines, label = \"diff\", className }: DiffViewProps) {\n  return (\n    <figure\n      className={cn(\n        \"overflow-hidden rounded-2xl bg-card font-mono text-[13px] leading-relaxed shadow-[0_0_0_1px_var(--border)]\",\n        className,\n      )}\n    >\n      <figcaption className=\"flex h-11 items-center gap-2 border-b border-border pl-4 pr-1.5 font-sans text-xs text-muted-foreground\">\n        <FileCode aria-hidden=\"true\" className=\"h-3.5 w-3.5 shrink-0\" />\n        <span className=\"truncate\">{label}</span>\n      </figcaption>\n      <div className=\"overflow-x-auto py-1.5\">\n        {lines.map((line, index) => (\n          <div\n            // biome-ignore lint/suspicious/noArrayIndexKey: a fixed diff, lines never reorder.\n            key={index}\n            className={cn(\"flex items-start gap-3 px-4 py-0.5\", LINE_CLASS[line.type])}\n          >\n            <span aria-hidden=\"true\" className=\"mt-1 flex w-3 shrink-0 items-center justify-center\">\n              {MARK[line.type]}\n            </span>\n            <span className=\"whitespace-pre\">{line.content || \" \"}</span>\n          </div>\n        ))}\n      </div>\n    </figure>\n  );\n}\n"},{"path":"lib/utils.ts","type":"registry:lib","target":"@lib/utils.ts","content":"import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n"}]}