CodeBlock
tsx
1import CodeBlock from './CodeBlock'23// Simple usage4<CodeBlock code="pnpm add @arctis/ui" lang="bash" />56// With line numbers7<CodeBlock code={sourceCode} lang="tsx" showLineNumbers />
bash
pnpm add prism-react-renderer
Installation
bash
pnpm add prism-react-renderer
Usage
tsx
1import CodeBlock from './CodeBlock'23// Simple usage4<CodeBlock code="pnpm add @arctis/ui" lang="bash" />56// With line numbers7<CodeBlock code={sourceCode} lang="tsx" showLineNumbers />
Code
tsx
1"use client";23import { useState } from "react";4import { Highlight, themes } from "prism-react-renderer";56export type CodeBlockProps = {7 code: string;8 lang?: string;9 showLineNumbers?: boolean;10};1112export function CodeBlock({13 code,14 lang = "tsx",15 showLineNumbers = false,16}: CodeBlockProps) {17 const [copied, setCopied] = useState(false);1819 const copy = async () => {20 await navigator.clipboard.writeText(code);21 setCopied(true);22 setTimeout(() => setCopied(false), 1200);23 };2425 return (26 <div className="relative overflow-hidden rounded border border-white/10 bg-[#050509]">27 {/* Header */}28 <div className="flex items-center justify-between border-b border-white/10 px-3 py-2 text-[11px] text-white/50">29 <div className="flex items-center gap-2">30 <span className="uppercase tracking-wide">{lang || "code"}</span>31 </div>3233 <button34 onClick={copy}35 className="rounded border border-white/20 px-2 py-0.5 text-[10px] hover:border-white/40"36 >37 {copied ? "Copied" : "Copy"}38 </button>39 </div>4041 {/* Body */}42 <Highlight43 theme={themes.okaidia}44 code={code.trimEnd()}45 language={lang as any}46 >47 {({ className, style, tokens, getLineProps, getTokenProps }) => (48 <pre49 className={`${className} overflow-auto p-3 text-xs`}50 style={style}51 >52 {tokens.map((line, i) => {53 // Prism sometimes inserts the last blank line → completely discards the blank line54 const isLastEmptyLine =55 i === tokens.length - 1 &&56 line.length === 1 &&57 line[0]!.content.trim() === "";5859 if (isLastEmptyLine) return null;6061 return (62 <div key={i} {...getLineProps({ line })} className="flex gap-4">63 {showLineNumbers && (64 <span className="select-none opacity-50">{i + 1}</span>65 )}6667 <span className="flex-1">68 {line.map((token, key) => (69 <span key={key} {...getTokenProps({ token })} />70 ))}71 </span>72 </div>73 );74 })}75 </pre>76 )}77 </Highlight>78 </div>79 );80}8182/**83 Arctis UI Component — <CodeBlock>8485 Created with 💛 by Ranaufal Muha86 https://ranaufalmuha.com8788 Hi! Thank you for using this component.89 You’re free to copy, modify, or use it in any project you like.9091 If possible, please keep this small header as appreciation.92 It helps others know where the component came from ❤️9394 Usage:95 import { CodeBlock } from "@arctis/ui";9697 // Simple usage98 <CodeBlock code="pnpm add @arctis/ui" lang="bash" />99100 // With line numbers101 <CodeBlock code={sourceCode} lang="tsx" showLineNumbers />102 */