From e7d6658c7a1303496d7a3e8f9659e7851410b139 Mon Sep 17 00:00:00 2001 From: misch334 <259832695+misch334@users.noreply.github.com> Date: Tue, 10 Feb 2026 17:34:00 +0100 Subject: [PATCH 001/116] add generic launch.json for debugging/dap --- .vscode/launch.json | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000..2573a8e852 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,38 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Launch server", + "type": "node", + "request": "launch", + "program": "${workspaceFolder}/apps/server/src/main.ts", + "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/tsx", + "env": { + "NODE_ENV": "development", + "TRILIUM_ENV": "dev", + "TRILIUM_DATA_DIR": "${input:trilium_data_dir}", + "TRILIUM_RESOURCE_DIR": "${workspaceFolder}/apps/server/src" + }, + "cwd": "${workspaceFolder}", + "skipFiles": ["/**", "${workspaceFolder}/node_modules/**"] + }, + { + "name": "Launch vitest", + "type": "node", + "request": "launch", + "program": "${file}", + "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/vitest", + "runtimeArgs": ["--inspectBrk", "--no-file-parallelism", "run"], + "cwd": "${workspaceFolder}", + "skipFiles": ["/**", "${workspaceFolder}/node_modules/**"] + } + ], + "inputs": [ + { + "id": "trilium_data_dir", + "type": "promptString", + "description": "Select Trilum Notes data directory", + "default": "${workspaceFolder}/apps/server/data" + } + ] +} From ef6c733f93fae2abfbdfed45e15c9c64ca5ddc5b Mon Sep 17 00:00:00 2001 From: misch334 <259832695+misch334@users.noreply.github.com> Date: Tue, 10 Feb 2026 18:15:51 +0100 Subject: [PATCH 002/116] add options recommended by tsx.is docs --- .vscode/launch.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.vscode/launch.json b/.vscode/launch.json index 2573a8e852..953428cdb0 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -14,6 +14,8 @@ "TRILIUM_RESOURCE_DIR": "${workspaceFolder}/apps/server/src" }, "cwd": "${workspaceFolder}", + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen", "skipFiles": ["/**", "${workspaceFolder}/node_modules/**"] }, { From 5c007cdebc3a1ac0f41605c31a72ec5f84fb658a Mon Sep 17 00:00:00 2001 From: misch334 <259832695+misch334@users.noreply.github.com> Date: Tue, 10 Feb 2026 18:45:56 +0100 Subject: [PATCH 003/116] adjust vi launch.json to be based on vitest.dev/guide/debugging --- .vscode/launch.json | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 953428cdb0..a45f8602fc 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -19,14 +19,16 @@ "skipFiles": ["/**", "${workspaceFolder}/node_modules/**"] }, { - "name": "Launch vitest", + "name": "Launch Vitest with current test file", "type": "node", "request": "launch", - "program": "${file}", - "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/vitest", - "runtimeArgs": ["--inspectBrk", "--no-file-parallelism", "run"], - "cwd": "${workspaceFolder}", - "skipFiles": ["/**", "${workspaceFolder}/node_modules/**"] + "autoAttachChildProcesses": true, + "program": "${workspaceFolder}/node_modules/vitest/vitest.mjs", + "args": ["run", "${relativeFile}"], + "smartStep": true, + "console": "integratedTerminal", + "skipFiles": ["/**", "**/node_modules/**"], + "cwd": "${workspaceFolder}" } ], "inputs": [ From fd8ab990bdaa39d3522d4273899aa81223598de5 Mon Sep 17 00:00:00 2001 From: misch334 <259832695+misch334@users.noreply.github.com> Date: Wed, 11 Feb 2026 07:25:58 +0100 Subject: [PATCH 004/116] add autoAttachChildProcesses to launch server config --- .vscode/launch.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.vscode/launch.json b/.vscode/launch.json index a45f8602fc..6aee4ca1af 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -13,6 +13,7 @@ "TRILIUM_DATA_DIR": "${input:trilium_data_dir}", "TRILIUM_RESOURCE_DIR": "${workspaceFolder}/apps/server/src" }, + "autoAttachChildProcesses": true, "cwd": "${workspaceFolder}", "console": "integratedTerminal", "internalConsoleOptions": "neverOpen", From 4c36a9cca93cb7dfb3f51fb090aadcbd6de38cc7 Mon Sep 17 00:00:00 2001 From: misch334 <259832695+misch334@users.noreply.github.com> Date: Thu, 12 Feb 2026 16:11:21 +0100 Subject: [PATCH 005/116] add client and compound launch entry --- .vscode/launch.json | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/.vscode/launch.json b/.vscode/launch.json index 6aee4ca1af..e69744775a 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,6 +1,14 @@ { "version": "0.2.0", "configurations": [ + { + "name": "Launch client (Chrome)", + "request": "launch", + "type": "chrome", + "url": "http://localhost:8080", + "webRoot": "${workspaceFolder}/apps/client", + "runtimeExecutable": "${input:pick_chrome_browser}" + }, { "name": "Launch server", "type": "node", @@ -32,12 +40,26 @@ "cwd": "${workspaceFolder}" } ], + "compounds": [ + { + "name": "Launch client (Chrome) and server", + "configurations": ["Launch server","Launch client (Chrome)"], + "stopAll": true + } + ], "inputs": [ { "id": "trilium_data_dir", "type": "promptString", "description": "Select Trilum Notes data directory", "default": "${workspaceFolder}/apps/server/data" + }, + { + "id": "pick_chrome_browser", + "type": "pickString", + "description": "Select a Chrome browser", + "options": ["/usr/bin/chromium-browser", "/usr/bin/google-chrome"], + "default": "/usr/bin/chromium-browser" } ] } From 516f0052efcd7f87cd3f66d1e1df50fe257ae964 Mon Sep 17 00:00:00 2001 From: Adorian Doran Date: Tue, 17 Feb 2026 20:36:01 +0200 Subject: [PATCH 006/116] ui/grid view: use flex gap instead of margins for cards --- apps/client/src/stylesheets/theme-next/base.css | 1 - apps/client/src/widgets/collections/legacy/ListOrGridView.css | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/client/src/stylesheets/theme-next/base.css b/apps/client/src/stylesheets/theme-next/base.css index 9e39b2f002..f7d65c765f 100644 --- a/apps/client/src/stylesheets/theme-next/base.css +++ b/apps/client/src/stylesheets/theme-next/base.css @@ -655,7 +655,6 @@ li.dropdown-item a.dropdown-item-button:focus-visible { border-radius: 12px; user-select: none; padding: 0; - margin: 5px 10px 5px 0; } :root .note-list .note-book-card:hover { diff --git a/apps/client/src/widgets/collections/legacy/ListOrGridView.css b/apps/client/src/widgets/collections/legacy/ListOrGridView.css index 222682cc9f..adc6c8b2b3 100644 --- a/apps/client/src/widgets/collections/legacy/ListOrGridView.css +++ b/apps/client/src/widgets/collections/legacy/ListOrGridView.css @@ -8,7 +8,6 @@ border-radius: 10px; background-color: var(--accented-background-color); padding: 10px 15px 15px 8px; - margin: 5px 5px 5px 5px; overflow: hidden; display: flex; flex-direction: column; @@ -304,6 +303,7 @@ .note-list.grid-view .note-list-container { display: flex; flex-wrap: wrap; + gap: 10px; } .note-list.grid-view .note-book-card { From 297cbbd8b311711a7ada830de0f4e9b6341efcc5 Mon Sep 17 00:00:00 2001 From: Adorian Doran Date: Wed, 18 Feb 2026 09:15:38 +0200 Subject: [PATCH 007/116] ui/grid view: reuse some styles from list view --- .../collections/legacy/ListOrGridView.css | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/apps/client/src/widgets/collections/legacy/ListOrGridView.css b/apps/client/src/widgets/collections/legacy/ListOrGridView.css index adc6c8b2b3..6b55c0fade 100644 --- a/apps/client/src/widgets/collections/legacy/ListOrGridView.css +++ b/apps/client/src/widgets/collections/legacy/ListOrGridView.css @@ -99,6 +99,28 @@ overflow: auto; } +.nested-note-list-item, +.note-book-card { + h5 { + display: flex; + align-items: center; + font-size: 1em; + font-weight: normal; + margin: 0; + } + + .tn-icon { + font-size: 1.2em; + } + + .note-book-title { + --link-hover-background: transparent; + --link-hover-color: currentColor; + color: inherit; + font-weight: normal; + } +} + /* #region List view */ @keyframes note-preview-show { @@ -119,13 +141,6 @@ /* List item */ .nested-note-list-item { - h5 { - display: flex; - align-items: center; - font-size: 1em; - font-weight: normal; - margin: 0; - } .note-expander { margin-inline-end: 4px; @@ -136,14 +151,6 @@ .tn-icon { margin-inline-end: 8px; color: var(--note-list-view-icon-color); - font-size: 1.2em; - } - - .note-book-title { - --link-hover-background: transparent; - --link-hover-color: currentColor; - color: inherit; - font-weight: normal; } .note-path { From 5036518458fdfd3c63dce41305ae06fe487a0b4c Mon Sep 17 00:00:00 2001 From: Adorian Doran Date: Wed, 18 Feb 2026 09:20:00 +0200 Subject: [PATCH 008/116] ui/grid view: hide attributes --- apps/client/src/widgets/collections/legacy/ListOrGridView.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/client/src/widgets/collections/legacy/ListOrGridView.tsx b/apps/client/src/widgets/collections/legacy/ListOrGridView.tsx index cdde8a6087..866ec56537 100644 --- a/apps/client/src/widgets/collections/legacy/ListOrGridView.tsx +++ b/apps/client/src/widgets/collections/legacy/ListOrGridView.tsx @@ -163,7 +163,6 @@ function GridNoteCard({ note, parentNote, highlightedTokens, includeArchived }:
-
Date: Wed, 18 Feb 2026 09:31:03 +0200 Subject: [PATCH 009/116] ui/grid view: refactor --- .../collections/legacy/ListOrGridView.tsx | 42 ++++++++++++------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/apps/client/src/widgets/collections/legacy/ListOrGridView.tsx b/apps/client/src/widgets/collections/legacy/ListOrGridView.tsx index 866ec56537..2d34681666 100644 --- a/apps/client/src/widgets/collections/legacy/ListOrGridView.tsx +++ b/apps/client/src/widgets/collections/legacy/ListOrGridView.tsx @@ -148,27 +148,37 @@ function ListNoteCard({ note, parentNote, highlightedTokens, currentLevel, expan ); } -function GridNoteCard({ note, parentNote, highlightedTokens, includeArchived }: { note: FNote, parentNote: FNote, highlightedTokens: string[] | null | undefined, includeArchived: boolean }) { - const titleRef = useRef(null); - const [ noteTitle, setNoteTitle ] = useState(); - const notePath = getNotePath(parentNote, note); +interface GridNoteCardProps { + note: FNote; + parentNote: FNote; + highlightedTokens: string[] | null | undefined; + includeArchived: boolean +} + +function GridNoteCard(props: GridNoteCardProps) { + const notePath = getNotePath(props.parentNote, props.note); return ( -
link.goToLink(e)} +
link.goToLink(e)} >
- - + +
-
); From e006550b9f50d7832af3d20b653ac3b318cb775d Mon Sep 17 00:00:00 2001 From: Adorian Doran Date: Wed, 18 Feb 2026 09:51:18 +0200 Subject: [PATCH 010/116] ui/grid view: add a menu button for grid items --- .../collections/legacy/ListOrGridView.css | 21 +++++++++++---- .../collections/legacy/ListOrGridView.tsx | 27 +++++++++++-------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/apps/client/src/widgets/collections/legacy/ListOrGridView.css b/apps/client/src/widgets/collections/legacy/ListOrGridView.css index 6b55c0fade..3fac974358 100644 --- a/apps/client/src/widgets/collections/legacy/ListOrGridView.css +++ b/apps/client/src/widgets/collections/legacy/ListOrGridView.css @@ -119,6 +119,11 @@ color: inherit; font-weight: normal; } + + .note-book-item-menu { + margin-inline-start: 8px; + flex-shrink: 0; + } } /* #region List view */ @@ -167,11 +172,6 @@ opacity: .75; } - .nested-note-list-item-menu { - margin-inline-start: 8px; - flex-shrink: 0; - } - &.archived { span.tn-icon + span, .tn-icon { @@ -307,6 +307,17 @@ /* #endregion */ /* #region Grid view */ + +.note-book-card { + h5 { + + .tn-icon + span { + flex-grow: 1; + } + } + +} + .note-list.grid-view .note-list-container { display: flex; flex-wrap: wrap; diff --git a/apps/client/src/widgets/collections/legacy/ListOrGridView.tsx b/apps/client/src/widgets/collections/legacy/ListOrGridView.tsx index 2d34681666..8534b8d564 100644 --- a/apps/client/src/widgets/collections/legacy/ListOrGridView.tsx +++ b/apps/client/src/widgets/collections/legacy/ListOrGridView.tsx @@ -1,7 +1,7 @@ import "./ListOrGridView.css"; import { Card, CardSection } from "../../react/Card"; -import { useEffect, useRef, useState } from "preact/hooks"; +import { useCallback, useEffect, useRef, useState } from "preact/hooks"; import FNote from "../../../entities/fnote"; import attribute_renderer from "../../../services/attribute_renderer"; @@ -139,10 +139,7 @@ function ListNoteCard({ note, parentNote, highlightedTokens, currentLevel, expan showNotePath={parentNote.type === "search"} highlightedTokens={highlightedTokens} /> - openNoteMenu(notePath, e)} - /> + ); @@ -174,6 +171,7 @@ function GridNoteCard(props: GridNoteCardProps) { showNotePath={props.parentNote.type === "search"} highlightedTokens={props.highlightedTokens} /> + ); } +function NoteMenuButton(props: {notePath: string}) { + const openMenu = useCallback((e: TargetedMouseEvent) => { + linkContextMenuService.openContextMenu(props.notePath, e); + e.stopPropagation() + }, [props.notePath]); + + return +} + function getNotePath(parentNote: FNote, childNote: FNote) { if (parentNote.type === "search") { // for search note parent, we want to display a non-search path @@ -282,9 +292,4 @@ function useExpansionDepth(note: FNote) { } return parseInt(expandDepth, 10); -} - -function openNoteMenu(notePath, e: TargetedMouseEvent) { - linkContextMenuService.openContextMenu(notePath, e); - e.stopPropagation() -} +} \ No newline at end of file From 75c7d55e016b157eb19d362cd39c066c55b963bc Mon Sep 17 00:00:00 2001 From: Adorian Doran Date: Wed, 18 Feb 2026 10:08:50 +0200 Subject: [PATCH 011/116] ui/grid view: tweak style --- .../src/stylesheets/theme-next/base.css | 28 ------------------- .../collections/legacy/ListOrGridView.css | 8 +++++- 2 files changed, 7 insertions(+), 29 deletions(-) diff --git a/apps/client/src/stylesheets/theme-next/base.css b/apps/client/src/stylesheets/theme-next/base.css index f7d65c765f..995e796d73 100644 --- a/apps/client/src/stylesheets/theme-next/base.css +++ b/apps/client/src/stylesheets/theme-next/base.css @@ -678,34 +678,6 @@ li.dropdown-item a.dropdown-item-button:focus-visible { color: inherit !important; } -.note-list-wrapper .note-book-card .note-book-header { - font-size: 1em; - font-weight: bold; - padding: 0.5em 1rem; - border-bottom-color: var(--card-border-color); -} - -.note-list-wrapper .note-book-card .note-book-header .note-icon { - font-size: 17px; - vertical-align: text-bottom; -} - -.note-list-wrapper .note-book-card .note-book-header .note-book-title { - font-size: 1em; - color: var(--active-item-text-color); - vertical-align: middle; -} - -.note-list-wrapper .note-book-card .note-book-header .rendered-note-attributes { - font-size: 0.7em; - font-weight: normal; - margin-bottom: 0; -} - -.note-list-wrapper .note-book-card .note-book-header:last-child { - border-bottom: 0; -} - .note-list-wrapper .note-book-card .note-book-content { padding: 0 !important; font-size: 0.8rem; diff --git a/apps/client/src/widgets/collections/legacy/ListOrGridView.css b/apps/client/src/widgets/collections/legacy/ListOrGridView.css index 3fac974358..3e151d79bf 100644 --- a/apps/client/src/widgets/collections/legacy/ListOrGridView.css +++ b/apps/client/src/widgets/collections/legacy/ListOrGridView.css @@ -309,10 +309,16 @@ /* #region Grid view */ .note-book-card { - h5 { + .note-book-header { + padding: .5em 1em; + padding-inline-end: 8px; + border-bottom-color: var(--card-border-color); .tn-icon + span { flex-grow: 1; + a { + font-weight: 500; + } } } From 419e87b0de1d92c74e9b21575355ad495b14ff7e Mon Sep 17 00:00:00 2001 From: Adorian Doran Date: Wed, 18 Feb 2026 10:29:41 +0200 Subject: [PATCH 012/116] ui/grid view: add support for colored notes --- apps/client/src/stylesheets/theme-next-dark.css | 3 ++- apps/client/src/stylesheets/theme-next-light.css | 3 ++- apps/client/src/stylesheets/theme-next/base.css | 4 ---- .../collections/legacy/ListOrGridView.css | 16 ++++++++-------- .../collections/legacy/ListOrGridView.tsx | 2 +- 5 files changed, 13 insertions(+), 15 deletions(-) diff --git a/apps/client/src/stylesheets/theme-next-dark.css b/apps/client/src/stylesheets/theme-next-dark.css index dfdc209040..ab86bcc4bd 100644 --- a/apps/client/src/stylesheets/theme-next-dark.css +++ b/apps/client/src/stylesheets/theme-next-dark.css @@ -314,7 +314,8 @@ */ #left-pane .fancytree-node.tinted, -.nested-note-list-item.use-note-color { +.nested-note-list-item.use-note-color, +.note-book-card.use-note-color { --custom-color: var(--dark-theme-custom-color); /* The background color of the active item in the note tree. diff --git a/apps/client/src/stylesheets/theme-next-light.css b/apps/client/src/stylesheets/theme-next-light.css index 4b6b37718c..ead60aa992 100644 --- a/apps/client/src/stylesheets/theme-next-light.css +++ b/apps/client/src/stylesheets/theme-next-light.css @@ -308,7 +308,8 @@ } #left-pane .fancytree-node.tinted, -.nested-note-list-item.use-note-color { +.nested-note-list-item.use-note-color, +.note-book-card.use-note-color { --custom-color: var(--light-theme-custom-color); /* The background color of the active item in the note tree. diff --git a/apps/client/src/stylesheets/theme-next/base.css b/apps/client/src/stylesheets/theme-next/base.css index 995e796d73..6a0ea97e53 100644 --- a/apps/client/src/stylesheets/theme-next/base.css +++ b/apps/client/src/stylesheets/theme-next/base.css @@ -727,10 +727,6 @@ li.dropdown-item a.dropdown-item-button:focus-visible { margin-bottom: 0; } -.note-list-wrapper .note-book-card .tn-icon { - color: var(--left-pane-icon-color) !important; -} - .note-list.grid-view .note-book-card:hover { filter: contrast(105%); } diff --git a/apps/client/src/widgets/collections/legacy/ListOrGridView.css b/apps/client/src/widgets/collections/legacy/ListOrGridView.css index 3e151d79bf..93af378501 100644 --- a/apps/client/src/widgets/collections/legacy/ListOrGridView.css +++ b/apps/client/src/widgets/collections/legacy/ListOrGridView.css @@ -124,6 +124,14 @@ margin-inline-start: 8px; flex-shrink: 0; } + + &.use-note-color { + span.tn-icon + span, + .tn-icon, + .rendered-note-attributes { + color: var(--custom-color); + } + } } /* #region List view */ @@ -178,14 +186,6 @@ opacity: .6; } } - - &.use-note-color { - span.tn-icon + span, - .nested-note-list:not(.search-results) & .tn-icon, - .rendered-note-attributes { - color: var(--custom-color); - } - } } .nested-note-list:not(.search-results) h5 { diff --git a/apps/client/src/widgets/collections/legacy/ListOrGridView.tsx b/apps/client/src/widgets/collections/legacy/ListOrGridView.tsx index 8534b8d564..dec8934043 100644 --- a/apps/client/src/widgets/collections/legacy/ListOrGridView.tsx +++ b/apps/client/src/widgets/collections/legacy/ListOrGridView.tsx @@ -156,7 +156,7 @@ function GridNoteCard(props: GridNoteCardProps) { const notePath = getNotePath(props.parentNote, props.note); return ( -
Date: Thu, 19 Feb 2026 19:14:01 +0200 Subject: [PATCH 013/116] ui/grid view: add support for search view --- .../src/stylesheets/theme-next-dark.css | 3 +- .../src/stylesheets/theme-next-light.css | 3 +- .../collections/legacy/ListOrGridView.css | 108 +++++++++--------- .../collections/legacy/ListOrGridView.tsx | 2 +- 4 files changed, 58 insertions(+), 58 deletions(-) diff --git a/apps/client/src/stylesheets/theme-next-dark.css b/apps/client/src/stylesheets/theme-next-dark.css index ab86bcc4bd..94f6254d25 100644 --- a/apps/client/src/stylesheets/theme-next-dark.css +++ b/apps/client/src/stylesheets/theme-next-dark.css @@ -366,7 +366,8 @@ body .todo-list input[type="checkbox"]:not(:checked):before { .note-split.with-hue, .quick-edit-dialog-wrapper.with-hue, -.nested-note-list-item.with-hue { +.nested-note-list-item.with-hue, +.note-book-card.with-hue { --note-icon-custom-background-color: hsl(var(--custom-color-hue), 15.8%, 30.9%); --note-icon-custom-color: hsl(var(--custom-color-hue), 100%, 76.5%); --note-icon-hover-custom-background-color: hsl(var(--custom-color-hue), 28.3%, 36.7%); diff --git a/apps/client/src/stylesheets/theme-next-light.css b/apps/client/src/stylesheets/theme-next-light.css index ead60aa992..a4d3eced8a 100644 --- a/apps/client/src/stylesheets/theme-next-light.css +++ b/apps/client/src/stylesheets/theme-next-light.css @@ -336,7 +336,8 @@ .note-split.with-hue, .quick-edit-dialog-wrapper.with-hue, -.nested-note-list-item.with-hue { +.nested-note-list-item.with-hue, +.note-book-card.with-hue { --note-icon-custom-background-color: hsl(var(--custom-color-hue), 44.5%, 43.1%); --note-icon-custom-color: hsl(var(--custom-color-hue), 91.3%, 91%); --note-icon-hover-custom-background-color: hsl(var(--custom-color-hue), 55.1%, 50.2%); diff --git a/apps/client/src/widgets/collections/legacy/ListOrGridView.css b/apps/client/src/widgets/collections/legacy/ListOrGridView.css index 93af378501..cf0187ab89 100644 --- a/apps/client/src/widgets/collections/legacy/ListOrGridView.css +++ b/apps/client/src/widgets/collections/legacy/ListOrGridView.css @@ -57,13 +57,6 @@ content: "\00a0\00a0"; } -.note-book-header .note-icon { - font-size: 100%; - display: inline-block; - padding-inline-end: 7px; - position: relative; -} - .note-book-card .note-book-card { border: 1px solid var(--main-border-color); } @@ -134,6 +127,59 @@ } } +/* Search result view */ +.nested-note-list.search-results .nested-note-list-item, +.note-list-container.search-results .note-book-card .note-book-header { + span.tn-icon + span > span { + display: flex; + flex-direction: column-reverse; + align-items: flex-start; + } + + small { + line-height: .85em; + } + + .note-path { + margin-left: 0; + font-size: .85em; + line-height: .85em; + font-weight: 500; + letter-spacing: .5pt; + } + + .tn-icon { + display: flex; + flex-shrink: 0; + justify-content: center; + align-items: center; + width: 1.75em; + height: 1.75em; + margin-inline-end: 12px; + border-radius: 50%; + background: var(--note-icon-custom-background-color, var(--note-list-view-large-icon-background)); + font-size: 1.2em; + color: var(--note-icon-custom-color, var(--note-list-view-large-icon-color)); + } + + .ck-find-result { + background: var(--note-list-view-search-result-highlight-background); + color: var(--note-list-view-search-result-highlight-color); + font-weight: 600; + text-decoration: underline; + } +} + +.nested-note-list .note-book-content, +.note-list-container .note-book-content { + .ck-find-result { + outline: 2px solid var(--note-list-view-content-search-result-highlight-background); + border-radius: 4px; + background: var(--note-list-view-content-search-result-highlight-background); + color: var(--note-list-view-content-search-result-highlight-color); + } +} + /* #region List view */ @keyframes note-preview-show { @@ -197,47 +243,6 @@ } } -/* List item (search results view) */ -.nested-note-list.search-results .nested-note-list-item { - span.tn-icon + span > span { - display: flex; - flex-direction: column-reverse; - align-items: flex-start; - } - - small { - line-height: .85em; - } - - .note-path { - margin-left: 0; - font-size: .85em; - line-height: .85em; - font-weight: 500; - letter-spacing: .5pt; - } - - .tn-icon { - display: flex; - flex-shrink: 0; - justify-content: center; - align-items: center; - width: 1.75em; - height: 1.75em; - margin-inline-end: 12px; - border-radius: 50%; - background: var(--note-icon-custom-background-color, var(--note-list-view-large-icon-background)); - font-size: 1.2em; - color: var(--note-icon-custom-color, var(--note-list-view-large-icon-color)); - } - - h5 .ck-find-result { - background: var(--note-list-view-search-result-highlight-background); - color: var(--note-list-view-search-result-highlight-color); - font-weight: 600; - text-decoration: underline; - } -} /* Note content preview */ .nested-note-list .note-book-content { @@ -291,13 +296,6 @@ justify-content: center; min-height: 50vh; } - - .ck-find-result { - outline: 2px solid var(--note-list-view-content-search-result-highlight-background); - border-radius: 4px; - background: var(--note-list-view-content-search-result-highlight-background); - color: var(--note-list-view-content-search-result-highlight-color); - } } .note-content-preview:has(.note-book-content:empty) { diff --git a/apps/client/src/widgets/collections/legacy/ListOrGridView.tsx b/apps/client/src/widgets/collections/legacy/ListOrGridView.tsx index dec8934043..2d1c4deb22 100644 --- a/apps/client/src/widgets/collections/legacy/ListOrGridView.tsx +++ b/apps/client/src/widgets/collections/legacy/ListOrGridView.tsx @@ -72,7 +72,7 @@ export function GridView({ note, noteIds: unfilteredNoteIds, highlightedTokens }
{!hasCollectionProperties && } - -
|     |     |
+  
|  |  |
 | --- | --- |
 | Heading | Not a heading |
 | Heading | Not a heading |
From 3b9f765c24a221eab92837b9e540bf7416187b47 Mon Sep 17 00:00:00 2001 From: Adorian Doran Date: Thu, 26 Feb 2026 19:52:20 +0200 Subject: [PATCH 111/116] style/tree items: display a fallback icon when the specified icon pack is missing --- apps/client/src/stylesheets/tree.css | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/apps/client/src/stylesheets/tree.css b/apps/client/src/stylesheets/tree.css index cb354d30df..a791f0578b 100644 --- a/apps/client/src/stylesheets/tree.css +++ b/apps/client/src/stylesheets/tree.css @@ -140,10 +140,22 @@ ul.fancytree-container { background-color: inherit; } + .fancytree-custom-icon { + display: flex; + justify-content: center; + align-items: center; + width: 1em; + height: 1em; font-size: 1.2em; } +/* Fallback icon */ +:where(.fancytree-custom-icon)::before { + content: "?"; +} + +/* Protected note icon badge */ span.fancytree-node.protected > span.fancytree-custom-icon { filter: drop-shadow(2px 2px 2px var(--main-text-color)); } From 7fac172ce2e83778ee179a2186cf93c3a4b5086a Mon Sep 17 00:00:00 2001 From: Adorian Doran Date: Thu, 26 Feb 2026 19:54:42 +0200 Subject: [PATCH 112/116] style: remove redundant style --- apps/client/src/stylesheets/theme-next/shell.css | 6 ------ 1 file changed, 6 deletions(-) diff --git a/apps/client/src/stylesheets/theme-next/shell.css b/apps/client/src/stylesheets/theme-next/shell.css index b7a08b4c97..ba6f5d95b5 100644 --- a/apps/client/src/stylesheets/theme-next/shell.css +++ b/apps/client/src/stylesheets/theme-next/shell.css @@ -839,13 +839,7 @@ body[dir=rtl] #left-pane span.fancytree-node.protected > span.fancytree-custom-i } #left-pane span.fancytree-node.fancytree-selected .fancytree-custom-icon { - display: flex; - justify-content: center; - align-items: center; - width: 1em; - height: 1em; margin: 0; - } #left-pane span.fancytree-node.fancytree-selected .fancytree-custom-icon::before { From f4d91e48ba2cc515dcba550d2bb48e5c51bf4cb4 Mon Sep 17 00:00:00 2001 From: Adorian Doran Date: Thu, 26 Feb 2026 20:46:55 +0200 Subject: [PATCH 113/116] style/pdf viewer: fix color scheme --- apps/client/src/widgets/type_widgets/file/PdfViewer.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/client/src/widgets/type_widgets/file/PdfViewer.tsx b/apps/client/src/widgets/type_widgets/file/PdfViewer.tsx index 7e6870dd42..a406f84a02 100644 --- a/apps/client/src/widgets/type_widgets/file/PdfViewer.tsx +++ b/apps/client/src/widgets/type_widgets/file/PdfViewer.tsx @@ -7,7 +7,8 @@ const VARIABLE_WHITELIST = new Set([ "root-background", "main-background-color", "main-border-color", - "main-text-color" + "main-text-color", + "theme-style" ]); interface PdfViewerProps extends Pick, "tabIndex"> { From 7c89c6652687a6d3fc42a2d01c38662dfdb8f59b Mon Sep 17 00:00:00 2001 From: Adorian Doran Date: Fri, 27 Feb 2026 19:34:26 +0200 Subject: [PATCH 114/116] style/pdf viewer: restyle UI --- .../widgets/type_widgets/file/PdfViewer.tsx | 44 +++- packages/pdfjs-viewer/src/custom.css | 219 ++++++++++++++++-- 2 files changed, 242 insertions(+), 21 deletions(-) diff --git a/apps/client/src/widgets/type_widgets/file/PdfViewer.tsx b/apps/client/src/widgets/type_widgets/file/PdfViewer.tsx index a406f84a02..6ba24ef812 100644 --- a/apps/client/src/widgets/type_widgets/file/PdfViewer.tsx +++ b/apps/client/src/widgets/type_widgets/file/PdfViewer.tsx @@ -1,14 +1,37 @@ import type { HTMLAttributes, RefObject } from "preact"; import { useCallback, useEffect, useRef } from "preact/hooks"; - +import Inter from "./../../../fonts/Inter/Inter-VariableFont_opsz,wght.ttf"; import { useSyncedRef, useTriliumOption, useTriliumOptionBool } from "../../react/hooks"; +interface FontDefinition { + name: string; + url: string; +} + +const FONTS: FontDefinition[] = [ + {name: "Inter", url: Inter}, +] + const VARIABLE_WHITELIST = new Set([ "root-background", "main-background-color", "main-border-color", "main-text-color", - "theme-style" + "theme-style", + "menu-background-color", + "dropdown-backdrop-filter", + "dropdown-border-radius", + "dropdown-border-color", + "dropdown-shadow-opacity", + "menu-padding-size", + "dropdown-backdrop-filter", + "menu-text-color", + "hover-item-background-color", + "hover-item-text-color", + "menu-item-icon-color", + "input-focus-outline-color", + "input-background-color", + "input-text-color" ]); interface PdfViewerProps extends Pick, "tabIndex"> { @@ -54,10 +77,14 @@ function useStyleInjection(iframeRef: RefObject) { const style = doc.createElement('style'); style.id = 'client-root-vars'; - style.textContent = cssVarsToString(getRootCssVariables()); + style.textContent = cssVarsToString(getRootCssVariables());; styleRef.current = style; - doc.head.appendChild(style); + + const fontStyles = doc.createElement("style"); + fontStyles.textContent = FONTS.map(injectFont).join("\n"); + doc.head.appendChild(fontStyles); + }, [ iframeRef ]); // React to changes. @@ -93,3 +120,12 @@ function cssVarsToString(vars: Record) { .map(([k, v]) => ` ${k}: ${v};`) .join('\n')}\n}`; } + +function injectFont(font: FontDefinition) { + return ` + @font-face { + font-family: '${font.name}'; + src: url('${font.url}'); + } + `; +}; \ No newline at end of file diff --git a/packages/pdfjs-viewer/src/custom.css b/packages/pdfjs-viewer/src/custom.css index bf291112dd..441fc049c0 100644 --- a/packages/pdfjs-viewer/src/custom.css +++ b/packages/pdfjs-viewer/src/custom.css @@ -1,31 +1,175 @@ -:root { - color-scheme: var(--tn-theme-style); +/* #region General */ - --body-bg-color: transparent; - --toolbar-bg-color: transparent; +:root { --main-color: var(--tn-main-text-color); + --body-bg-color: transparent; --toolbar-border-color: var(--tn-main-border-color); + --toolbar-bg-color: transparent; --toolbar-icon-opacity: 1; + --toggled-btn-bg-color: var(--tn-hover-item-background-color); + --doorhanger-bg-color: var(--tn-menu-background-color); + --doorhanger-separator-color: var(--tn-main-border-color); --page-margin: 12px auto; --spreadHorizontalWrapped-margin-LR: 4px; + + color-scheme: var(--tn-theme-style); } -.pdfViewer { - .page, - .page > .canvasWrapper, - .page > .canvasWrapper > canvas { - border-radius: 6px; - } +:root button, +:root dialog, +:root #toolbarContainer, +:root .toolbarButton, +:root #scaleSelect, +:root .toolbarButtonWithContainer .editorParamsToolbar .editorParamsLabel, +:root #toolbarContainer #toolbarViewer input, +:root #editorUndoBar, +:root .dialogButton { + font-family: "Inter"; + font-size: 11; +} - .page { - border: 1px solid var(--tn-main-border-color); - box-shadow: 7px 7px 15px #00000010; +#secondaryToolbar, +#documentPropertiesDialog, +#findbar.doorHanger, +.doorHangerRight, +#printServiceDialog { + border: 1px solid var(--tn-dropdown-border-color); + border-radius: var(--tn-dropdown-border-radius); + background-color: var(--tn-menu-background-color); + padding: var(--tn-menu-padding-size); + box-shadow: 0px 10px 20px rgba(0, 0, 0, var(--tn-dropdown-shadow-opacity)); + backdrop-filter: var(--tn-dropdown-backdrop-filter); +} + +.doorHangerRight, +.doorHangerLeft, +.doorHanger { + &::after, &::before { + display: none; } } +:root .toggle-button { + --toggle-border-color: transparent; + --toggle-background-color: var(--tn-input-background-color); + --toggle-background-color-hover: var(--toggle-background-color); + --toggle-dot-background-color: var(--tn-input-text-color); + --toggle-background-color-pressed: var(--tn-input-text-color); + --toggle-background-color-pressed-hover: var(--toggle-background-color-pressed); + cursor: pointer; +} + +:root .colorPicker { + --hover-outline-color: var(--tn-input-focus-outline-color); + --selected-outline-color: var(--tn-main-text-color); +} + +/* #endregion */ + /* #region Toolbar */ +.toolbarButton { + color: var(--menu-text-color); + + &:not(.labeled):active::before { + transform: scale(.85) !important; + } + + &:hover { + background: var(--tn-hover-item-background-color); + border-radius: 6px; + color: var(--tn-hover-item-text-color); + } +} + +#findbar { + padding: unset; +} + +#scaleSelectContainer { + --dropdown-btn-bg-color: transparent; + --button-hover-color: var(--tn-hover-item-background-color); + border-radius: 6px; + + select:focus { + background: var(--tn-main-background-color); + } +} + +/* Toolbar editor dropdowns */ +:root .editorParamsToolbar:not(.menu), +:root #highlightParamsToolbarContainer { + padding: 10px 16px; +} + +/* Toolbar dropdowns */ +:root .editorParamsToolbar { + .menu { + padding: 8px; + } + + .editorParamsToolbarContainer { + padding: 0; + } +} + +/* Overflow menu */ +#secondaryToolbar { + --toolbar-icon-bg-color: var(--tn-menu-item-icon-color); + --toolbar-icon-hover-bg-color: var(--tn-menu-item-icon-color); + --toggled-btn-bg-color: transparent; + --toggled-btn-color: currentColor; + --doorhanger-icon-opacity: 1; + padding: var(--tn-menu-padding-size); +} + +/* Horizontal menu dividers */ +:root #highlightParamsToolbarContainer #editorHighlightVisibility .divider, +:root .horizontalToolbarSeparator { + position: relative; + overflow: visible; + background: unset; + border: none; + + &:before { + content: ""; + position: absolute; + left: 0; + right: 0; + border-top: 1px solid var(--tn-main-border-color); + } +} + +/* Radio menu items */ +#cursorToolButtons .toolbarButton, +#scrollModeButtons .toolbarButton, +#spreadModeButtons .toolbarButton { + --toggled-hover-active-btn-color: var(--tn-hover-item-background-color); + --toggled-btn-color: var(--tn-menu-item-icon-color); + position: relative; + + &::after { + display: block; + content: ""; + position: absolute; + right: 0; + width: 2em; + height: 100%; + /* https://pictogrammers.com/library/mdi/icon/radiobox-blank/ */ + mask-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3e%3ctitle%3eradiobox-blank%3c/title%3e%3cpath d='M12%2c20A8%2c8 0 0%2c1 4%2c12A8%2c8 0 0%2c1 12%2c4A8%2c8 0 0%2c1 20%2c12A8%2c8 0 0%2c1 12%2c20M12%2c2A10%2c10 0 0%2c0 2%2c12A10%2c10 0 0%2c0 12%2c22A10%2c10 0 0%2c0 22%2c12A10%2c10 0 0%2c0 12%2c2Z' /%3e%3c/svg%3e"); + mask-size: 16px; + mask-repeat: no-repeat; + mask-position: center center; + background-color: var(--tn-main-text-color); + } + + &.toggled::after { + /* https://pictogrammers.com/library/mdi/icon/radiobox-marked/ */ + mask-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3e%3ctitle%3eradiobox-marked%3c/title%3e%3cpath d='M12%2c20A8%2c8 0 0%2c1 4%2c12A8%2c8 0 0%2c1 12%2c4A8%2c8 0 0%2c1 20%2c12A8%2c8 0 0%2c1 12%2c20M12%2c2A10%2c10 0 0%2c0 2%2c12A10%2c10 0 0%2c0 12%2c22A10%2c10 0 0%2c0 22%2c12A10%2c10 0 0%2c0 12%2c2M12%2c7A5%2c5 0 0%2c0 7%2c12A5%2c5 0 0%2c0 12%2c17A5%2c5 0 0%2c0 17%2c12A5%2c5 0 0%2c0 12%2c7Z' /%3e%3c/svg%3e"); + } +} + /* Permanently removed buttons */ #viewsManagerToggleButton, #downloadButton, @@ -43,10 +187,51 @@ /* #region Properties Dialog */ -/* Hide irrelevant properties */ -#documentPropertiesDialog > .row:has(#fileNameField), -#documentPropertiesDialog > .row:has(#linearizedField) { - display: none; +#documentPropertiesDialog { + --separator-color: transparent; + + user-select: none; + padding: 1em; + + .row { + line-height: 1.5; + + > span { + font-weight: bold; + opacity: .5; + } + + > p { + user-select: all; + } + } + + /* Hide irrelevant properties */ + > .row:has(#fileNameField), + > .row:has(#linearizedField) { + display: none; + } } /* #endregion */ + +/* #region Viewer Area */ + +.pdfViewer { + .page, + .page > .canvasWrapper, + .page > .canvasWrapper > canvas { + border-radius: 6px; + } + + .page { + border: 1px solid var(--tn-main-border-color); + box-shadow: 7px 7px 15px #00000010; + } +} + +#viewsManager { + display: none; +} + +/* #endregion */ \ No newline at end of file From 945b00030ba79ce8f8d953dadba82cbdfad221dd Mon Sep 17 00:00:00 2001 From: Adorian Doran Date: Fri, 27 Feb 2026 22:37:07 +0200 Subject: [PATCH 115/116] style/pdf viewer: restyle UI --- packages/pdfjs-viewer/src/custom.css | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/pdfjs-viewer/src/custom.css b/packages/pdfjs-viewer/src/custom.css index 441fc049c0..606afa4ac7 100644 --- a/packages/pdfjs-viewer/src/custom.css +++ b/packages/pdfjs-viewer/src/custom.css @@ -4,6 +4,7 @@ --main-color: var(--tn-main-text-color); --body-bg-color: transparent; --toolbar-border-color: var(--tn-main-border-color); + --toolbar-icon-bg-color: var(--tn-main-text-color); --toolbar-bg-color: transparent; --toolbar-icon-opacity: 1; --toggled-btn-bg-color: var(--tn-hover-item-background-color); @@ -26,7 +27,6 @@ :root #editorUndoBar, :root .dialogButton { font-family: "Inter"; - font-size: 11; } #secondaryToolbar, @@ -70,8 +70,6 @@ /* #region Toolbar */ .toolbarButton { - color: var(--menu-text-color); - &:not(.labeled):active::before { transform: scale(.85) !important; } @@ -81,10 +79,13 @@ border-radius: 6px; color: var(--tn-hover-item-text-color); } + + &.toggled::before { + color: var(--tn-menu-item-icon-color); + } } #findbar { - padding: unset; } #scaleSelectContainer { @@ -115,13 +116,19 @@ } /* Overflow menu */ -#secondaryToolbar { +:root #secondaryToolbar { --toolbar-icon-bg-color: var(--tn-menu-item-icon-color); --toolbar-icon-hover-bg-color: var(--tn-menu-item-icon-color); --toggled-btn-bg-color: transparent; --toggled-btn-color: currentColor; --doorhanger-icon-opacity: 1; padding: var(--tn-menu-padding-size); + + .toolbarButton.labeled { + color: var(--tn-menu-text-color); + + font-size: 13px; + } } /* Horizontal menu dividers */ @@ -146,7 +153,6 @@ #scrollModeButtons .toolbarButton, #spreadModeButtons .toolbarButton { --toggled-hover-active-btn-color: var(--tn-hover-item-background-color); - --toggled-btn-color: var(--tn-menu-item-icon-color); position: relative; &::after { From 676dea33e1d14c11647fedc79790c1c807045766 Mon Sep 17 00:00:00 2001 From: Adorian Doran Date: Fri, 27 Feb 2026 22:45:52 +0200 Subject: [PATCH 116/116] client: fix different issues --- apps/client/src/stylesheets/theme-next/shell.css | 2 +- apps/client/src/widgets/launch_bar/CalendarWidget.css | 1 - apps/client/src/widgets/type_widgets/file/PdfViewer.tsx | 5 ++--- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/apps/client/src/stylesheets/theme-next/shell.css b/apps/client/src/stylesheets/theme-next/shell.css index ba6f5d95b5..4ef72ddf57 100644 --- a/apps/client/src/stylesheets/theme-next/shell.css +++ b/apps/client/src/stylesheets/theme-next/shell.css @@ -823,7 +823,7 @@ body[dir=rtl] #left-pane span.fancytree-node.protected > span.fancytree-custom-i } #left-pane span.fancytree-node.fancytree-active .tree-item-button:hover, -#left-pane span.fancytree-node.fancytree-active.fancy-tree-selected .fancytree-custom-icon:hover { +#left-pane span.fancytree-node.fancytree-active.fancytree-selected .fancytree-custom-icon:hover { box-shadow: var(--left-pane-item-selected-action-button-hover-shadow); } diff --git a/apps/client/src/widgets/launch_bar/CalendarWidget.css b/apps/client/src/widgets/launch_bar/CalendarWidget.css index 73ecaccf32..d6b9d22645 100644 --- a/apps/client/src/widgets/launch_bar/CalendarWidget.css +++ b/apps/client/src/widgets/launch_bar/CalendarWidget.css @@ -65,7 +65,6 @@ border: 0; border-inline-start: unset; background-color: var(--menu-background-color); - font-weight: 400; outline: 0; font-weight: 300; font-size: 1.4em; diff --git a/apps/client/src/widgets/type_widgets/file/PdfViewer.tsx b/apps/client/src/widgets/type_widgets/file/PdfViewer.tsx index 6ba24ef812..3d39135c19 100644 --- a/apps/client/src/widgets/type_widgets/file/PdfViewer.tsx +++ b/apps/client/src/widgets/type_widgets/file/PdfViewer.tsx @@ -24,7 +24,6 @@ const VARIABLE_WHITELIST = new Set([ "dropdown-border-color", "dropdown-shadow-opacity", "menu-padding-size", - "dropdown-backdrop-filter", "menu-text-color", "hover-item-background-color", "hover-item-text-color", @@ -77,7 +76,7 @@ function useStyleInjection(iframeRef: RefObject) { const style = doc.createElement('style'); style.id = 'client-root-vars'; - style.textContent = cssVarsToString(getRootCssVariables());; + style.textContent = cssVarsToString(getRootCssVariables()); styleRef.current = style; doc.head.appendChild(style); @@ -128,4 +127,4 @@ function injectFont(font: FontDefinition) { src: url('${font.url}'); } `; -}; \ No newline at end of file +} \ No newline at end of file