import { Tab, TabGroup, TabList, TabPanel, TabPanels } from '@headlessui/react' import { createJavaScriptRegexEngine } from '@shikijs/engine-javascript' import { createHighlighterCoreSync, hastToHtml } from 'shiki/core' import css from 'shiki/dist/langs/css.mjs' import tsx from 'shiki/dist/langs/tsx.mjs' import ts from 'shiki/dist/langs/typescript.mjs' import theme from 'shiki/dist/themes/github-dark.mjs' import { cn } from '@/utils/cn' import { CopyButton } from './copy-button' // The normal shiki import is async, which we can't use here easily because of SSR complications. // So here we create a synchronous version of the highlighter. const shiki = createHighlighterCoreSync({ themes: [theme], langs: [ts, tsx, css], engine: createJavaScriptRegexEngine(), }) export function CodeFiles({ files, hideTabs, className, }: { files: { name: string; content: any }[] hideCopyButton?: boolean hideTabs?: boolean className?: string }) { return ( {files.map(({ name }, index) => ( {name} ))} {files.map(({ content, name }, index) => { // the typescript grammar has no JSX, so .tsx/.jsx need the tsx grammar const lang = name.endsWith('.css') ? 'css' : name.endsWith('.tsx') || name.endsWith('.jsx') ? 'tsx' : 'ts' const ast = shiki.codeToHast(content, { lang, theme }) const codeElem = (ast.children[0] as any).children[0] return (

							
						
) })}
) }