fixes in css

This commit is contained in:
Mateusz Gruszczyński
2026-08-03 13:13:11 +02:00
parent 8b8b3b82b8
commit 825edeab92
6 changed files with 170 additions and 6 deletions
Generated
+1 -1
View File
@@ -2581,7 +2581,7 @@ dependencies = [
[[package]] [[package]]
name = "rustpad" name = "rustpad"
version = "0.2.27" version = "0.2.28"
dependencies = [ dependencies = [
"argon2", "argon2",
"aws-config", "aws-config",
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "rustpad" name = "rustpad"
version = "0.2.27" version = "0.2.28"
edition = "2024" edition = "2024"
rust-version = "1.94" rust-version = "1.94"
description = "Collaborative Markdown notepad built with Axum, WebSockets and SQLite, PostgreSQL and MySQL" description = "Collaborative Markdown notepad built with Axum, WebSockets and SQLite, PostgreSQL and MySQL"
+134
View File
@@ -6572,3 +6572,137 @@ dialog::backdrop {
.form-message.warning { .form-message.warning {
color: var(--warning); color: var(--warning);
} }
/* Keep editor mode/view controls inside the viewport at browser zoom. */
.control-label-short {
display: none;
}
.pad-page .editor-toolbar,
.pad-page .toolbar-group,
.pad-page .view-switch {
min-width: 0;
max-width: 100%;
}
.pad-page #mode-toggle,
.pad-page .view-switch {
flex: 0 0 auto;
}
@media (max-width: 1699px) {
.pad-page :is(#mode-toggle, .view-switch) .control-label-full {
display: none;
}
.pad-page :is(#mode-toggle, .view-switch) .control-label-short {
display: inline;
}
.pad-page #mode-toggle {
width: 36px;
min-width: 36px;
padding-inline: 6px;
}
.pad-page .view-switch button {
width: 36px;
min-width: 36px;
padding-inline: 6px;
}
}
@media (max-width: 760px) {
.pad-page .editor-toolbar {
grid-template-columns: minmax(0, 1fr) auto auto;
width: 100%;
max-width: 100vw;
}
.pad-page #mode-toggle {
display: inline-flex;
}
.pad-page .view-switch button,
.pad-page .view-switch button[data-view="split"] {
display: inline-flex;
width: 34px;
min-width: 34px;
align-items: center;
justify-content: center;
padding-inline: 5px;
}
.pad-page .workspace.view-split {
grid-template-columns: minmax(0, 1fr);
grid-template-rows: minmax(0, 1fr) minmax(0, 1fr);
}
.pad-page .workspace.view-split .preview-column {
display: grid;
opacity: 1;
transform: translateX(0);
border-top: 1px solid var(--border);
}
}
/* History content wraps vertically and never creates a horizontal scrollbar. */
.history-panel {
max-width: 100vw;
min-width: 0;
}
.history-list {
min-width: 0;
overflow-x: hidden;
overflow-y: auto;
}
.revision {
min-width: 0;
grid-template-columns: 12px minmax(0, 1fr);
}
.revision > div,
.revision__meta,
.revision__meta strong,
.revision time,
.revision__snippet,
.revision__preview {
min-width: 0;
max-width: 100%;
}
.revision__meta {
flex-wrap: wrap;
}
.revision__meta strong,
.revision time,
.revision__snippet,
.revision__preview {
overflow-wrap: anywhere;
word-break: break-word;
}
.revision__snippet {
white-space: normal;
}
.revision__preview {
overflow-x: hidden;
overflow-y: auto;
white-space: pre-wrap;
}
.history-header > div,
.history-header h2,
.history-header p,
.history-help,
.history-list .empty,
.history-list .error {
min-width: 0;
max-width: 100%;
overflow-wrap: anywhere;
word-break: break-word;
}
+9 -3
View File
@@ -123,9 +123,15 @@
Compact</label><label class="line-toggle"><input id="line-links-toggle" type="checkbox"> Compact</label><label class="line-toggle"><input id="line-links-toggle" type="checkbox">
Line links</label> Line links</label>
<div class="toolbar-fill"></div><button id="mode-toggle" class="toolbar-action active" <div class="toolbar-fill"></div><button id="mode-toggle" class="toolbar-action active"
aria-pressed="true">Markdown</button> aria-pressed="true" aria-label="Markdown" title="Markdown"><span class="control-label-full">Markdown</span><span
<div class="view-switch"><button data-view="edit">Edit</button><button data-view="split" class="control-label-short" aria-hidden="true">M</span></button>
class="active">Split</button><button data-view="preview">Preview</button></div> <div class="view-switch" aria-label="Editor view"><button data-view="edit" aria-label="Edit" title="Edit"><span
class="control-label-full">Edit</span><span class="control-label-short"
aria-hidden="true">E</span></button><button data-view="split" class="active" aria-label="Split"
title="Split"><span class="control-label-full">Split</span><span class="control-label-short"
aria-hidden="true">S</span></button><button data-view="preview" aria-label="Preview" title="Preview"><span
class="control-label-full">Preview</span><span class="control-label-short"
aria-hidden="true">P</span></button></div>
</div> </div>
<div id="connection-notice" class="connection-notice" role="status" aria-live="polite" hidden> <div id="connection-notice" class="connection-notice" role="status" aria-live="polite" hidden>
<span class="connection-notice__signal" <span class="connection-notice__signal"
+5 -1
View File
@@ -858,9 +858,13 @@ export function startNoteEditor(adapter) {
button.setAttribute("aria-pressed", String(active)); button.setAttribute("aria-pressed", String(active));
}); });
const markdown = uiState.mode === "markdown"; const markdown = uiState.mode === "markdown";
const modeName = markdown ? "Markdown" : "Text";
modeToggle.classList.toggle("active", markdown); modeToggle.classList.toggle("active", markdown);
modeToggle.setAttribute("aria-pressed", String(markdown)); modeToggle.setAttribute("aria-pressed", String(markdown));
modeToggle.textContent = markdown ? "Markdown" : "Text"; modeToggle.title = modeName;
modeToggle.setAttribute("aria-label", modeName);
modeToggle.querySelector(".control-label-full").textContent = modeName;
modeToggle.querySelector(".control-label-short").textContent = markdown ? "M" : "T";
render(); render();
if (write) writeEditorState(uiState, { replace }); if (write) writeEditorState(uiState, { replace });
updateAddressLabel(); updateAddressLabel();
+20
View File
@@ -137,3 +137,23 @@ test("Markdown/Text uses the same toolbar action styling as More", async () => {
assert.match(css, /\.markdown-more>summary,\s*\.pad-page \.toolbar-action \{/); assert.match(css, /\.markdown-more>summary,\s*\.pad-page \.toolbar-action \{/);
assert.match(editorSource, /modeToggle\.setAttribute\("aria-pressed", String\(markdown\)\)/); assert.match(editorSource, /modeToggle\.setAttribute\("aria-pressed", String\(markdown\)\)/);
}); });
test("zoomed editor uses compact labels without hiding any view", async () => {
const html = await readFile(new URL("../static/editor.html", import.meta.url), "utf8");
const css = await readFile(new URL("../static/css/styles.css", import.meta.url), "utf8");
const editorSource = await readFile(new URL("../static/js/note-editor.js", import.meta.url), "utf8");
assert.match(html, /id="mode-toggle"[\s\S]*?control-label-full">Markdown<[\s\S]*?control-label-short" aria-hidden="true">M</);
assert.match(html, /data-view="edit"[\s\S]*?>E<[\s\S]*?data-view="split"[\s\S]*?>S<[\s\S]*?data-view="preview"[\s\S]*?>P</);
assert.match(css, /@media \(max-width: 1699px\) \{[\s\S]*?\.pad-page :is\(#mode-toggle, \.view-switch\) \.control-label-full \{\s*display:\s*none;/);
assert.match(css, /@media \(max-width: 760px\) \{[\s\S]*?grid-template-columns:\s*minmax\(0, 1fr\) auto auto;[\s\S]*?#mode-toggle \{\s*display:\s*inline-flex;[\s\S]*?button\[data-view="split"\][\s\S]*?display:\s*inline-flex;/);
assert.match(editorSource, /modeToggle\.querySelector\("\.control-label-short"\)\.textContent = markdown \? "M" : "T";/);
});
test("history panel wraps long content without horizontal scrolling", async () => {
const css = await readFile(new URL("../static/css/styles.css", import.meta.url), "utf8");
assert.match(css, /\.history-list \{[\s\S]*?overflow-x:\s*hidden;[\s\S]*?overflow-y:\s*auto;/);
assert.match(css, /\.revision \{[\s\S]*?grid-template-columns:\s*12px minmax\(0, 1fr\);/);
assert.match(css, /\.revision__meta strong,[\s\S]*?\.revision__preview \{[\s\S]*?overflow-wrap:\s*anywhere;[\s\S]*?word-break:\s*break-word;/);
assert.match(css, /\.revision__preview \{[\s\S]*?overflow-x:\s*hidden;[\s\S]*?white-space:\s*pre-wrap;/);
});