This commit is contained in:
Juergen Kunz
2025-06-27 18:38:39 +00:00
parent 56f5f5887b
commit fe3cd0591f
5 changed files with 161 additions and 117 deletions

View File

@ -4,6 +4,7 @@ import { cssManager } from '@design.estate/dees-element';
import { WysiwygSelection } from '../../wysiwyg.selection.js';
import hlight from 'highlight.js';
import { cssGeistFontFamily, cssMonoFontFamily } from '../../../00fonts.js';
import { PROGRAMMING_LANGUAGES } from '../../wysiwyg.constants.js';
/**
* CodeBlockHandler with improved architecture
@ -21,7 +22,7 @@ export class CodeBlockHandler extends BaseBlockHandler {
private highlightTimer: any = null;
render(block: IBlock, isSelected: boolean): string {
const language = block.metadata?.language || 'javascript';
const language = block.metadata?.language || 'typescript';
const content = block.content || '';
const lineCount = content.split('\n').length;
@ -31,10 +32,18 @@ export class CodeBlockHandler extends BaseBlockHandler {
lineNumbersHtml += `<div class="line-number">${i}</div>`;
}
// Generate language options
const languageOptions = PROGRAMMING_LANGUAGES.map(lang => {
const value = lang.toLowerCase();
return `<option value="${value}" ${value === language ? 'selected' : ''}>${lang}</option>`;
}).join('');
return `
<div class="code-block-container${isSelected ? ' selected' : ''}" data-language="${language}">
<div class="code-header">
<span class="language-label">${language}</span>
<select class="language-selector" data-block-id="${block.id}">
${languageOptions}
</select>
<button class="copy-button" title="Copy code">
<svg class="copy-icon" width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path>
@ -61,9 +70,29 @@ export class CodeBlockHandler extends BaseBlockHandler {
const editor = element.querySelector('.code-editor') as HTMLElement;
const container = element.querySelector('.code-block-container') as HTMLElement;
const copyButton = element.querySelector('.copy-button') as HTMLButtonElement;
const languageSelector = element.querySelector('.language-selector') as HTMLSelectElement;
if (!editor || !container) return;
// Setup language selector
if (languageSelector) {
languageSelector.addEventListener('change', (e) => {
const newLanguage = (e.target as HTMLSelectElement).value;
block.metadata = { ...block.metadata, language: newLanguage };
container.setAttribute('data-language', newLanguage);
// Update the syntax highlighting if content exists and not focused
if (block.content && document.activeElement !== editor) {
this.applyHighlighting(element, block);
}
// Notify about the change
if (handlers.onInput) {
handlers.onInput(new InputEvent('input'));
}
});
}
// Setup copy button
if (copyButton) {
copyButton.addEventListener('click', async () => {
@ -286,7 +315,7 @@ export class CodeBlockHandler extends BaseBlockHandler {
// Get plain text content
const content = editor.textContent || '';
const language = block.metadata?.language || 'javascript';
const language = block.metadata?.language || 'typescript';
// Apply highlighting
try {
@ -337,7 +366,7 @@ export class CodeBlockHandler extends BaseBlockHandler {
type: 'code',
content: content,
metadata: {
language: element.querySelector('.code-block-container')?.getAttribute('data-language') || 'javascript'
language: element.querySelector('.code-block-container')?.getAttribute('data-language') || 'typescript'
}
};
this.applyHighlighting(element, block);
@ -441,13 +470,30 @@ export class CodeBlockHandler extends BaseBlockHandler {
align-items: center;
}
.language-label {
.language-selector {
font-size: 12px;
color: ${cssManager.bdTheme('#6b7280', '#9ca3af')};
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.05em;
font-family: ${cssGeistFontFamily};
background: transparent;
border: 1px solid transparent;
border-radius: 4px;
padding: 4px 8px;
cursor: pointer;
transition: all 0.15s ease;
outline: none;
}
.language-selector:hover {
background: ${cssManager.bdTheme('#f9fafb', '#1f2937')};
border-color: ${cssManager.bdTheme('#e5e7eb', '#374151')};
color: ${cssManager.bdTheme('#374151', '#e5e7eb')};
}
.language-selector:focus {
border-color: ${cssManager.bdTheme('#9ca3af', '#6b7280')};
}
/* Copy Button - Minimal */