CodeBlockTabs.tsx42 lines · main
| 1 | 'use client' |
| 2 | |
| 3 | import { useState } from 'react' |
| 4 | import { cn } from 'ui' |
| 5 | |
| 6 | interface CodeBlockTabsProps { |
| 7 | files: { filename: string; darkHtml: string; lightHtml: string }[] |
| 8 | } |
| 9 | |
| 10 | export default function CodeBlockTabs({ files }: CodeBlockTabsProps) { |
| 11 | const [activeIndex, setActiveIndex] = useState(0) |
| 12 | |
| 13 | return ( |
| 14 | <> |
| 15 | <div className="flex border-b border-muted bg-surface-200/50"> |
| 16 | {files.map((file, i) => ( |
| 17 | <button |
| 18 | key={file.filename} |
| 19 | type="button" |
| 20 | onClick={() => setActiveIndex(i)} |
| 21 | className={cn( |
| 22 | 'px-5 py-3 text-xs font-mono transition-colors', |
| 23 | i === activeIndex |
| 24 | ? 'text-foreground border-b border-foreground -mb-px' |
| 25 | : 'text-foreground-lighter hover:text-foreground-light' |
| 26 | )} |
| 27 | > |
| 28 | {file.filename} |
| 29 | </button> |
| 30 | ))} |
| 31 | </div> |
| 32 | <div |
| 33 | className="hidden dark:block px-5 py-4 sm:px-6 sm:py-5 overflow-x-auto text-[13px] leading-[1.6] [&_pre]:bg-transparent! [&_pre]:m-0! [&_code]:font-mono" |
| 34 | dangerouslySetInnerHTML={{ __html: files[activeIndex].darkHtml }} |
| 35 | /> |
| 36 | <div |
| 37 | className="block dark:hidden px-5 py-4 sm:px-6 sm:py-5 overflow-x-auto text-[13px] leading-[1.6] [&_pre]:bg-transparent! [&_pre]:m-0! [&_code]:font-mono" |
| 38 | dangerouslySetInnerHTML={{ __html: files[activeIndex].lightHtml }} |
| 39 | /> |
| 40 | </> |
| 41 | ) |
| 42 | } |