From eeb957cf1701f275e344dc8b69291e9403ebe331 Mon Sep 17 00:00:00 2001 From: Bruno Charest Date: Tue, 21 Oct 2025 22:32:54 -0400 Subject: [PATCH] refactor: redesign editor buttons and improve scrollbar theming --- src/app.component.css | 44 +--- src/app.component.ts | 2 +- .../editor/markdown-editor.component.ts | 131 +++++++++-- .../note-view/app-toc-overlay.component.ts | 16 +- .../note-header/note-header.component.ts | 1 + .../properties-popover.component.html | 28 ++- .../properties-popover.component.ts | 29 ++- .../state-chip/state-chip.component.html | 4 +- .../state-chip/state-chip.component.ts | 28 ++- .../shared/frontmatter-properties.service.ts | 15 +- .../note/shared/note-properties.model.ts | 2 + .../sidebar/nimbus-sidebar.component.ts | 2 +- .../app-shell-nimbus.component.ts | 41 ++-- .../markdown/markdown-frontmatter.util.ts | 86 +++++++ .../tag-editor-overlay.component.html | 2 +- .../tag-manager/tag-manager.component.html | 25 ++- .../tags/tag-manager/tag-manager.component.ts | 2 + .../note-viewer/note-viewer.component.ts | 86 ++++--- .../tags-view/tags-view.component.ts | 4 +- src/services/vault.service.ts | 26 ++- src/styles.css | 43 +++- src/styles/_overlay-scrollbar.css | 33 ++- src/styles/themes.css | 212 ++++++++++++++++++ vault/.trash/archive/archived-note.md | 6 +- vault/.trash/archive/archived-note.md.bak | 9 +- vault/Nouveau-markdown.md | 3 + vault/Nouveau-markdown.md.bak | 7 +- 27 files changed, 739 insertions(+), 148 deletions(-) diff --git a/src/app.component.css b/src/app.component.css index 62990b6..b575859 100644 --- a/src/app.component.css +++ b/src/app.component.css @@ -14,20 +14,19 @@ } } -:host-context(.dark) ::ng-deep .note-content-area::-webkit-scrollbar-thumb { - background: rgba(148, 163, 184, 0.4); +/* Theme-aware subtle scrollbar for note area */ +:host ::ng-deep .note-content-area { + scrollbar-width: thin; /* Firefox */ + scrollbar-color: color-mix(in oklab, var(--scrollbar-thumb, rgba(148,163,184,0.45)) 80%, transparent) transparent; /* Firefox */ } -:host-context(.dark) ::ng-deep .note-content-area::-webkit-scrollbar-thumb:hover { - background: rgba(148, 163, 184, 0.65); +:host ::ng-deep .note-content-area::-webkit-scrollbar-thumb { + background: color-mix(in oklab, var(--scrollbar-thumb, rgba(148,163,184,0.45)) 80%, transparent); + border-radius: 9999px; } -:not(.dark) ::ng-deep .note-content-area::-webkit-scrollbar-thumb { - background: rgba(100, 116, 139, 0.28); -} - -:not(.dark) ::ng-deep .note-content-area::-webkit-scrollbar-thumb:hover { - background: rgba(100, 116, 139, 0.45); +:host ::ng-deep .note-content-area::-webkit-scrollbar-thumb:hover { + background: color-mix(in oklab, var(--scrollbar-thumb, rgba(148,163,184,0.45)) 95%, transparent); } :host ::ng-deep .md-tag-group { @@ -166,30 +165,7 @@ } } -/* Custom scrollbar for webkit browsers */ -::-webkit-scrollbar { - width: 8px; - height: 8px; -} -::-webkit-scrollbar-track { - background: transparent; -} -.dark ::-webkit-scrollbar-thumb { - background: #3c3d3f; - border-radius: 4px; -} -.dark ::-webkit-scrollbar-thumb:hover { - background: #5c6166; -} - -/* Light mode scrollbar */ -:not(.dark) ::-webkit-scrollbar-thumb { - background: #d8dbe0; - border-radius: 4px; -} -:not(.dark) ::-webkit-scrollbar-thumb:hover { - background: #b8bcc2; -} +/* Global scrollbar rules moved to styles.css for true global scope */ .resize-handle { width: 8px; diff --git a/src/app.component.ts b/src/app.component.ts index 13f41d4..495cb8f 100644 --- a/src/app.component.ts +++ b/src/app.component.ts @@ -555,7 +555,7 @@ export class AppComponent implements OnInit, OnDestroy { const isDesktop = this.isDesktopView(); if (isDesktop && !this.wasDesktop) { this.isSidebarOpen.set(true); - this.isOutlineOpen.set(true); + // Keep existing outline state to avoid forcing it open } if (!isDesktop && this.wasDesktop) { this.isSidebarOpen.set(false); diff --git a/src/app/features/editor/markdown-editor.component.ts b/src/app/features/editor/markdown-editor.component.ts index 588a531..3a669d8 100644 --- a/src/app/features/editor/markdown-editor.component.ts +++ b/src/app/features/editor/markdown-editor.component.ts @@ -54,42 +54,42 @@ import { EditorHighlightService } from '../../shared/editor/editor-highlight.ser @@ -171,7 +171,108 @@ import { EditorHighlightService } from '../../shared/editor/editor-highlight.ser flex-wrap: wrap; } - + .editor-btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 0.45rem; + padding: 0.45rem 0.85rem; + border-radius: 9999px; + font-size: 0.875rem; + font-weight: 600; + letter-spacing: 0.01em; + transition: transform 0.18s ease, box-shadow 0.18s ease, background 0.18s ease, border-color 0.18s ease, color 0.18s ease; + border: 1px solid transparent; + box-shadow: 0 6px 14px -12px color-mix(in oklab, var(--brand) 70%, transparent); + } + + .editor-btn:focus-visible { + outline: none; + box-shadow: 0 0 0 3px color-mix(in oklab, var(--brand) 35%, transparent); + } + + .editor-btn:disabled { + opacity: 0.7; + cursor: not-allowed; + box-shadow: none; + } + + .editor-btn__icon { + width: 16px; + height: 16px; + } + + .editor-btn__label { + white-space: nowrap; + } + + .editor-btn--icon { + padding: 0.4rem; + border-radius: 9999px; + box-shadow: none; + } + + .editor-btn--primary { + color: #0f172a; + background: linear-gradient(135deg, + color-mix(in oklab, var(--brand) 55%, transparent) 0%, + color-mix(in oklab, var(--brand-700) 45%, transparent) 100%); + border-color: color-mix(in oklab, var(--brand-700) 40%, transparent); + } + + .editor-btn--primary:hover:not(:disabled) { + transform: translateY(-1px); + box-shadow: 0 12px 22px -12px color-mix(in oklab, var(--brand) 80%, transparent); + } + + .editor-btn--neutral { + color: inherit; + background: linear-gradient(135deg, + color-mix(in oklab, var(--surface-1, #e5e7eb) 65%, transparent) 0%, + color-mix(in oklab, var(--surface-2, #d1d5db) 55%, transparent) 100%); + border-color: color-mix(in oklab, var(--border, #cbd5e1) 55%, transparent); + box-shadow: none; + } + + .editor-btn--neutral:hover:not(:disabled) { + transform: translateY(-1px); + box-shadow: 0 8px 18px -14px color-mix(in oklab, var(--border, #cbd5e1) 65%, transparent); + } + + .editor-btn--ghost { + color: var(--brand-500, var(--btn-bg)); + background: transparent; + border-color: transparent; + box-shadow: none; + } + + .editor-btn--ghost:hover:not(:disabled) { + background: color-mix(in srgb, var(--brand) 10%, transparent); + } + + :host-context(.dark) .editor-btn--primary { + color: #e2e8f0; + background: linear-gradient(135deg, + color-mix(in oklab, var(--brand-700) 55%, transparent) 0%, + color-mix(in oklab, var(--brand-900, #1e1b4b) 55%, transparent) 100%); + border-color: color-mix(in oklab, var(--brand-700) 45%, transparent); + } + + :host-context(.dark) .editor-btn--neutral { + color: #e2e8f0; + background: linear-gradient(135deg, + color-mix(in oklab, var(--card, #111827) 65%, transparent) 0%, + color-mix(in oklab, var(--surface2, #0b1220) 55%, transparent) 100%); + border-color: color-mix(in oklab, var(--border, #334155) 60%, transparent); + } + + :host-context(.dark) .editor-btn--ghost { + color: color-mix(in oklab, var(--brand-200, #c7d2fe) 75%, #93c5fd 25%); + } + + .editor-btn--ghost.editor-btn--icon:hover:not(:disabled) { + transform: translateY(-1px); + } .markdown-editor__container { flex: 1; diff --git a/src/app/features/note-view/app-toc-overlay.component.ts b/src/app/features/note-view/app-toc-overlay.component.ts index f125847..0772bff 100644 --- a/src/app/features/note-view/app-toc-overlay.component.ts +++ b/src/app/features/note-view/app-toc-overlay.component.ts @@ -30,8 +30,20 @@ import { ScrollableOverlayDirective } from '../../shared/overlay-scrollbar/scrol aria-modal="true" (click)="$event.stopPropagation()"> -
-
+
+
+
+
+
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 385f357..49686f2 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 @@ -168,6 +168,7 @@ export class NoteHeaderComponent implements AfterViewInit, OnDestroy { const note = this.vaultService.getNoteById(this.noteId); const props = this.frontmatterService.get(note); compRef.instance.props = props; + compRef.instance.noteId = this.noteId; compRef.instance.requestClose.subscribe(() => this.scheduleClose()); compRef.instance.cancelClose.subscribe(() => clearTimeout(this.closeTimer)); diff --git a/src/app/features/note/components/properties-popover/properties-popover.component.html b/src/app/features/note/components/properties-popover/properties-popover.component.html index fc1c820..5577e60 100644 --- a/src/app/features/note/components/properties-popover/properties-popover.component.html +++ b/src/app/features/note/components/properties-popover/properties-popover.component.html @@ -1,11 +1,12 @@