- {libraryView === 'notes' && !isNarrowWorkspace && (
-
)}
diff --git a/src/renderer/src/styles.css b/src/renderer/src/styles.css
index 64e2b83b..fd3d700a 100644
--- a/src/renderer/src/styles.css
+++ b/src/renderer/src/styles.css
@@ -1283,6 +1283,7 @@
}
.magic-notes-workspace {
+ position: relative;
display: grid;
flex: 1;
min-width: 0;
@@ -1291,7 +1292,7 @@
}
.magic-notes-workspace--notes {
- grid-template-columns: var(--magic-notes-notes-width, 280px) 9px minmax(0, 1fr);
+ grid-template-columns: var(--magic-notes-notes-width, 200px) 9px minmax(0, 1fr);
}
.magic-notes-workspace--list-hidden,
@@ -1327,6 +1328,24 @@
gap: var(--space-2);
}
+.magic-notes-list-backdrop {
+ position: absolute;
+ inset: 0;
+ z-index: 4;
+ background: var(--overlay-backdrop);
+}
+
+.magic-notes-workspace--drawer > .magic-notes-overview {
+ position: absolute;
+ inset: 0 auto 0 0;
+ z-index: 5;
+ width: min(var(--magic-notes-notes-width, 200px), calc(100% - 32px));
+ padding: var(--space-2);
+ background: var(--surface-raised);
+ border-right: 1px solid var(--border-default);
+ box-shadow: var(--shadow-dialog);
+}
+
.magic-notes-workspace--notes .magic-notes-pane-heading {
min-height: var(--magic-notes-heading-height);
}
@@ -15302,6 +15321,14 @@ textarea.field-control {
overflow-wrap: anywhere;
}
+/* Windowed document table (P5): the table keeps the reader's row in place by
+ correcting the page's scrollTop; native scroll anchoring on the page could
+ pick a spacer and fight the correction. */
+.workspace-panel-scroll:has(.knowledge-documents__table-scroll--windowed),
+.knowledge-documents__table-scroll--windowed {
+ overflow-anchor: none;
+}
+
/* Windowed document table (P5): spacer rows stand in for unmounted rows. */
.knowledge-documents__table-scroll tbody tr.knowledge-documents__spacer {
border: 0;
@@ -19431,6 +19458,11 @@ textarea.field-control {
min-height: 0;
overflow: auto;
}
+/* A windowed tree keeps the reader's row in place itself; native scroll
+ anchoring could pick a spacer and fight the correction. */
+.workspace-files__files-view--windowed {
+ overflow-anchor: none;
+}
.workspace-git__changes {
flex: 1;
min-height: 0;
diff --git a/tests/magic-notes-layout.electron.test.ts b/tests/magic-notes-layout.electron.test.ts
index 5338ad93..6c20f474 100644
--- a/tests/magic-notes-layout.electron.test.ts
+++ b/tests/magic-notes-layout.electron.test.ts
@@ -94,7 +94,7 @@ it('resizes record columns with native Electron input and preserves desktop widt
const toolbarBox = await rect('.magic-note-detail-toolbar'), streamBox = await rect('.magic-notes-stream-pane');
const streamClient = await js('document.querySelector(".magic-notes-stream-pane").clientWidth');
assert(Math.abs(toolbarBox.x - streamBox.x) <= 1 && Math.abs(toolbarBox.width - streamClient) <= 1, 'Toolbar spans the stream: ' + JSON.stringify({ toolbarBox, streamBox, streamClient }));
- assert.equal((await rect('.magic-notes-overview')).width, 280);
+ assert.equal((await rect('.magic-notes-overview')).width, 200);
assert(await js('document.querySelector(".magic-notes-overview").checkVisibility()'));
await js('document.querySelector(".magic-notes-card-grid").scrollTop = 300; document.querySelector(".magic-notes-stream-pane").scrollTop = 420');
await wait('document.querySelector(".magic-notes-stream-pane").scrollTop === 420');
@@ -108,7 +108,7 @@ it('resizes record columns with native Electron input and preserves desktop widt
assert.equal(await js('document.querySelector("#magic-note-select-layout-note").getAttribute("aria-current")'), 'true');
await drag('.magic-notes-notes-resize-handle', 40);
const notesWidth = (await rect('.magic-notes-overview')).width;
- assert(notesWidth >= 320 && notesWidth <= 325);
+ assert(notesWidth >= 240 && notesWidth <= 245);
await key('.magic-notes-notes-resize-handle', 'Left');
assert.equal((await rect('.magic-notes-overview')).width, notesWidth - 16);
await click('button[aria-controls="magic-library-panel-notes"]');
@@ -117,7 +117,7 @@ it('resizes record columns with native Electron input and preserves desktop widt
assert.equal((await rect('.magic-notes-overview')).width, notesWidth - 16);
assert.equal(await js('document.querySelector(".magic-notes-card-grid").scrollTop'), 300);
await key('.magic-notes-notes-resize-handle', 'Home');
- assert.equal((await rect('.magic-notes-overview')).width, 240);
+ assert.equal((await rect('.magic-notes-overview')).width, 160);
await js('document.querySelector(".magic-notes-stream-pane").scrollTop = 0');
const editor = '.magic-note-composer .magic-note-editor__content .ql-editor';
const saveButton = '.magic-note-composer > footer > .primary-button';
@@ -184,10 +184,10 @@ it('resizes record columns with native Electron input and preserves desktop widt
const withoutAi = (await rect(index)).width; assert(withoutAi < 250 && withoutAi > 230);
await click('button[aria-controls="magic-notes-ai-pane"]'); assert.equal((await rect(index)).width, withoutAi);
await win.loadURL(${JSON.stringify(server.resolvedUrls!.local[0] + 'layout.html')}); await open(); assert.equal((await rect(index)).width, withoutAi);
- assert.equal((await rect('.magic-notes-overview')).width, 240);
+ assert.equal((await rect('.magic-notes-overview')).width, 160);
await js('document.querySelector(".magic-notes-card-grid").scrollTop = 300');
- win.setContentSize(1000, 720); await settle(); await settle();
- assert.equal((await rect('.magic-notes-overview')).width, 240);
+ win.setContentSize(960, 720); await settle(); await settle();
+ assert.equal((await rect('.magic-notes-overview')).width, 160);
assert.equal((await rect(index)).width, 0, 'Record drawer follows detail width, not the outer page');
const assertSideBySide = async () => {
const s = await rect(stream), ai = await rect('.magic-notes-ai-pane'), list = await rect('.magic-notes-overview');
@@ -198,12 +198,14 @@ it('resizes record columns with native Electron input and preserves desktop widt
await assertSideBySide();
win.setContentSize(930, 720); await settle(); await settle();
await assertSideBySide();
- win.setContentSize(1000, 720); await settle(); await settle();
+ win.setContentSize(960, 720); await settle(); await settle();
assert(await js('document.documentElement.scrollWidth <= innerWidth'));
win.setContentSize(820, 720); await settle(); await settle();
assert((await rect(stream)).width >= 299);
const constrained = { index: (await rect(index)).width, editor: (await rect(stream)).width, ai: (await rect('.magic-notes-ai-pane')).width };
win.setContentSize(720, 640); await settle(); await settle();
+ assert.equal((await rect('.magic-notes-overview')).width, 160);
+ await click('#magic-notes-list-toggle');
assert.equal((await rect('.magic-notes-overview')).width, 0);
await click('#magic-notes-back');
assert(await js('document.querySelector(".magic-notes-overview").checkVisibility()'));
@@ -224,10 +226,28 @@ it('resizes record columns with native Electron input and preserves desktop widt
assert(Math.abs(narrowFooter.x + narrowFooter.width - footerPaddingRight - narrowSave.x - narrowSave.width) <= 1, 'Narrow Save button stays right-aligned within footer padding');
await screenshot('magic-notes-narrow');
win.setContentSize(560, 640); await settle(); await settle();
+ assert(await js('document.querySelector("#magic-notes-list-toggle").checkVisibility()'));
+ const detailBeforeDrawer = await rect('.magic-notes-detail-container');
+ await click('#magic-notes-list-toggle');
+ assert(await js('document.querySelector(".magic-notes-workspace--drawer") !== null'));
+ assert.equal((await rect('.magic-notes-overview')).width, 160);
+ assert.deepEqual(await rect('.magic-notes-detail-container'), detailBeforeDrawer);
+ assert(await js('document.querySelector(".magic-notes-overview").scrollWidth <= document.querySelector(".magic-notes-overview").clientWidth'));
+ await key('#magic-library-panel-notes input', 'Escape');
+ assert.equal((await rect('.magic-notes-overview')).width, 0);
+ assert(await js('document.activeElement.id === "magic-notes-list-toggle"'));
+ await click('#magic-notes-list-toggle');
+ await click('#magic-note-select-other-note-3');
+ await wait('document.querySelector(".magic-note-detail-title").value === "Other note 3"');
+ assert.equal((await rect('.magic-notes-overview')).width, 0);
+ await click('#magic-notes-list-toggle');
+ await click('#magic-note-select-layout-note');
+ await wait('document.querySelector(".magic-note-detail-title").value === "Layout note"');
assert((await rect('.magic-notes-ai-pane')).y >= (await rect(stream)).y + (await rect(stream)).height, 'AI pane stacks below the stream on very narrow widths');
assert.equal(await js('getComputedStyle(document.querySelector(".magic-notes-ai-resize-handle")).display'), 'none');
win.setContentSize(1280, 800); await settle(); await settle();
- assert.equal((await rect('.magic-notes-overview')).width, 240);
+ await click('#magic-notes-list-toggle');
+ assert.equal((await rect('.magic-notes-overview')).width, 160);
assert.equal((await rect(index)).width, withoutAi);
await key('.magic-note-record', 'Tab');
await js('document.querySelector(".magic-note-record").focus()');