docs: align uiux demo theme controls
This commit is contained in:
@@ -2,6 +2,11 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Documentation
|
||||
|
||||
- Align the `docs/ui-ux/` demo appearance controls with the current Theme + Skin
|
||||
model, replacing the stale `data-theme`-only buttons and legacy theme names.
|
||||
|
||||
## [v0.51.89] — 2026-05-18 — Release BM (stage-382 — 6-PR full sweep batch — runtime adapter approval/clarify seam + SOUL.md memory panel + #1855 resolve_model_provider fast-path + PWA sidebar spinner fix + /model active-provider preference + contributor contract docs index)
|
||||
|
||||
### Changed
|
||||
|
||||
BIN
docs/pr-media/uiux-theme-demo-controls/after-index.png
Normal file
BIN
docs/pr-media/uiux-theme-demo-controls/after-index.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
BIN
docs/pr-media/uiux-theme-demo-controls/after-two-stage.png
Normal file
BIN
docs/pr-media/uiux-theme-demo-controls/after-two-stage.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 45 KiB |
BIN
docs/pr-media/uiux-theme-demo-controls/before-index.png
Normal file
BIN
docs/pr-media/uiux-theme-demo-controls/before-index.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 57 KiB |
BIN
docs/pr-media/uiux-theme-demo-controls/before-two-stage.png
Normal file
BIN
docs/pr-media/uiux-theme-demo-controls/before-two-stage.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 53 KiB |
@@ -1,5 +1,5 @@
|
||||
<!doctype html>
|
||||
<html lang="en" data-theme="slate">
|
||||
<html lang="en" class="dark" data-skin="slate">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Hermes WebUI — Messages UI Inventory</title>
|
||||
@@ -54,14 +54,21 @@
|
||||
<div class="doc-title">Hermes WebUI — Messages UI Inventory<small>Every message-area element & combination, wired to the real <code>static/style.css</code>. · <a href="./two-stage-proposal.html" style="color:var(--blue);text-decoration:none;">Two-stage proposal (#536) →</a></small></div>
|
||||
<div class="doc-toggles">
|
||||
<strong style="font-size:10px;color:var(--muted);letter-spacing:.08em;text-transform:uppercase;align-self:center;margin-right:4px;">Theme</strong>
|
||||
<button data-theme-btn="default">Default</button>
|
||||
<button data-theme-btn="slate" class="on">Slate</button>
|
||||
<button data-theme-btn="light">Light</button>
|
||||
<button data-theme-btn="solarized">Solarized</button>
|
||||
<button data-theme-btn="monokai">Monokai</button>
|
||||
<button data-theme-btn="nord">Nord</button>
|
||||
<button data-theme-btn="oled">OLED</button>
|
||||
<button data-mode-btn="system">System</button>
|
||||
<button data-mode-btn="dark" class="on">Dark</button>
|
||||
<button data-mode-btn="light">Light</button>
|
||||
<span style="width:1px;height:18px;background:var(--border);margin:0 4px;align-self:center;"></span>
|
||||
<strong style="font-size:10px;color:var(--muted);letter-spacing:.08em;text-transform:uppercase;align-self:center;margin-right:4px;">Skin</strong>
|
||||
<button data-skin-btn="default">Default</button>
|
||||
<button data-skin-btn="ares">Ares</button>
|
||||
<button data-skin-btn="mono">Mono</button>
|
||||
<button data-skin-btn="slate" class="on">Slate</button>
|
||||
<button data-skin-btn="poseidon">Poseidon</button>
|
||||
<button data-skin-btn="sisyphus">Sisyphus</button>
|
||||
<button data-skin-btn="charizard">Charizard</button>
|
||||
<button data-skin-btn="sienna">Sienna</button>
|
||||
<button data-skin-btn="catppuccin">Catppuccin</button>
|
||||
<button data-skin-btn="nous">Nous</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@@ -817,15 +824,33 @@ Run typecheck to confirm, then patch.</pre></div>
|
||||
onload="renderMathInElement(document.body,{delimiters:[{left:'$$',right:'$$',display:true},{left:'\\[',right:'\\]',display:true},{left:'\\(',right:'\\)',display:false},{left:'$',right:'$',display:false}],throwOnError:false});"></script>
|
||||
|
||||
<script>
|
||||
// Theme picker
|
||||
document.querySelectorAll('[data-theme-btn]').forEach(btn => {
|
||||
// Appearance picker (matches the real app contract: theme class + skin data attribute)
|
||||
let docTheme = 'dark';
|
||||
let docSkin = 'slate';
|
||||
const docThemeMq = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
function applyDocAppearance() {
|
||||
const resolvedTheme = docTheme === 'system' ? (docThemeMq.matches ? 'dark' : 'light') : docTheme;
|
||||
document.documentElement.classList.toggle('dark', resolvedTheme === 'dark');
|
||||
if (docSkin === 'default') document.documentElement.removeAttribute('data-skin');
|
||||
else document.documentElement.dataset.skin = docSkin;
|
||||
}
|
||||
document.querySelectorAll('[data-mode-btn]').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
const t = btn.dataset.themeBtn;
|
||||
if (t === 'default') document.documentElement.removeAttribute('data-theme');
|
||||
else document.documentElement.setAttribute('data-theme', t);
|
||||
document.querySelectorAll('[data-theme-btn]').forEach(b => b.classList.toggle('on', b === btn));
|
||||
docTheme = btn.dataset.modeBtn;
|
||||
applyDocAppearance();
|
||||
document.querySelectorAll('[data-mode-btn]').forEach(b => b.classList.toggle('on', b === btn));
|
||||
});
|
||||
});
|
||||
document.querySelectorAll('[data-skin-btn]').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
docSkin = btn.dataset.skinBtn;
|
||||
applyDocAppearance();
|
||||
document.querySelectorAll('[data-skin-btn]').forEach(b => b.classList.toggle('on', b === btn));
|
||||
});
|
||||
});
|
||||
if (docThemeMq.addEventListener) {
|
||||
docThemeMq.addEventListener('change', () => { if (docTheme === 'system') applyDocAppearance(); });
|
||||
}
|
||||
// Bubble-layout toggle
|
||||
|
||||
// Thinking / tool-card click-to-toggle (so the demo feels live)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!doctype html>
|
||||
<html lang="en" data-theme="slate">
|
||||
<html lang="en" class="dark" data-skin="slate">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Hermes WebUI — Two-Stage Chat Proposal (Issue #536)</title>
|
||||
@@ -167,13 +167,21 @@
|
||||
</div>
|
||||
<div class="doc-toggles">
|
||||
<strong style="font-size:10px;color:var(--muted);letter-spacing:.08em;text-transform:uppercase;align-self:center;margin-right:4px;">Theme</strong>
|
||||
<button data-theme-btn="default">Default</button>
|
||||
<button data-theme-btn="slate" class="on">Slate</button>
|
||||
<button data-theme-btn="light">Light</button>
|
||||
<button data-theme-btn="solarized">Solarized</button>
|
||||
<button data-theme-btn="monokai">Monokai</button>
|
||||
<button data-theme-btn="nord">Nord</button>
|
||||
<button data-theme-btn="oled">OLED</button>
|
||||
<button data-mode-btn="system">System</button>
|
||||
<button data-mode-btn="dark" class="on">Dark</button>
|
||||
<button data-mode-btn="light">Light</button>
|
||||
<span style="width:1px;height:18px;background:var(--border);margin:0 4px;align-self:center;"></span>
|
||||
<strong style="font-size:10px;color:var(--muted);letter-spacing:.08em;text-transform:uppercase;align-self:center;margin-right:4px;">Skin</strong>
|
||||
<button data-skin-btn="default">Default</button>
|
||||
<button data-skin-btn="ares">Ares</button>
|
||||
<button data-skin-btn="mono">Mono</button>
|
||||
<button data-skin-btn="slate" class="on">Slate</button>
|
||||
<button data-skin-btn="poseidon">Poseidon</button>
|
||||
<button data-skin-btn="sisyphus">Sisyphus</button>
|
||||
<button data-skin-btn="charizard">Charizard</button>
|
||||
<button data-skin-btn="sienna">Sienna</button>
|
||||
<button data-skin-btn="catppuccin">Catppuccin</button>
|
||||
<button data-skin-btn="nous">Nous</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@@ -698,15 +706,33 @@ tool_calls get attached before save.</pre></div>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
// Theme picker (matches index.html)
|
||||
document.querySelectorAll('[data-theme-btn]').forEach(btn => {
|
||||
// Appearance picker (matches the real app contract: theme class + skin data attribute)
|
||||
let docTheme = 'dark';
|
||||
let docSkin = 'slate';
|
||||
const docThemeMq = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
function applyDocAppearance() {
|
||||
const resolvedTheme = docTheme === 'system' ? (docThemeMq.matches ? 'dark' : 'light') : docTheme;
|
||||
document.documentElement.classList.toggle('dark', resolvedTheme === 'dark');
|
||||
if (docSkin === 'default') document.documentElement.removeAttribute('data-skin');
|
||||
else document.documentElement.dataset.skin = docSkin;
|
||||
}
|
||||
document.querySelectorAll('[data-mode-btn]').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
const t = btn.dataset.themeBtn;
|
||||
if (t === 'default') document.documentElement.removeAttribute('data-theme');
|
||||
else document.documentElement.setAttribute('data-theme', t);
|
||||
document.querySelectorAll('[data-theme-btn]').forEach(b => b.classList.toggle('on', b === btn));
|
||||
docTheme = btn.dataset.modeBtn;
|
||||
applyDocAppearance();
|
||||
document.querySelectorAll('[data-mode-btn]').forEach(b => b.classList.toggle('on', b === btn));
|
||||
});
|
||||
});
|
||||
document.querySelectorAll('[data-skin-btn]').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
docSkin = btn.dataset.skinBtn;
|
||||
applyDocAppearance();
|
||||
document.querySelectorAll('[data-skin-btn]').forEach(b => b.classList.toggle('on', b === btn));
|
||||
});
|
||||
});
|
||||
if (docThemeMq.addEventListener) {
|
||||
docThemeMq.addEventListener('change', () => { if (docTheme === 'system') applyDocAppearance(); });
|
||||
}
|
||||
|
||||
// Existing thinking/tool cards click-to-toggle.
|
||||
document.querySelectorAll('.thinking-card-header, .tool-card-header').forEach(h => {
|
||||
|
||||
40
tests/test_uiux_docs_theme_contract.py
Normal file
40
tests/test_uiux_docs_theme_contract.py
Normal file
@@ -0,0 +1,40 @@
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
DEMO_DOCS = [
|
||||
Path("docs/ui-ux/index.html"),
|
||||
Path("docs/ui-ux/two-stage-proposal.html"),
|
||||
]
|
||||
|
||||
THEME_VALUES = ("system", "dark", "light")
|
||||
SKIN_VALUES = (
|
||||
"default",
|
||||
"ares",
|
||||
"mono",
|
||||
"slate",
|
||||
"poseidon",
|
||||
"sisyphus",
|
||||
"charizard",
|
||||
"sienna",
|
||||
"catppuccin",
|
||||
"nous",
|
||||
)
|
||||
LEGACY_THEME_LABELS = ("Solarized", "Monokai", "Nord", "OLED")
|
||||
|
||||
|
||||
def test_uiux_demo_docs_use_current_theme_skin_axes():
|
||||
for doc_path in DEMO_DOCS:
|
||||
html = doc_path.read_text()
|
||||
assert 'data-theme="' not in html, f"{doc_path} should not use legacy data-theme"
|
||||
assert 'class="dark" data-skin="slate"' in html
|
||||
assert "classList.toggle('dark'" in html
|
||||
assert "dataset.skin" in html
|
||||
|
||||
for theme in THEME_VALUES:
|
||||
assert f'data-mode-btn="{theme}"' in html
|
||||
|
||||
for skin in SKIN_VALUES:
|
||||
assert f'data-skin-btn="{skin}"' in html
|
||||
|
||||
for label in LEGACY_THEME_LABELS:
|
||||
assert f">{label}<" not in html
|
||||
Reference in New Issue
Block a user