feat: add syntax highlighting and code block styling with theme support

This commit is contained in:
2025-10-21 08:34:46 -04:00
parent 062d743481
commit d788c9d267
75 changed files with 4783 additions and 830 deletions
@@ -45,14 +45,14 @@ type SortOption = 'relevance' | 'name' | 'modified';
imports: [CommonModule, FormsModule],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div class="flex flex-col h-full bg-bg-primary dark:bg-gray-900">
<div class="flex flex-col h-full bg-bg-primary dark:bg-main">
<!-- Results header -->
<div class="flex items-center justify-between p-4 border-b border-border dark:border-gray-700">
<div class="flex items-center justify-between p-4 border-b border-border dark:border-border">
<div class="flex items-center gap-3">
<h3 class="text-sm font-semibold text-text-main dark:text-gray-100">
{{ totalResults() }} {{ totalResults() === 1 ? 'result' : 'results' }}
@if (totalMatches() > 0) {
<span class="text-text-muted dark:text-gray-400">
<span class="text-text-muted dark:text-muted">
({{ totalMatches() }} {{ totalMatches() === 1 ? 'match' : 'matches' }})
</span>
}
@@ -61,11 +61,11 @@ type SortOption = 'relevance' | 'name' | 'modified';
<!-- Sort options -->
<div class="flex items-center gap-2">
<label class="text-xs text-text-muted dark:text-gray-400">Sort:</label>
<label class="text-xs text-text-muted dark:text-muted">Sort:</label>
<select
[(ngModel)]="sortBy"
(change)="onSortChange()"
class="text-xs px-2 py-1 rounded border border-border dark:border-gray-600 bg-bg-primary dark:bg-gray-800 text-text-main dark:text-gray-100"
class="text-xs px-2 py-1 rounded border border-border dark:border-border bg-bg-primary dark:bg-card text-text-main dark:text-gray-100"
>
<option value="relevance">Relevance</option>
<option value="name">Name</option>
@@ -77,7 +77,7 @@ type SortOption = 'relevance' | 'name' | 'modified';
<!-- Results list -->
<div class="flex-1 overflow-y-auto">
@if (sortedGroups().length === 0) {
<div class="flex flex-col items-center justify-center h-full text-text-muted dark:text-gray-400 p-8">
<div class="flex flex-col items-center justify-center h-full text-text-muted dark:text-muted p-8">
<svg xmlns="http://www.w3.org/2000/svg" class="h-16 w-16 mb-4 opacity-50" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
@@ -86,7 +86,7 @@ type SortOption = 'relevance' | 'name' | 'modified';
} @else {
<div class="divide-y divide-border dark:divide-gray-700">
@for (group of sortedGroups(); track group.noteId) {
<div class="hover:bg-bg-muted dark:hover:bg-gray-800 transition-colors">
<div class="hover:bg-bg-muted dark:hover:bg-card transition-colors">
<!-- File header -->
<div
class="flex items-center justify-between p-3 cursor-pointer"
@@ -96,7 +96,7 @@ type SortOption = 'relevance' | 'name' | 'modified';
<!-- Expand/collapse icon -->
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-4 w-4 text-text-muted dark:text-gray-400 transition-transform"
class="h-4 w-4 text-text-muted dark:text-muted transition-transform"
[class.rotate-90]="group.isExpanded"
fill="none"
viewBox="0 0 24 24"
@@ -115,7 +115,7 @@ type SortOption = 'relevance' | 'name' | 'modified';
<div class="text-sm font-medium text-text-main dark:text-gray-100 truncate">
{{ group.fileName }}
</div>
<div class="text-xs text-text-muted dark:text-gray-400 truncate">
<div class="text-xs text-text-muted dark:text-muted truncate">
{{ group.filePath }}
</div>
</div>
@@ -143,23 +143,23 @@ type SortOption = 'relevance' | 'name' | 'modified';
<div class="px-3 pb-3 pl-11 space-y-2">
@for (match of group.matches; track $index) {
<div
class="p-2 rounded bg-bg-muted dark:bg-gray-800 hover:bg-bg-secondary dark:hover:bg-gray-700 cursor-pointer transition-colors"
class="p-2 rounded bg-bg-muted dark:bg-card hover:bg-bg-secondary dark:hover:bg-surface2 cursor-pointer transition-colors"
(click)="openNote(group.noteId, $event, match.line)"
>
<!-- Match type badge -->
<div class="flex items-center gap-2 mb-1">
<span class="text-xs px-1.5 py-0.5 rounded bg-bg-primary dark:bg-gray-900 text-text-muted dark:text-gray-400 font-mono">
<span class="text-xs px-1.5 py-0.5 rounded bg-bg-primary dark:bg-main text-text-muted dark:text-muted font-mono">
{{ match.type }}
</span>
@if (match.line) {
<span class="text-xs text-text-muted dark:text-gray-500">
<span class="text-xs text-text-muted dark:text-muted">
Line {{ match.line }}
</span>
}
</div>
<!-- Match context with highlighting -->
<div class="text-sm text-text-main dark:text-gray-200 font-mono leading-relaxed whitespace-pre-wrap">
<div class="text-sm text-text-main dark:text-main font-mono leading-relaxed whitespace-pre-wrap">
<span [innerHTML]="highlightMatch(match)"></span>
</div>
</div>