ui: declarative per-page tab titles via definePage title

This commit is contained in:
2026-09-04 21:59:09 +00:00
parent 6476695d29
commit 6229c39347
18 changed files with 84 additions and 4 deletions
+58 -1
View File
@@ -116,11 +116,12 @@ const flush = () => new Promise(r => setTimeout(r, 20));
* loadCredentials: refreshing=true before the fetch, credentials=<new array>
* and refreshing=false after — fresh values on every run).
*/
function makePage(label, counters) {
function makePage(label, counters, title) {
const state = reactive({ loading: true, done: 0 });
return {
state,
page: definePage({
title: title || undefined,
init: () => state,
async load(s) {
counters.loads++;
@@ -227,6 +228,62 @@ test('two #comp containers: updates in one root do not disturb the other', async
assertEq(c.unmounts, 0, 'neither page unmounted');
});
/* ── Tab title (definePage `title`) ─────────────────────────── */
test('mounting a titled page sets document.title', async () => {
const c = freshCounters();
const { page } = makePage('T', c, 'Titled - Vacuum Wall');
const main = new FakeEl('div');
document.title = 'base';
render(main, () => hComp(page, '/titled'));
await flush();
assertEq(document.title, 'Titled - Vacuum Wall', 'title applied on mount');
});
test('a page without a title leaves document.title untouched', async () => {
const c = freshCounters();
const { page } = makePage('U', c);
const main = new FakeEl('div');
document.title = 'unchanged';
render(main, () => hComp(page, '/untitled'));
await flush();
assertEq(document.title, 'unchanged', 'no title → document.title untouched');
});
test('navigation updates document.title; remount re-applies idempotently', async () => {
const c = freshCounters();
const a = makePage('A', c, 'Alpha - Vacuum Wall');
const b = makePage('B', c, 'Beta - Vacuum Wall');
const nav = reactive({ path: '/page-a' });
const main = new FakeEl('div');
render(main, () => hComp(nav.path === '/page-a' ? a.page : b.page, nav.path));
await flush();
assertEq(document.title, 'Alpha - Vacuum Wall', 'A title on first mount');
nav.path = '/page-b';
await flush();
assertEq(document.title, 'Beta - Vacuum Wall', 'B title after navigation');
nav.path = '/page-a';
await flush();
assertEq(document.title, 'Alpha - Vacuum Wall', 'A title re-applied on remount');
});
test('mounting an untitled page does not reset a previously set title', async () => {
const c = freshCounters();
const a = makePage('A', c, 'Alpha - Vacuum Wall');
const b = makePage('B', c);
const nav = reactive({ path: '/page-a' });
const main = new FakeEl('div');
render(main, () => hComp(nav.path === '/page-a' ? a.page : b.page, nav.path));
await flush();
assertEq(document.title, 'Alpha - Vacuum Wall', 'baseline');
nav.path = '/page-b';
await flush();
assertEq(document.title, 'Alpha - Vacuum Wall', 'untitled mount keeps prior title');
});
/* ── Runner ─────────────────────────────────────────────────── */
(async () => {
for (const { name, fn } of tests) {