Draw navigation arrows with CSS borders

This commit is contained in:
Server 2026-08-10 18:47:23 +00:00
parent df68cae94b
commit 06032e6800
7 changed files with 18 additions and 14 deletions

View file

@ -13,7 +13,7 @@ SharedDocsLib — небольшой Python-фреймворк для докум
- `index.zip`, содержащий только `index.html`;
- live-preview с перекомпиляцией изменившегося Python-модуля.
UI не содержит языко-зависимых служебных подписей. Базовый шрифт — `system-ui 16px`; служебные UTF-8-пиктограммы используют Arial, а навигационные стрелки остаются в `system-ui`. AMOLED-тема включена по умолчанию и сохраняется локально после переключения.
UI не содержит языко-зависимых служебных подписей. Базовый шрифт — `system-ui 16px`, а служебные UTF-8-пиктограммы используют Arial. Навигационные стрелки отрисовываются CSS-границами без текстовых символов. AMOLED-тема включена по умолчанию и сохраняется локально после переключения.
На десктопе компактный header содержит полное название документации, поиск и переключатель темы, а слева постоянно видны header-кнопки и дерево страниц. Поисковый placeholder медленно печатает первые слова случайного названия, добавляет троеточие только в конце и сохраняет готовый текст 5 секунд; при вводе поле раскрывает ранжированные результаты вниз. Проверка manifest выполняется автоматически в фоне без отдельной кнопки обновления.

View file

@ -5,4 +5,4 @@ from .server import build, create_app, run
from .ui import HeaderButton
__all__ = ["Component", "HeaderButton", "Page", "build", "create_app", "run"]
__version__ = "0.3.3"
__version__ = "0.3.4"

View file

@ -43,7 +43,6 @@ button, input { font: inherit; }
button, a { -webkit-tap-highlight-color: transparent; }
button { color: inherit; }
.glyph-button, .refresh-glyph { font-family: Arial, sans-serif; }
.nav-arrow { font-family: system-ui; }
.app-shell { --desktop-sidebar-width: clamp(270px, 25vw, 400px); display: flex; width: 100%; height: 100%; flex-direction: column; overflow: hidden; background: var(--shell); }
.desktop-header { position: relative; z-index: 20; display: grid; min-height: 76px; flex: 0 0 76px; grid-template-columns: minmax(260px, 1fr) auto; align-items: center; gap: 18px; padding: 12px 20px; background: var(--shell); }
@ -128,7 +127,9 @@ button { color: inherit; }
.nav-card { display: flex; min-height: 48px; align-items: center; gap: 8px; padding: 7px 20px; border: 0; border-radius: 30px; color: var(--text); background: var(--control); cursor: pointer; }
.nav-card:hover:not(:disabled) { background: var(--active); }
.nav-card:disabled { display: none; }
.nav-card small { color: inherit; font-size: 1.3rem; }
.nav-arrow { display: block; width: 10px; height: 10px; flex: 0 0 10px; border: 0 solid currentColor; transform: rotate(45deg); }
.nav-arrow-previous { border-bottom-width: 2px; border-left-width: 2px; }
.nav-arrow-next { border-top-width: 2px; border-right-width: 2px; }
#next-page { color: var(--shell); background: var(--text); }
:root[data-theme="dark"] #next-page { color: #000; background: #eee; }

View file

@ -228,12 +228,12 @@
button.disabled = !page;
button.replaceChildren();
if (!page) return;
const arrow = document.createElement("small");
arrow.className = "nav-arrow";
arrow.textContent = direction;
const arrow = document.createElement("span");
arrow.className = `nav-arrow nav-arrow-${direction}`;
arrow.setAttribute("aria-hidden", "true");
const title = document.createElement("span");
title.textContent = page.title;
if (direction === "") button.append(arrow, title);
if (direction === "previous") button.append(arrow, title);
else button.append(title, arrow);
button.onclick = () => navigate(page.number);
}
@ -260,8 +260,8 @@
});
});
updateActiveNavigation(page.number);
setupNavButton(elements.previous, manifest.pages[index - 1], "");
setupNavButton(elements.next, manifest.pages[index + 1], "");
setupNavButton(elements.previous, manifest.pages[index - 1], "previous");
setupNavButton(elements.next, manifest.pages[index + 1], "next");
elements.pageSurface.scrollTo({ top: 0, behavior: "instant" });
}

View file

@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project]
name = "shared-docs-lib"
version = "0.3.3"
version = "0.3.4"
description = "Build self-contained, Obsidian-like documentation sites from Python functions."
readme = "README.md"
requires-python = ">=3.10"

View file

@ -120,7 +120,10 @@ def test_all_endpoints_and_self_contained_build(tmp_path):
assert "elements.pageSurface.scrollTo" in html
assert "font-family: system-ui; font-size: 16px" in html
assert ".glyph-button, .refresh-glyph { font-family: Arial" in html
assert ".nav-arrow { font-family: system-ui; }" in html
assert ".nav-arrow { display: block; width: 10px; height: 10px; flex: 0 0 10px; border: 0 solid currentColor; transform: rotate(45deg); }" in html
assert ".nav-arrow-previous { border-bottom-width: 2px; border-left-width: 2px; }" in html
assert ".nav-arrow-next { border-top-width: 2px; border-right-width: 2px; }" in html
assert 'arrow.textContent = direction' not in html
assert "--shell: #000000" in html
assert 'id="desktop-search-input"' in html
assert '<header class="desktop-header">' in html
@ -165,7 +168,7 @@ def test_all_endpoints_and_self_contained_build(tmp_path):
def test_build_writes_static_bundle(tmp_path):
assert __version__ == "0.3.3"
assert __version__ == "0.3.4"
@Page("1", "Static page")
def static_page():

2
uv.lock generated
View file

@ -452,7 +452,7 @@ wheels = [
[[package]]
name = "shared-docs-lib"
version = "0.3.3"
version = "0.3.4"
source = { editable = "." }
dependencies = [
{ name = "fastapi" },