import { Component, Input, Output, EventEmitter, ViewChild, ElementRef, AfterViewInit, inject } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { Block, CodeProps } from '../../../core/models/block.model'; import { CodeThemeService } from '../../../services/code-theme.service'; @Component({ selector: 'app-code-block', standalone: true, imports: [CommonModule, FormsModule], styleUrls: ['./code-themes.css'], template: `
@if (props.showLineNumbers) {
@for (line of getLineNumbers(); track $index) {
{{ line }}
}
}
` }) export class CodeBlockComponent implements AfterViewInit { @Input({ required: true }) block!: Block; @Output() update = new EventEmitter(); @ViewChild('editable') editable?: ElementRef; readonly codeThemeService = inject(CodeThemeService); get props(): CodeProps { return this.block.props; } ngAfterViewInit(): void { if (this.editable?.nativeElement) { this.editable.nativeElement.textContent = this.props.code || ''; } } onInput(event: Event): void { const target = event.target as HTMLElement; this.update.emit({ ...this.props, code: target.textContent || '' }); } onLangChange(event: Event): void { const target = event.target as HTMLSelectElement; this.update.emit({ ...this.props, lang: target.value }); } getThemeClass(): string { return this.codeThemeService.getThemeClass(this.props.theme); } getLineNumbers(): number[] { if (!this.props.showLineNumbers) return []; const lines = (this.props.code || '').split('\n'); return Array.from({ length: lines.length }, (_, i) => i + 1); } }