diff --git a/index.html b/index.html index 42a3630..c84f4e0 100644 --- a/index.html +++ b/index.html @@ -5,6 +5,10 @@ Code Canvas - Create Beautiful Code Images + + + +
diff --git a/src/store/canvasStore.ts b/src/store/canvasStore.ts index fde5d58..8f19c1b 100644 --- a/src/store/canvasStore.ts +++ b/src/store/canvasStore.ts @@ -235,9 +235,15 @@ export const createCodeElement = (x: number, y: number): CodeElement => ({ locked: false, visible: true, props: { - code: '// Your code here\nconsole.log("Hello, World!");', - language: 'javascript', - theme: 'github-dark', + code: `@Composable +fun Greeting(name: String) { + Text( + text = "Hello, $name!", + modifier = Modifier.padding(16.dp) + ) +}`, + language: 'kotlin', + theme: 'dracula', fontFamily: 'JetBrains Mono', fontSize: 14, lineHeight: 1.5, diff --git a/src/types/index.ts b/src/types/index.ts index 63ef467..49d639d 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -125,44 +125,58 @@ export const ASPECT_RATIOS: AspectRatio[] = [ ]; export const CODE_THEMES = [ - { id: 'github-dark', name: 'GitHub Dark', bg: '#0d1117' }, - { id: 'github-light', name: 'GitHub Light', bg: '#ffffff' }, + // IntelliJ / Android Studio themes (prioritized for Kotlin) + { id: 'andromeeda', name: 'Andromeeda', bg: '#23262e' }, + { id: 'aurora-x', name: 'Aurora X', bg: '#07090f' }, + { id: 'dark-plus', name: 'Dark+ (VS Code)', bg: '#1e1e1e' }, { id: 'dracula', name: 'Dracula', bg: '#282a36' }, - { id: 'nord', name: 'Nord', bg: '#2e3440' }, - { id: 'one-dark-pro', name: 'One Dark Pro', bg: '#282c34' }, - { id: 'monokai', name: 'Monokai', bg: '#272822' }, - { id: 'tokyo-night', name: 'Tokyo Night', bg: '#1a1b26' }, - { id: 'vitesse-dark', name: 'Vitesse Dark', bg: '#121212' }, - { id: 'vitesse-light', name: 'Vitesse Light', bg: '#ffffff' }, + { id: 'dracula-soft', name: 'Dracula Soft', bg: '#282a36' }, + { id: 'github-dark', name: 'GitHub Dark', bg: '#0d1117' }, + { id: 'github-dark-dimmed', name: 'GitHub Dimmed', bg: '#22272e' }, + { id: 'github-light', name: 'GitHub Light', bg: '#ffffff' }, + { id: 'light-plus', name: 'Light+ (VS Code)', bg: '#ffffff' }, { id: 'material-theme-darker', name: 'Material Darker', bg: '#212121' }, - { id: 'catppuccin-mocha', name: 'Catppuccin Mocha', bg: '#1e1e2e' }, - { id: 'catppuccin-latte', name: 'Catppuccin Latte', bg: '#eff1f5' }, - { id: 'slack-dark', name: 'Slack Dark', bg: '#222222' }, - { id: 'poimandres', name: 'Poimandres', bg: '#1b1e28' }, - { id: 'night-owl', name: 'Night Owl', bg: '#011627' }, + { id: 'material-theme-ocean', name: 'Material Ocean', bg: '#0f111a' }, + { id: 'material-theme-palenight', name: 'Material Palenight', bg: '#292d3e' }, { id: 'min-dark', name: 'Min Dark', bg: '#1f1f1f' }, { id: 'min-light', name: 'Min Light', bg: '#ffffff' }, - { id: 'ayu-dark', name: 'Ayu Dark', bg: '#0b0e14' }, + { id: 'monokai', name: 'Monokai', bg: '#272822' }, + { id: 'night-owl', name: 'Night Owl', bg: '#011627' }, + { id: 'nord', name: 'Nord', bg: '#2e3440' }, + { id: 'one-dark-pro', name: 'One Dark Pro', bg: '#282c34' }, + { id: 'poimandres', name: 'Poimandres', bg: '#1b1e28' }, + { id: 'rose-pine', name: 'Rosé Pine', bg: '#191724' }, + { id: 'rose-pine-moon', name: 'Rosé Pine Moon', bg: '#232136' }, + { id: 'slack-dark', name: 'Slack Dark', bg: '#222222' }, { id: 'solarized-dark', name: 'Solarized Dark', bg: '#002b36' }, { id: 'solarized-light', name: 'Solarized Light', bg: '#fdf6e3' }, + { id: 'tokyo-night', name: 'Tokyo Night', bg: '#1a1b26' }, + { id: 'vesper', name: 'Vesper', bg: '#101010' }, + { id: 'vitesse-dark', name: 'Vitesse Dark', bg: '#121212' }, + { id: 'vitesse-light', name: 'Vitesse Light', bg: '#ffffff' }, ] as const; export type CodeThemeId = typeof CODE_THEMES[number]['id']; export const LANGUAGES = [ - 'javascript', - 'typescript', 'kotlin', 'java', + 'typescript', + 'javascript', 'python', 'rust', 'go', + 'swift', + 'dart', 'html', 'css', 'json', + 'xml', + 'yaml', 'markdown', 'bash', 'sql', + 'groovy', ] as const; export const FONT_FAMILIES = { diff --git a/src/utils/highlighter.ts b/src/utils/highlighter.ts index 6f8a7f1..8fad2c5 100644 --- a/src/utils/highlighter.ts +++ b/src/utils/highlighter.ts @@ -62,7 +62,7 @@ export function getThemeBackground(themeId: CodeThemeId): string { } export function isLightTheme(themeId: CodeThemeId): boolean { - const lightThemes = ['github-light', 'vitesse-light', 'catppuccin-latte', 'min-light', 'solarized-light']; + const lightThemes = ['github-light', 'vitesse-light', 'min-light', 'solarized-light', 'light-plus']; return lightThemes.includes(themeId); } @@ -81,6 +81,22 @@ export function isHighlighterReady(): boolean { // Language detection based on common patterns export function detectLanguage(code: string): string { + // Kotlin / Jetpack Compose patterns (check first - primary language) + // Look for @Composable, fun, val, var, class, object, companion object, etc. + if (/@Composable|@Preview|@OptIn|@Suppress/.test(code)) { + return 'kotlin'; + } + if (/^(fun|val|var|class|object|package|import|sealed|data\s+class|enum\s+class|interface)\s+/m.test(code)) { + // Check for Kotlin-specific syntax + if (/:\s*\w+(\s*[={()]|$|\s*,)/.test(code) || + /\b(Unit|String|Int|Long|Boolean|Float|Double|List|Map|Set|suspend|inline|crossinline|noinline|reified)\b/.test(code) || + /\bModifier\b|\bColumn\b|\bRow\b|\bBox\b|\bText\b|\bButton\b|\bScaffold\b/.test(code) || + /\.copy\(|\.let\s*\{|\.apply\s*\{|\.also\s*\{|\.run\s*\{/.test(code) || + /\blambda\b|->/.test(code)) { + return 'kotlin'; + } + } + // TypeScript/JavaScript patterns if (/^import\s+.*from\s+['"]|^export\s+(default\s+)?|const\s+\w+:\s*\w+/m.test(code)) { if (/:\s*(string|number|boolean|any|void|Promise|Array)\b/.test(code)) { @@ -89,15 +105,22 @@ export function detectLanguage(code: string): string { return 'javascript'; } - // Kotlin patterns - if (/^(fun|val|var|class|object|package|import)\s+/m.test(code) && - /:\s*\w+(\s*=|\s*\{|\s*\))/.test(code)) { - return 'kotlin'; + // Java patterns (after Kotlin to avoid false positives) + if (/^(public|private|protected)\s+(static\s+)?(class|void|int|String)/m.test(code) && + !/@Composable/.test(code)) { + return 'java'; } - // Java patterns - if (/^(public|private|protected)\s+(static\s+)?(class|void|int|String)/m.test(code)) { - return 'java'; + // Swift patterns + if (/^(func|var|let|class|struct|enum|protocol|import\s+\w+)\s+/m.test(code) && + /@State|@Binding|@Published|@ObservedObject|some\s+View/.test(code)) { + return 'swift'; + } + + // Dart/Flutter patterns + if (/^(class|void|final|const|import\s+')/m.test(code) && + /Widget|StatelessWidget|StatefulWidget|BuildContext|setState/.test(code)) { + return 'dart'; } // Python patterns @@ -115,6 +138,17 @@ export function detectLanguage(code: string): string { return 'go'; } + // Groovy/Gradle patterns + if (/^(plugins|dependencies|android|buildscript)\s*\{/m.test(code) || + /implementation\s*\(|compile\s*\(/.test(code)) { + return 'groovy'; + } + + // XML patterns (for Android layouts) + if (/^<\?xml|^