11import React , { useState } from 'react'
22import { cn } from '@/lib/utils'
3+ import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'
4+ import { oneDark } from 'react-syntax-highlighter/dist/cjs/styles/prism'
35
46/**
57 * CodeGroup component for displaying multiple code blocks in tabs
@@ -128,6 +130,21 @@ const LANGUAGE_NAMES: { [key: string]: string } = {
128130 http : 'HTTP' ,
129131}
130132
133+ // Custom syntax highlighting theme based on oneDark
134+ const customTheme = {
135+ ...oneDark ,
136+ 'pre[class*="language-"]' : {
137+ ...oneDark [ 'pre[class*="language-"]' ] ,
138+ background : 'transparent' ,
139+ margin : 0 ,
140+ padding : 0 ,
141+ } ,
142+ 'code[class*="language-"]' : {
143+ ...oneDark [ 'code[class*="language-"]' ] ,
144+ background : 'transparent' ,
145+ }
146+ }
147+
131148// Add this function before the CodeGroup component
132149/**
133150 * Preprocesses code content to fix common MDX parsing issues:
@@ -166,42 +183,90 @@ export function CodeGroup({ children, className }: CodeGroupProps) {
166183 // Preprocess the code content
167184 const processedCode = preprocessCode ( code ) ;
168185
169- return React . createElement ( 'div' , {
170- key : `${ index } -${ displayTitle } ` ,
171- className : "font-mono text-sm processed-code-block" ,
172- 'data-type' : 'processed' ,
173- 'data-language' : language ,
174- 'data-title' : displayTitle ,
175- children : processedCode
176- } ) ;
186+ return (
187+ < div key = { `${ index } -${ displayTitle } ` } className = "relative" >
188+ < SyntaxHighlighter
189+ language = { language . toLowerCase ( ) }
190+ style = { customTheme }
191+ showLineNumbers
192+ wrapLines
193+ customStyle = { {
194+ margin : 0 ,
195+ padding : '1rem' ,
196+ background : 'transparent' ,
197+ fontSize : '0.875rem' ,
198+ } }
199+ lineNumberStyle = { {
200+ minWidth : '2.5em' ,
201+ paddingRight : '1em' ,
202+ textAlign : 'right' ,
203+ color : 'rgba(156, 163, 175, 0.5)' ,
204+ userSelect : 'none' ,
205+ } }
206+ codeTagProps = { {
207+ style : {
208+ fontSize : 'inherit' ,
209+ lineHeight : '1.5' ,
210+ }
211+ } }
212+ >
213+ { processedCode }
214+ </ SyntaxHighlighter >
215+ </ div >
216+ ) ;
177217 }
178218 }
179219
180220 // Handle regular JSX components (likely our <Code> component)
181221 if ( React . isValidElement ( child ) ) {
182222 const element = child as React . ReactElement < ElementProps > ;
223+ let language = '' ;
224+ let code = '' ;
183225
184- // If the child has string content, preprocess it
185- if ( typeof element . props . children === 'string' ) {
186- return React . cloneElement ( element , {
187- ... element . props ,
188- children : preprocessCode ( element . props . children )
189- } ) ;
226+ // Extract language from className
227+ if ( element . props . className ) {
228+ const match = String ( element . props . className ) . match ( / l a n g u a g e - ( \w + ) / ) ;
229+ if ( match ) {
230+ language = match [ 1 ] . toLowerCase ( ) ;
231+ }
190232 }
191233
192- // If the child has nested content, process it recursively
193- if ( React . isValidElement ( element . props . children ) ) {
194- const nestedElement = element . props . children as React . ReactElement < ElementProps > ;
195- if ( nestedElement . props ?. children && typeof nestedElement . props . children === 'string' ) {
196- return React . cloneElement ( element , {
197- ...element . props ,
198- children : React . cloneElement ( nestedElement , {
199- ...nestedElement . props ,
200- children : preprocessCode ( nestedElement . props . children )
201- } )
202- } ) ;
203- }
234+ // Extract code content
235+ if ( typeof element . props . children === 'string' ) {
236+ code = preprocessCode ( element . props . children ) ;
204237 }
238+
239+ return (
240+ < div key = { index } className = "relative" >
241+ < SyntaxHighlighter
242+ language = { language || 'text' }
243+ style = { customTheme }
244+ showLineNumbers
245+ wrapLines
246+ customStyle = { {
247+ margin : 0 ,
248+ padding : '1rem' ,
249+ background : 'transparent' ,
250+ fontSize : '0.875rem' ,
251+ } }
252+ lineNumberStyle = { {
253+ minWidth : '2.5em' ,
254+ paddingRight : '1em' ,
255+ textAlign : 'right' ,
256+ color : 'rgba(156, 163, 175, 0.5)' ,
257+ userSelect : 'none' ,
258+ } }
259+ codeTagProps = { {
260+ style : {
261+ fontSize : 'inherit' ,
262+ lineHeight : '1.5' ,
263+ }
264+ } }
265+ >
266+ { code }
267+ </ SyntaxHighlighter >
268+ </ div >
269+ ) ;
205270 }
206271
207272 return child ;
@@ -299,12 +364,13 @@ export function CodeGroup({ children, className }: CodeGroupProps) {
299364
300365 return (
301366 < div className = { cn (
302- "relative my-6 overflow-hidden rounded-3xl border border-gray-200/50 dark:border-gray-800/80" ,
367+ "relative my-6 overflow-hidden rounded-xl border border-gray-200/50 dark:border-gray-800/80" ,
303368 "shadow-sm hover:shadow-md transition-all duration-300 backdrop-blur-sm" ,
369+ "bg-gray-50/50 dark:bg-gray-900/50" ,
304370 className
305371 ) } >
306372 { /* Tabs */ }
307- < div className = "flex overflow-x-auto border-b border-gray-200/50 dark:border-gray-800/80 scrollbar-none" >
373+ < div className = "flex overflow-x-auto border-b border-gray-200/50 dark:border-gray-800/80 bg-white/50 dark:bg-black/50 scrollbar-none" >
308374 { processedChildren . map ( ( child , index ) => {
309375 const { title } = getTabInfo ( child , index ) ;
310376
@@ -315,7 +381,7 @@ export function CodeGroup({ children, className }: CodeGroupProps) {
315381 className = { cn (
316382 'px-5 py-3 text-sm font-medium whitespace-nowrap transition-all duration-200' ,
317383 activeTab === index
318- ? 'border-b-2 border-gray-800 text-gray-900 dark:border-gray-200 dark:text-gray-100 '
384+ ? 'border-b-2 border-primary text-primary bg-primary/5 '
319385 : 'text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-gray-200'
320386 ) }
321387 >
@@ -325,19 +391,51 @@ export function CodeGroup({ children, className }: CodeGroupProps) {
325391 } ) }
326392 </ div >
327393
328- { /* Content - clean minimal style */ }
329- < div className = "relative p-5 font-mono text-sm text-gray-800 dark:text-gray-200" >
394+ { /* Content - modern IDE style */ }
395+ < div className = "relative font-mono text-sm text-gray-800 dark:text-gray-200 bg-gray-50/80 dark:bg-gray-900/80 " >
330396 { processedChildren [ activeTab ] }
331397 < CopyButton value = { getContentToCopy ( ) } />
332398 </ div >
333399 </ div >
334400 )
335401}
336402
337- export function Code ( { title, children, className } : CodeProps ) {
403+ export function Code ( { title, children, className, language } : CodeProps ) {
338404 return (
339- < div className = { cn ( "font-mono text-sm" , className ) } >
340- { children }
405+ < div className = { cn ( "relative" , className ) } >
406+ { title && (
407+ < div className = "px-4 py-2 text-xs font-medium text-gray-600 dark:text-gray-400 border-b border-gray-200/50 dark:border-gray-800/80 bg-white/50 dark:bg-black/50" >
408+ { title }
409+ </ div >
410+ ) }
411+ < SyntaxHighlighter
412+ language = { language || 'text' }
413+ style = { customTheme }
414+ showLineNumbers
415+ wrapLines
416+ customStyle = { {
417+ margin : 0 ,
418+ padding : '1rem' ,
419+ background : 'transparent' ,
420+ fontSize : '0.875rem' ,
421+ } }
422+ lineNumberStyle = { {
423+ minWidth : '2.5em' ,
424+ paddingRight : '1em' ,
425+ textAlign : 'right' ,
426+ color : 'rgba(156, 163, 175, 0.5)' ,
427+ userSelect : 'none' ,
428+ } }
429+ codeTagProps = { {
430+ style : {
431+ fontSize : 'inherit' ,
432+ lineHeight : '1.5' ,
433+ }
434+ } }
435+ >
436+ { typeof children === 'string' ? children : '' }
437+ </ SyntaxHighlighter >
438+ { typeof children === 'string' && < CopyButton value = { children } className = { title ? "top-11" : "" } /> }
341439 </ div >
342440 )
343441}
0 commit comments