diff --git a/src/app.component.css b/src/app.component.css index 03b80b4..62990b6 100644 --- a/src/app.component.css +++ b/src/app.component.css @@ -83,31 +83,31 @@ display: inline; } -:host ::ng-deep .md-tag-palette-0 { background: rgba(190, 242, 100, 0.35); color: #3f6212; } -:host ::ng-deep .md-tag-palette-1 { background: rgba(129, 230, 217, 0.35); color: #0f766e; } -:host ::ng-deep .md-tag-palette-2 { background: rgba(196, 181, 253, 0.35); color: #6b21a8; } -:host ::ng-deep .md-tag-palette-3 { background: rgba(248, 196, 113, 0.35); color: #b45309; } -:host ::ng-deep .md-tag-palette-4 { background: rgba(248, 113, 113, 0.35); color: #b91c1c; } -:host ::ng-deep .md-tag-palette-5 { background: rgba(129, 140, 248, 0.35); color: #4338ca; } -:host ::ng-deep .md-tag-palette-6 { background: rgba(233, 213, 255, 0.35); color: #7e22ce; } -:host ::ng-deep .md-tag-palette-7 { background: rgba(209, 250, 229, 0.35); color: #047857; } -:host ::ng-deep .md-tag-palette-8 { background: rgba(165, 180, 252, 0.35); color: #1d4ed8; } -:host ::ng-deep .md-tag-palette-9 { background: rgba(253, 224, 71, 0.35); color: #92400e; } -:host ::ng-deep .md-tag-palette-10 { background: rgba(244, 114, 182, 0.35); color: #be185d; } -:host ::ng-deep .md-tag-palette-11 { background: rgba(148, 163, 184, 0.35); color: #1f2937; } +:host ::ng-deep .md-tag-color-0 { background: rgba(190, 242, 100, 0.35); color: #3f6212; } +:host ::ng-deep .md-tag-color-1 { background: rgba(129, 230, 217, 0.35); color: #0f766e; } +:host ::ng-deep .md-tag-color-2 { background: rgba(196, 181, 253, 0.35); color: #6b21a8; } +:host ::ng-deep .md-tag-color-3 { background: rgba(248, 196, 113, 0.35); color: #b45309; } +:host ::ng-deep .md-tag-color-4 { background: rgba(248, 113, 113, 0.35); color: #b91c1c; } +:host ::ng-deep .md-tag-color-5 { background: rgba(129, 140, 248, 0.35); color: #4338ca; } +:host ::ng-deep .md-tag-color-6 { background: rgba(233, 213, 255, 0.35); color: #7e22ce; } +:host ::ng-deep .md-tag-color-7 { background: rgba(209, 250, 229, 0.35); color: #047857; } +:host ::ng-deep .md-tag-color-8 { background: rgba(165, 180, 252, 0.35); color: #1d4ed8; } +:host ::ng-deep .md-tag-color-9 { background: rgba(253, 224, 71, 0.35); color: #92400e; } +:host ::ng-deep .md-tag-color-10 { background: rgba(244, 114, 182, 0.35); color: #be185d; } +:host ::ng-deep .md-tag-color-11 { background: rgba(148, 163, 184, 0.35); color: #1f2937; } -:host-context(.dark) ::ng-deep .md-tag-palette-0 { background: rgba(132, 204, 22, 0.35); color: #d9f99d; } -:host-context(.dark) ::ng-deep .md-tag-palette-1 { background: rgba(45, 212, 191, 0.3); color: #d1fae5; } -:host-context(.dark) ::ng-deep .md-tag-palette-2 { background: rgba(168, 85, 247, 0.28); color: #ede9fe; } -:host-context(.dark) ::ng-deep .md-tag-palette-3 { background: rgba(245, 158, 11, 0.28); color: #fde68a; } -:host-context(.dark) ::ng-deep .md-tag-palette-4 { background: rgba(248, 113, 113, 0.3); color: #fee2e2; } -:host-context(.dark) ::ng-deep .md-tag-palette-5 { background: rgba(99, 102, 241, 0.3); color: #e0e7ff; } -:host-context(.dark) ::ng-deep .md-tag-palette-6 { background: rgba(217, 70, 239, 0.28); color: #f5d0fe; } -:host-context(.dark) ::ng-deep .md-tag-palette-7 { background: rgba(34, 197, 94, 0.3); color: #bbf7d0; } -:host-context(.dark) ::ng-deep .md-tag-palette-8 { background: rgba(59, 130, 246, 0.28); color: #bfdbfe; } -:host-context(.dark) ::ng-deep .md-tag-palette-9 { background: rgba(250, 204, 21, 0.28); color: #fef08a; } -:host-context(.dark) ::ng-deep .md-tag-palette-10 { background: rgba(236, 72, 153, 0.3); color: #fbcfe8; } -:host-context(.dark) ::ng-deep .md-tag-palette-11 { background: rgba(107, 114, 128, 0.3); color: #cbd5f5; } +:host-context(.dark) ::ng-deep .md-tag-color-0 { background: rgba(132, 204, 22, 0.35); color: #d9f99d; } +:host-context(.dark) ::ng-deep .md-tag-color-1 { background: rgba(45, 212, 191, 0.3); color: #d1fae5; } +:host-context(.dark) ::ng-deep .md-tag-color-2 { background: rgba(168, 85, 247, 0.28); color: #ede9fe; } +:host-context(.dark) ::ng-deep .md-tag-color-3 { background: rgba(245, 158, 11, 0.28); color: #fde68a; } +:host-context(.dark) ::ng-deep .md-tag-color-4 { background: rgba(248, 113, 113, 0.3); color: #fee2e2; } +:host-context(.dark) ::ng-deep .md-tag-color-5 { background: rgba(99, 102, 241, 0.3); color: #e0e7ff; } +:host-context(.dark) ::ng-deep .md-tag-color-6 { background: rgba(217, 70, 239, 0.28); color: #f5d0fe; } +:host-context(.dark) ::ng-deep .md-tag-color-7 { background: rgba(34, 197, 94, 0.3); color: #bbf7d0; } +:host-context(.dark) ::ng-deep .md-tag-color-8 { background: rgba(59, 130, 246, 0.28); color: #bfdbfe; } +:host-context(.dark) ::ng-deep .md-tag-color-9 { background: rgba(250, 204, 21, 0.28); color: #fef08a; } +:host-context(.dark) ::ng-deep .md-tag-color-10 { background: rgba(236, 72, 153, 0.3); color: #fbcfe8; } +:host-context(.dark) ::ng-deep .md-tag-color-11 { background: rgba(107, 114, 128, 0.3); color: #cbd5f5; } :host ::ng-deep .metadata-panel__item .md-tag-badge { cursor: default; diff --git a/src/app/features/note/components/note-header/note-header.component.html b/src/app/features/note/components/note-header/note-header.component.html index a5140fc..4f7c8a1 100644 --- a/src/app/features/note/components/note-header/note-header.component.html +++ b/src/app/features/note/components/note-header/note-header.component.html @@ -45,5 +45,6 @@ [noteId]="noteId" [tags]="tags" (saved)="tagsChange.emit($event)" + (tagSelected)="tagSelected.emit($event)" > diff --git a/src/app/features/note/components/note-header/note-header.component.ts b/src/app/features/note/components/note-header/note-header.component.ts index 63f1430..385f357 100644 --- a/src/app/features/note/components/note-header/note-header.component.ts +++ b/src/app/features/note/components/note-header/note-header.component.ts @@ -24,6 +24,7 @@ export class NoteHeaderComponent implements AfterViewInit, OnDestroy { @Output() openDirectory = new EventEmitter(); @Output() copyRequested = new EventEmitter(); @Output() tagsChange = new EventEmitter(); + @Output() tagSelected = new EventEmitter(); pathParts: { prefix: string; filename: string } = { prefix: '', filename: '' }; diff --git a/src/app/features/parameters/parameters.page.css b/src/app/features/parameters/parameters.page.css index b2ea652..5d5fc6d 100644 --- a/src/app/features/parameters/parameters.page.css +++ b/src/app/features/parameters/parameters.page.css @@ -92,30 +92,21 @@ .mode-button { display: inline-flex; align-items: center; - gap: 0.5rem; - padding: 0.625rem 1rem; - background: var(--bg-muted); - border: 1.5px solid var(--border); - border-radius: 0.5rem; - color: var(--text-main); - font-size: 0.875rem; - font-weight: 500; - cursor: pointer; - transition: all var(--transition-base); - min-width: 6.5rem; + gap: 0.45rem; justify-content: center; + min-width: 6.5rem; + cursor: pointer; + border: none; + background: transparent; + color: inherit; + padding: 0; + font-size: 0.85rem; + font-weight: 500; + text-decoration: none; } -.mode-button:hover { - background: var(--bg-main); - border-color: var(--primary); - transform: translateY(-1px); -} - -.mode-button.active { - background: var(--primary); - border-color: var(--primary); - color: white; +.mode-button:focus-visible { + outline: none; } .button-icon { @@ -126,6 +117,66 @@ flex-shrink: 0; } +/* Colored shadows small buttons (shared look with tag manager) */ +.btn-colored-xs { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 0.35rem; + padding: 0.35rem 0.6rem; + border-radius: 9999px; + font-size: 0.75rem; + font-weight: 600; + letter-spacing: 0.02em; + color: #0f172a; + background: linear-gradient(135deg, + color-mix(in oklab, var(--brand) 18%, transparent) 0%, + color-mix(in oklab, var(--brand) 8%, transparent) 100%); + box-shadow: 0 6px 14px -10px color-mix(in oklab, var(--brand) 65%, transparent); + border: 1px solid color-mix(in oklab, var(--brand) 22%, transparent); + transition: transform 0.15s ease, box-shadow 0.2s ease, background 0.2s ease, border-color 0.2s ease; +} + +.btn-colored-xs:hover, +.btn-colored-xs:focus-visible { + transform: translateY(-1px); + box-shadow: 0 10px 18px -10px color-mix(in oklab, var(--brand) 75%, transparent); + border-color: color-mix(in oklab, var(--brand) 35%, transparent); +} + +:host-context(.dark) .btn-colored-xs { + color: #e2e8f0; + background: linear-gradient(135deg, + color-mix(in oklab, var(--brand-700) 22%, transparent) 0%, + color-mix(in oklab, var(--brand-700) 12%, transparent) 100%); + box-shadow: 0 10px 22px -14px color-mix(in oklab, var(--brand-700) 85%, transparent); + border-color: color-mix(in oklab, var(--brand-700) 30%, transparent); +} + +.btn-primary { + color: white; + background: linear-gradient(135deg, + color-mix(in oklab, var(--brand) 60%, transparent) 0%, + color-mix(in oklab, var(--brand-700) 60%, transparent) 100%); + border-color: color-mix(in oklab, var(--brand-700) 50%, transparent); +} + +.btn-neutral { + color: inherit; + background: linear-gradient(135deg, + color-mix(in oklab, var(--surface-1, #e5e7eb) 60%, transparent) 0%, + color-mix(in oklab, var(--surface-2, #d1d5db) 60%, transparent) 100%); + border-color: color-mix(in oklab, var(--border, #cbd5e1) 60%, transparent); +} + +:host-context(.dark) .btn-neutral { + color: #e2e8f0; + background: linear-gradient(135deg, + color-mix(in oklab, var(--card, #111827) 60%, transparent) 0%, + color-mix(in oklab, var(--surface2, #0b1220) 60%, transparent) 100%); + border-color: color-mix(in oklab, var(--border, #334155) 60%, transparent); +} + /* Theme Grid */ .theme-grid { display: grid; diff --git a/src/app/features/parameters/parameters.page.html b/src/app/features/parameters/parameters.page.html index cf010bd..4729d4a 100644 --- a/src/app/features/parameters/parameters.page.html +++ b/src/app/features/parameters/parameters.page.html @@ -31,8 +31,9 @@ diff --git a/src/app/graph/ui/settings-panel.component.ts b/src/app/graph/ui/settings-panel.component.ts index 61c9195..8c97826 100644 --- a/src/app/graph/ui/settings-panel.component.ts +++ b/src/app/graph/ui/settings-panel.component.ts @@ -24,7 +24,7 @@ import { GraphSettingsAccordionComponent } from '../../../components/graph-setti -
-
- @for (t of working(); track t) { - - {{ t }} - - - } - -
- -
-
- @if (suggestions().length === 0) { -
Aucune suggestion
- } @else { -
    - @for (s of suggestions(); track s) { -
  • - -
  • - } -
+
+ +
+
+ + @for (L of letters; track L) { + } + +
+ +
+ @for (t of working(); track t) { + + {{ t }} + + + } + +
+ + +
+ @if (suggestions().length === 0) { +
Aucune suggestion
+ } @else { +
+ @for (s of suggestions(); track s) { + + } +
+ } +
+ +
- - + +
diff --git a/src/app/shared/tags/tag-editor-overlay/tag-editor-overlay.component.ts b/src/app/shared/tags/tag-editor-overlay/tag-editor-overlay.component.ts index 9de88f7..2f37087 100644 --- a/src/app/shared/tags/tag-editor-overlay/tag-editor-overlay.component.ts +++ b/src/app/shared/tags/tag-editor-overlay/tag-editor-overlay.component.ts @@ -28,10 +28,28 @@ export class TagEditorOverlayComponent { working = signal([]); count = computed(() => this.working().length); + private readonly tagPaletteSize = 12; + private readonly tagColorCache = new Map(); + + // Alphabet filter state: 'all' | 'other' | '#', or 'a'..'z' + letter = signal('all'); + readonly letters = Array.from('ABCDEFGHIJKLMNOPQRSTUVWXYZ'); + ngOnInit() { this.working.set(uniqueTags(this.value || [])); } + tagColorClass(tag: string): string { + if (!tag) return ''; + const normalized = `${tag}`.toLowerCase(); + if (this.tagColorCache.has(normalized)) return `md-tag-color-${this.tagColorCache.get(normalized)}`; + let hash = 0; + for (let i = 0; i < normalized.length; i++) hash = (hash * 31 + normalized.charCodeAt(i)) >>> 0; + const colorIndex = hash % this.tagPaletteSize; + this.tagColorCache.set(normalized, colorIndex); + return `md-tag-color-${colorIndex}`; + } + private allKnownTags = computed(() => { const provided = this.allTags || []; if (provided.length > 0) return provided; @@ -44,10 +62,21 @@ export class TagEditorOverlayComponent { suggestions = computed(() => { const q = this.inputValue().trim().toLowerCase(); + const selected = this.letter(); const source = this.allKnownTags(); - const pool = q ? source.filter(t => t.toLowerCase().includes(q)) : source; + + const matchesLetter = (t: string) => { + if (selected === 'all') return true; + const first = (t?.[0] || '').toUpperCase(); + if (selected === '#') return /[0-9]/.test(first); + if (selected === 'other') return !/[A-Z0-9]/.test(first); + return first === selected.toUpperCase(); + }; + + const byLetter = source.filter(matchesLetter); + const byQuery = q ? byLetter.filter(t => t.toLowerCase().includes(q)) : byLetter; const exist = new Set(this.working().map(t => t.toLowerCase())); - return pool.filter(t => !exist.has(t.toLowerCase())).slice(0, 50); + return byQuery.filter(t => !exist.has(t.toLowerCase())).slice(0, 100); }); onKeydown(ev: KeyboardEvent) { diff --git a/src/app/shared/tags/tag-manager/tag-manager.component.html b/src/app/shared/tags/tag-manager/tag-manager.component.html index d89b4e1..4908bda 100644 --- a/src/app/shared/tags/tag-manager/tag-manager.component.html +++ b/src/app/shared/tags/tag-manager/tag-manager.component.html @@ -12,9 +12,11 @@
diff --git a/src/app/shared/tags/tag-manager/tag-manager.component.ts b/src/app/shared/tags/tag-manager/tag-manager.component.ts index ddcf996..020fae2 100644 --- a/src/app/shared/tags/tag-manager/tag-manager.component.ts +++ b/src/app/shared/tags/tag-manager/tag-manager.component.ts @@ -32,6 +32,20 @@ export class TagManagerComponent { isEditing = signal(false); readonly normalizedTags = computed(() => uniqueTags(this.tagsSignal())); + private readonly tagPaletteSize = 12; + private readonly tagColorCache = new Map(); + + tagColorClass(tag: string): string { + if (!tag) return ''; + const normalized = `${tag}`.toLowerCase(); + if (this.tagColorCache.has(normalized)) return `md-tag-color-${this.tagColorCache.get(normalized)}`; + let hash = 0; + for (let i = 0; i < normalized.length; i++) hash = (hash * 31 + normalized.charCodeAt(i)) >>> 0; + const colorIndex = hash % this.tagPaletteSize; + this.tagColorCache.set(normalized, colorIndex); + return `md-tag-color-${colorIndex}`; + } + toggleEditor(): void { const next = !this.isEditing(); this.isEditing.set(next); diff --git a/src/components/tags-view/note-viewer/note-viewer.component.ts b/src/components/tags-view/note-viewer/note-viewer.component.ts index dbafd6f..c78b187 100644 --- a/src/components/tags-view/note-viewer/note-viewer.component.ts +++ b/src/components/tags-view/note-viewer/note-viewer.component.ts @@ -59,6 +59,7 @@ export interface WikiLinkActivation { (copyRequested)="copyPath()" (openDirectory)="directoryClicked.emit(getDirectoryFromPath(note().filePath))" (tagsChange)="onTagsChange($event)" + (tagSelected)="tagClicked.emit($event)" >
@@ -116,15 +117,15 @@ export interface WikiLinkActivation { ⋯ @if (menuOpen()) { -
- - +
}
diff --git a/src/services/markdown.service.ts b/src/services/markdown.service.ts index aad7ab1..0a33516 100644 --- a/src/services/markdown.service.ts +++ b/src/services/markdown.service.ts @@ -126,7 +126,9 @@ export class MarkdownService { if (this.canUseFastPath(markdown)) { const env: MarkdownRenderEnv = { codeBlockIndex: 0 }; this.activeSlugState = new Map(); - return this.md.render(markdown, env); + // Even on fast path, decorate inline #tags so they render as clickable badges + const decoratedFast = this.decorateInlineTags(markdown); + return this.md.render(decoratedFast, env); } const env: MarkdownRenderEnv = { codeBlockIndex: 0 }; diff --git a/vault/.trash/archive/archived-note.md b/vault/.trash/archive/archived-note.md index 054c5f4..19a8cc8 100644 --- a/vault/.trash/archive/archived-note.md +++ b/vault/.trash/archive/archived-note.md @@ -4,7 +4,10 @@ auteur: Bruno Charest creation_date: 2025-10-19T11:13:12-04:00 modification_date: 2025-10-19T12:09:46-04:00 catégorie: "" -tags: [] +tags: + - configuration + - test + - tag3 aliases: [] status: en-cours publish: false @@ -17,4 +20,7 @@ private: false --- # Archived Note +#bruno + + This note was archived and moved to trash. diff --git a/vault/.trash/archive/archived-note.md.bak b/vault/.trash/archive/archived-note.md.bak index 054c5f4..cff1a95 100644 --- a/vault/.trash/archive/archived-note.md.bak +++ b/vault/.trash/archive/archived-note.md.bak @@ -4,7 +4,10 @@ auteur: Bruno Charest creation_date: 2025-10-19T11:13:12-04:00 modification_date: 2025-10-19T12:09:46-04:00 catégorie: "" -tags: [] +tags: + - configuration + - test + - tag3 aliases: [] status: en-cours publish: false