"use client"; import { useCopyToClipboard } from "../hooks/useCopyToClipboard"; const CODE = `import TUIkit @main struct MyApp: App { var body: some Scene { WindowGroup { VStack { Text("Hello, TUIkit!") .bold() .foregroundColor(.cyan) Button("Press me") { // handle action } } } } }`; /** A Swift code block with copy-to-clipboard and minimal syntax highlighting. */ export default function CodePreview() { const { copied, copy } = useCopyToClipboard(); return (
{/* Header bar */}
MyApp.swift
{/* Code content */}
        
          
        
      
); } /** Syntax highlight color palette — One Dark inspired. */ const HIGHLIGHT = { comment: "#6a737d", decorator: "#d19a66", string: "#98c379", modifier: "#61afef", keyword: "#c678dd", type: "#e5c07b", } as const; /** Minimal Swift syntax highlighter — no external dependency. */ function Highlight({ code }: { code: string }) { const lines = code.split("\n"); return ( <> {lines.map((line, lineIndex) => ( {tokenizeLine(line)} {lineIndex < lines.length - 1 && "\n"} ))} ); } function tokenizeLine(line: string) { // Comments take precedence const commentMatch = line.match(/^(.*?)(\/\/.*)$/); if (commentMatch) { const [, before, comment] = commentMatch; return ( <> {tokenizeSegment(before)} {comment} ); } return tokenizeSegment(line); } function tokenizeSegment(segment: string) { // Build a combined regex for all token types const combined = /(@\w+)|("(?:[^"\\]|\\.)*")|(\.\w+)\(|\b(struct|var|some|func|import|let|return|if|else|for|in|while|switch|case|default|class|protocol|enum|init|self|true|false|nil|private|public|internal)\b|\b(App|Scene|WindowGroup|VStack|HStack|Text|Button|View|String|Int|Bool|Never)\b/g; const parts: React.ReactNode[] = []; let lastIndex = 0; let match: RegExpExecArray | null; // Reset pattern state combined.lastIndex = 0; while ((match = combined.exec(segment)) !== null) { // Add text before match if (match.index > lastIndex) { parts.push(segment.slice(lastIndex, match.index)); } if (match[1]) { // Decorator (@main, @State) parts.push( {match[1]} ); } else if (match[2]) { // String literal parts.push( {match[2]} ); } else if (match[3]) { // Modifier (.bold, .foregroundColor) — add dot+name, then the ( back parts.push( {match[3]} ); parts.push("("); } else if (match[4]) { // Keyword parts.push( {match[4]} ); } else if (match[5]) { // Type parts.push( {match[5]} ); } lastIndex = combined.lastIndex; } // Remaining text if (lastIndex < segment.length) { parts.push(segment.slice(lastIndex)); } return <>{parts}; }