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
@@ -38,12 +38,12 @@ export interface GraphOptions {
imports: [CommonModule, FormsModule, SearchInputWithAssistantComponent],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div class="graph-options-panel bg-white dark:bg-gray-800 border-l border-gray-200 dark:border-gray-700 h-full overflow-y-auto">
<div class="graph-options-panel bg-card dark:bg-card border-l border-border dark:border-border h-full overflow-y-auto">
<div class="p-4 space-y-6">
<!-- Filters Section -->
<section>
<h3 class="text-sm font-semibold text-gray-900 dark:text-gray-100 mb-3 flex items-center gap-2">
<h3 class="text-sm font-semibold text-main dark:text-gray-100 mb-3 flex items-center gap-2">
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z" />
</svg>
@@ -56,8 +56,8 @@ export interface GraphOptions {
type="checkbox"
[(ngModel)]="filters().showTags"
(change)="emitOptionsChange()"
class="rounded border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700">
<span class="text-sm text-gray-700 dark:text-gray-300 group-hover:text-gray-900 dark:group-hover:text-gray-100">Tags</span>
class="rounded border-border text-blue-600 focus:ring-ring dark:border-border dark:bg-surface2">
<span class="text-sm text-main dark:text-main group-hover:text-main dark:group-hover:text-gray-100">Tags</span>
</label>
<label class="flex items-center gap-2 cursor-pointer group">
@@ -65,8 +65,8 @@ export interface GraphOptions {
type="checkbox"
[(ngModel)]="filters().showAttachments"
(change)="emitOptionsChange()"
class="rounded border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700">
<span class="text-sm text-gray-700 dark:text-gray-300 group-hover:text-gray-900 dark:group-hover:text-gray-100">Attachments</span>
class="rounded border-border text-blue-600 focus:ring-ring dark:border-border dark:bg-surface2">
<span class="text-sm text-main dark:text-main group-hover:text-main dark:group-hover:text-gray-100">Attachments</span>
</label>
<label class="flex items-center gap-2 cursor-pointer group">
@@ -74,8 +74,8 @@ export interface GraphOptions {
type="checkbox"
[(ngModel)]="filters().existingFilesOnly"
(change)="emitOptionsChange()"
class="rounded border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700">
<span class="text-sm text-gray-700 dark:text-gray-300 group-hover:text-gray-900 dark:group-hover:text-gray-100">Existing files only</span>
class="rounded border-border text-blue-600 focus:ring-ring dark:border-border dark:bg-surface2">
<span class="text-sm text-main dark:text-main group-hover:text-main dark:group-hover:text-gray-100">Existing files only</span>
</label>
<label class="flex items-center gap-2 cursor-pointer group">
@@ -83,8 +83,8 @@ export interface GraphOptions {
type="checkbox"
[(ngModel)]="filters().showOrphans"
(change)="emitOptionsChange()"
class="rounded border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700">
<span class="text-sm text-gray-700 dark:text-gray-300 group-hover:text-gray-900 dark:group-hover:text-gray-100">Orphans</span>
class="rounded border-border text-blue-600 focus:ring-ring dark:border-border dark:bg-surface2">
<span class="text-sm text-main dark:text-main group-hover:text-main dark:group-hover:text-gray-100">Orphans</span>
</label>
</div>
@@ -96,14 +96,14 @@ export interface GraphOptions {
[placeholder]="'Search files…'"
[context]="'graph'"
[showSearchIcon]="true"
[inputClass]="'w-full px-3 py-2 text-sm border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 placeholder-gray-500 dark:placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500'"
[inputClass]="'w-full px-3 py-2 text-sm border border-border dark:border-border rounded-md bg-card dark:bg-surface2 text-main dark:text-gray-100 placeholder-gray-500 dark:placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-ring'"
/>
</div>
</section>
<!-- Groups Section -->
<section>
<h3 class="text-sm font-semibold text-gray-900 dark:text-gray-100 mb-3 flex items-center gap-2">
<h3 class="text-sm font-semibold text-main dark:text-gray-100 mb-3 flex items-center gap-2">
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" />
</svg>
@@ -112,7 +112,7 @@ export interface GraphOptions {
<div class="space-y-2 mb-3">
@for (group of colorGroups(); track $index) {
<div class="flex items-center gap-2 p-2 bg-gray-50 dark:bg-gray-700/50 rounded-lg">
<div class="flex items-center gap-2 p-2 bg-surface1 dark:bg-surface2/50 rounded-lg">
<div
[style.background-color]="getGroupColorPreview(group)"
class="w-6 h-6 rounded-full border-2 border-white dark:border-gray-800 shadow-sm flex-shrink-0">
@@ -122,11 +122,11 @@ export interface GraphOptions {
[value]="group.query"
(input)="updateGroupQuery($index, $any($event.target).value)"
placeholder="Query (e.g., tag:#code)"
class="flex-1 px-2 py-1 text-xs bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded"
class="flex-1 px-2 py-1 text-xs bg-card dark:bg-card border border-border dark:border-border rounded"
/>
<button
(click)="removeGroup($index)"
class="p-1 text-gray-400 hover:text-red-500 transition-colors"
class="p-1 text-muted hover:text-red-500 transition-colors"
title="Remove group"
>
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
@@ -147,7 +147,7 @@ export interface GraphOptions {
<!-- Display Section -->
<section>
<h3 class="text-sm font-semibold text-gray-900 dark:text-gray-100 mb-3 flex items-center gap-2">
<h3 class="text-sm font-semibold text-main dark:text-gray-100 mb-3 flex items-center gap-2">
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
@@ -161,12 +161,12 @@ export interface GraphOptions {
type="checkbox"
[(ngModel)]="display().showArrows"
(change)="emitOptionsChange()"
class="rounded border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700">
<span class="text-sm text-gray-700 dark:text-gray-300 group-hover:text-gray-900 dark:group-hover:text-gray-100">Arrows</span>
class="rounded border-border text-blue-600 focus:ring-blue-500 dark:border-border dark:bg-surface2">
<span class="text-sm text-main dark:text-main group-hover:text-main dark:group-hover:text-gray-100">Arrows</span>
</label>
<div>
<label class="flex items-center justify-between text-sm text-gray-700 dark:text-gray-300 mb-1">
<label class="flex items-center justify-between text-sm text-main dark:text-main mb-1">
<span>Text fade threshold</span>
<span class="font-mono text-xs">{{ display().textFadeThreshold }}</span>
</label>
@@ -176,11 +176,11 @@ export interface GraphOptions {
max="100"
[(ngModel)]="display().textFadeThreshold"
(input)="emitOptionsChange()"
class="w-full h-2 bg-gray-200 dark:bg-gray-700 rounded-lg appearance-none cursor-pointer accent-blue-600">
class="w-full h-2 bg-surface2 dark:bg-surface2 rounded-lg appearance-none cursor-pointer accent-blue-600">
</div>
<div>
<label class="flex items-center justify-between text-sm text-gray-700 dark:text-gray-300 mb-1">
<label class="flex items-center justify-between text-sm text-main dark:text-main mb-1">
<span>Node size</span>
<span class="font-mono text-xs">{{ display().nodeSize }}</span>
</label>
@@ -190,11 +190,11 @@ export interface GraphOptions {
max="20"
[(ngModel)]="display().nodeSize"
(input)="emitOptionsChange()"
class="w-full h-2 bg-gray-200 dark:bg-gray-700 rounded-lg appearance-none cursor-pointer accent-blue-600">
class="w-full h-2 bg-surface2 dark:bg-surface2 rounded-lg appearance-none cursor-pointer accent-blue-600">
</div>
<div>
<label class="flex items-center justify-between text-sm text-gray-700 dark:text-gray-300 mb-1">
<label class="flex items-center justify-between text-sm text-main dark:text-main mb-1">
<span>Link thickness</span>
<span class="font-mono text-xs">{{ display().linkThickness }}</span>
</label>
@@ -204,7 +204,7 @@ export interface GraphOptions {
max="10"
[(ngModel)]="display().linkThickness"
(input)="emitOptionsChange()"
class="w-full h-2 bg-gray-200 dark:bg-gray-700 rounded-lg appearance-none cursor-pointer accent-blue-600">
class="w-full h-2 bg-surface2 dark:bg-surface2 rounded-lg appearance-none cursor-pointer accent-blue-600">
</div>
</div>
@@ -221,7 +221,7 @@ export interface GraphOptions {
<button
type="button"
(click)="forcesExpanded.set(!forcesExpanded())"
class="w-full flex items-center justify-between text-sm font-semibold text-gray-900 dark:text-gray-100 mb-3">
class="w-full flex items-center justify-between text-sm font-semibold text-main dark:text-gray-100 mb-3">
<span class="flex items-center gap-2">
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" />
@@ -242,7 +242,7 @@ export interface GraphOptions {
@if (forcesExpanded()) {
<div class="space-y-4">
<div>
<label class="flex items-center justify-between text-sm text-gray-700 dark:text-gray-300 mb-1">
<label class="flex items-center justify-between text-sm text-main dark:text-main mb-1">
<span>Charge</span>
<span class="font-mono text-xs">{{ forces().chargeStrength }}</span>
</label>
@@ -252,11 +252,11 @@ export interface GraphOptions {
max="0"
[(ngModel)]="forces().chargeStrength"
(input)="emitOptionsChange()"
class="w-full h-2 bg-gray-200 dark:bg-gray-700 rounded-lg appearance-none cursor-pointer accent-blue-600">
class="w-full h-2 bg-surface2 dark:bg-surface2 rounded-lg appearance-none cursor-pointer accent-blue-600">
</div>
<div>
<label class="flex items-center justify-between text-sm text-gray-700 dark:text-gray-300 mb-1">
<label class="flex items-center justify-between text-sm text-main dark:text-main mb-1">
<span>Link distance</span>
<span class="font-mono text-xs">{{ forces().linkDistance }}</span>
</label>
@@ -266,11 +266,11 @@ export interface GraphOptions {
max="500"
[(ngModel)]="forces().linkDistance"
(input)="emitOptionsChange()"
class="w-full h-2 bg-gray-200 dark:bg-gray-700 rounded-lg appearance-none cursor-pointer accent-blue-600">
class="w-full h-2 bg-surface2 dark:bg-surface2 rounded-lg appearance-none cursor-pointer accent-blue-600">
</div>
<div>
<label class="flex items-center justify-between text-sm text-gray-700 dark:text-gray-300 mb-1">
<label class="flex items-center justify-between text-sm text-main dark:text-main mb-1">
<span>Center strength</span>
<span class="font-mono text-xs">{{ forces().centerStrength.toFixed(2) }}</span>
</label>
@@ -281,7 +281,7 @@ export interface GraphOptions {
step="0.01"
[(ngModel)]="forces().centerStrength"
(input)="emitOptionsChange()"
class="w-full h-2 bg-gray-200 dark:bg-gray-700 rounded-lg appearance-none cursor-pointer accent-blue-600">
class="w-full h-2 bg-surface2 dark:bg-surface2 rounded-lg appearance-none cursor-pointer accent-blue-600">
</div>
</div>
}