BranchDiff
neon-ui/branch-diffFreeComponent
Schema and row-level comparison between two branches with change counts, search, kind filters, and expandable DDL and word-level value diffs.
Install it
npx shadcn@latest add https://ui.neon.com/r/branch-diff.jsonSource
1"use client";23import {4 Alert02Icon,5 ArrowDown01Icon,6 ArrowRight01Icon,7 GitBranchIcon,8 Search01Icon,9 Table01Icon,10} from "@hugeicons/core-free-icons";11import { HugeiconsIcon } from "@hugeicons/react";12import { diffWordsWithSpace } from "diff";13import { useMemo, useState } from "react";1415import {16 Tabs,17 TabsContent,18 TabsIndicator,19 TabsList,20 TabsTrigger,21} from "@/components/ui/tabs";22import { cn } from "@/lib/utils";2324type ChangeKind = "added" | "removed" | "modified";25type DiffTab = "schema" | "data";26type DiffValue = boolean | number | string | null;2728interface BranchDiffBranch {29 id: string;30 name: string;31}3233interface SchemaChange {34 id: string;35 kind: ChangeKind;36 objectType: "table" | "column" | "index" | "constraint";37 path: string[];38 before?: string;39 after?: string;40 ddl?: string;41 breaking?: boolean;42}4344interface RowChange {45 id: string;46 kind: ChangeKind;47 primaryKey: Record<string, DiffValue>;48 before?: Record<string, DiffValue>;49 after?: Record<string, DiffValue>;50}5152interface TableDataDiff {53 id: string;54 schema: string;55 table: string;56 primaryKey: string[];57 rows: RowChange[];58 addedCount: number;59 removedCount: number;60 modifiedCount: number;61 unchangedCount?: number;62 hasMore?: boolean;63}6465interface BranchDiffProps {66 from: BranchDiffBranch;67 to: BranchDiffBranch;68 schemaChanges: SchemaChange[];69 dataDiffs: TableDataDiff[];70 tab?: DiffTab;71 defaultTab?: DiffTab;72 onTabChange?: (tab: DiffTab) => void;73 onLoadMore?: (table: TableDataDiff) => void | Promise<void>;74 loadingTableId?: string | null;75 isLoading?: boolean;76 error?: Error | string | null;77 className?: string;78}7980const KIND = {81 added: {82 className: "text-[var(--status-active)]",83 label: "Added",84 surface: "bg-[var(--status-active)]/8",85 symbol: "+",86 },87 modified: {88 className: "text-[var(--status-scaling)]",89 label: "Modified",90 surface: "bg-[var(--status-scaling)]/8",91 symbol: "~",92 },93 removed: {94 className: "text-destructive",95 label: "Removed",96 surface: "bg-destructive/7",97 symbol: "−",98 },99} satisfies Record<ChangeKind, Record<string, string>>;100101const countSchemaKinds = (changes: SchemaChange[]) => ({102 added: changes.filter((change) => change.kind === "added").length,103 modified: changes.filter((change) => change.kind === "modified").length,104 removed: changes.filter((change) => change.kind === "removed").length,105});106107const countDataKinds = (tables: TableDataDiff[]) => {108// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from neon-ui
All 77 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| ActivityFeedactivity-feed | neon-ui | Components | Free | 2 deps | |
| AgentChatagent-chat | neon-ui | Components | Free | 6 deps | |
| AnimatedWashanimated-wash | neon-ui | Components | Free | no deps · 2 files | |
| ApiKeyListapi-key-list | neon-ui | Components | Free | 2 deps | |
| AppCardapp-card | neon-ui | Components | Free | 2 deps | |
| AppCreatorapp-creator | neon-ui | Components | Free | 2 deps | |
| AuthFormauth-form | neon-ui | Components | Free | no deps | |
| AutoscaleChartautoscale-chart | neon-ui | Components | Free | 1 dep |
