a programming education platform
www.hypercommit.com
education
1"use client"
2
3import { useRef } from "react"
4import { cn } from "@workspace/ui/lib/utils"
5import { CodeBlockHeader, CopyCodeButton } from "./code-block-header"
6
7export function CodeBlock({
8 children,
9 filename,
10}: {
11 children: React.ReactNode
12 filename?: string
13}) {
14 const ref = useRef<HTMLDivElement>(null)
15 const getCode = () => ref.current?.querySelector("pre")?.textContent ?? ""
16
17 if (filename) {
18 return (
19 <div className="rounded-lg border border-border/70 bg-muted/70 p-1 pt-0">
20 <CodeBlockHeader filename={filename} getCode={getCode} />
21 <div
22 ref={ref}
23 className={cn(
24 "grid",
25 "[&>pre]:overflow-auto [&>pre]:rounded-md [&>pre]:border [&>pre]:border-border/70 [&>pre]:bg-card [&>pre]:p-4 [&>pre]:text-sm [&>pre]:leading-[1.6] [&>pre]:shadow-2xs/2 dark:[&>pre]:border-border/80",
26 "[&_code]:bg-transparent [&_code]:p-0 [&_code]:border-0"
27 )}
28 >
29 {children}
30 </div>
31 </div>
32 )
33 }
34
35 return (
36 <div
37 ref={ref}
38 className={cn(
39 "group relative grid",
40 "[&>pre]:overflow-auto [&>pre]:rounded-lg [&>pre]:border [&>pre]:border-border/70 [&>pre]:bg-card [&>pre]:p-4 [&>pre]:text-sm [&>pre]:leading-[1.6] [&>pre]:shadow-2xs/2 dark:[&>pre]:border-border/80",
41 "[&_code]:bg-transparent [&_code]:p-0 [&_code]:border-0"
42 )}
43 >
44 {children}
45 <CopyCodeButton
46 getCode={getCode}
47 className="absolute top-1.5 right-1.5 opacity-0 transition-opacity group-hover:opacity-100 focus-visible:opacity-100"
48 />
49 </div>
50 )
51}