77}  from  "@shikijs/transformers" ; 
88import  { FileIcon }  from  "lucide-react" ; 
99import  { useTheme }  from  "next-themes" ; 
10- import  { useEffect ,  useState ,  useMemo }  from  "react" ; 
10+ import  React ,  { useEffect ,  useState ,  useMemo }  from  "react" ; 
11+ import  { Badge }  from  "@/components/ui/badge" ; 
1112
1213interface  CodeComparisonProps  { 
1314  beforeCode : string ; 
@@ -16,8 +17,10 @@ interface CodeComparisonProps {
1617  afterLanguage : string ; 
1718  beforeFilename : string ; 
1819  afterFilename : string ; 
19-   lightTheme : string ; 
20-   darkTheme : string ; 
20+   beforeDescription ?: string ; 
21+   afterDescription ?: string ; 
22+   lightTheme ?: string ; 
23+   darkTheme ?: string ; 
2124  highlightColor ?: string ; 
2225} 
2326
@@ -28,28 +31,21 @@ export function CodeComparison({
2831                                 afterLanguage, 
2932                                 beforeFilename, 
3033                                 afterFilename, 
31-                                  lightTheme, 
32-                                  darkTheme, 
34+                                  beforeDescription =  "before" , 
35+                                  afterDescription =  "after" , 
36+                                  lightTheme =  "github-light" , 
37+                                  darkTheme =  "github-dark" , 
3338                                 highlightColor =  "#ff3333" , 
3439                               } : CodeComparisonProps )  { 
3540  const  { theme,  systemTheme}  =  useTheme ( ) ; 
3641  const  [ highlightedBefore ,  setHighlightedBefore ]  =  useState ( "" ) ; 
3742  const  [ highlightedAfter ,  setHighlightedAfter ]  =  useState ( "" ) ; 
38-   const  [ hasLeftFocus ,  setHasLeftFocus ]  =  useState ( false ) ; 
39-   const  [ hasRightFocus ,  setHasRightFocus ]  =  useState ( false ) ; 
4043
4144  const  selectedTheme  =  useMemo ( ( )  =>  { 
4245    const  currentTheme  =  theme  ===  "system"  ? systemTheme  : theme ; 
4346    return  currentTheme  ===  "dark"  ? darkTheme  : lightTheme ; 
4447  } ,  [ theme ,  systemTheme ,  darkTheme ,  lightTheme ] ) ; 
4548
46-   useEffect ( ( )  =>  { 
47-     if  ( highlightedBefore  ||  highlightedAfter )  { 
48-       setHasLeftFocus ( highlightedBefore . includes ( 'class="line focused"' ) ) ; 
49-       setHasRightFocus ( highlightedAfter . includes ( 'class="line focused"' ) ) ; 
50-     } 
51-   } ,  [ highlightedBefore ,  highlightedAfter ] ) ; 
52- 
5349  useEffect ( ( )  =>  { 
5450    async  function  highlightCode ( )  { 
5551      try  { 
@@ -95,15 +91,11 @@ export function CodeComparison({
9591          style = { { "--highlight-color" : highlightColor }  as  React . CSSProperties } 
9692          className = { cn ( 
9793            "h-full w-full overflow-auto bg-background font-mono text-xs" , 
98-             "[&>pre]:h-full [&>pre]:!w-screen [&>pre]: py-2" , 
99-             "[&>pre>code]:!inline-block [&>pre>code]:!w-full " , 
100-             "[&>pre>code>span]:! inline-block [&>pre>code>span]:w-full [&>pre>code>span]: px-4  [&>pre>code>span]:py-0.5" , 
94+             "[&>pre]:h-full [&>pre]:py-2" , 
95+             "[&>pre>code]:!inline-block [&>pre>code]:!flex-col " , 
96+             "[&>pre>code>span]:inline-block [&>pre>code>span]:px-3  [&>pre>code>span]:py-0.5" , 
10197            "[&>pre>code>.highlighted]:inline-block [&>pre>code>.highlighted]:w-full [&>pre>code>.highlighted]:!bg-[var(--highlight-color)]" , 
102-             "group-hover/left:[&>pre>code>:not(.focused)]:!opacity-100 group-hover/left:[&>pre>code>:not(.focused)]:!blur-none" , 
103-             "group-hover/right:[&>pre>code>:not(.focused)]:!opacity-100 group-hover/right:[&>pre>code>:not(.focused)]:!blur-none" , 
10498            "[&>pre>code>.add]:bg-[rgba(16,185,129,.16)] [&>pre>code>.remove]:bg-[rgba(244,63,94,.16)]" , 
105-             "group-hover/left:[&>pre>code>:not(.focused)]:transition-all group-hover/left:[&>pre>code>:not(.focused)]:duration-300" , 
106-             "group-hover/right:[&>pre>code>:not(.focused)]:transition-all group-hover/right:[&>pre>code>:not(.focused)]:duration-300" , 
10799          ) } 
108100          dangerouslySetInnerHTML = { { __html : highlighted } } 
109101        /> 
@@ -119,35 +111,22 @@ export function CodeComparison({
119111
120112  return  ( 
121113    < div  className = "mx-auto w-full max-w-5xl" > 
122-       < div  className = "group relative w-full overflow-hidden rounded-md border border-border" > 
123-         < div  className = "relative grid md:grid-cols-2" > 
124-           < div 
125-             className = { cn ( 
126-               "leftside group/left border-primary/20 md:border-r" , 
127-               hasLeftFocus  && 
128-               "[&>div>pre>code>:not(.focused)]:!opacity-50 [&>div>pre>code>:not(.focused)]:!blur-[0.095rem]" , 
129-               "[&>div>pre>code>:not(.focused)]:transition-all [&>div>pre>code>:not(.focused)]:duration-300" , 
130-             ) } 
131-           > 
132-             < div  className = "flex items-center border-b border-primary/20 bg-accent p-2 text-sm text-foreground" > 
114+       < div  className = "relative w-full overflow-hidden rounded-md border border-border border-primary/20" > 
115+         < div  className = "grid grid-cols-1 md:grid-cols-2" > 
116+           < div  className = "border-primary/20 md:border-r flex flex-col" > 
117+             < div  className = "w-full flex items-center border-b border-primary/20 bg-accent p-2 text-sm text-foreground" > 
133118              < FileIcon  className = "mr-2 h-4 w-4" /> 
134119              { beforeFilename } 
135-               < span  className = "ml-auto hidden md:block"  > before </ span > 
120+               < Badge  className = "ml-auto rounded-full"  > { beforeDescription } </ Badge > 
136121            </ div > 
137122            { renderCode ( beforeCode ,  highlightedBefore ) } 
138123          </ div > 
139-           < div 
140-             className = { cn ( 
141-               "rightside group/right border-t border-primary/20 md:border-t-0" , 
142-               hasRightFocus  && 
143-               "[&>div>pre>code>:not(.focused)]:!opacity-50 [&>div>pre>code>:not(.focused)]:!blur-[0.095rem]" , 
144-               "[&>div>pre>code>:not(.focused)]:transition-all [&>div>pre>code>:not(.focused)]:duration-300" , 
145-             ) } 
146-           > 
147-             < div  className = "flex items-center border-b border-primary/20 bg-accent p-2 text-sm text-foreground" > 
124+ 
125+           < div  className = "border-primary/20 border-t md:border-t-0 flex flex-col" > 
126+             < div  className = "w-full flex items-center border-b border-primary/20 bg-accent p-2 text-sm text-foreground" > 
148127              < FileIcon  className = "mr-2 h-4 w-4" /> 
149128              { afterFilename } 
150-               < span  className = "ml-auto hidden md:block"  > after </ span > 
129+               < Badge  className = "ml-auto rounded-full"  > { afterDescription } </ Badge > 
151130            </ div > 
152131            { renderCode ( afterCode ,  highlightedAfter ) } 
153132          </ div > 
0 commit comments