chore(release): redesign UI tokens and publish styles 0.8.26, ui 0.8.86
Visual-only redesign ("instrument panel"): cool graphite neutrals for light
and dark, layered hairline elevation, larger radii, a mono token for
eyebrows/data, keycap-style solid and secondary buttons, recessed input
wells and tab tracks, a stronger dialog, and a theme-driven focus outline.
No props, outputs or behaviour change.
Also records the already-published csr 0.8.42, styles 0.8.25 and ui 0.8.85
changes (optional chaining/nullish in the reactive runtime, shared
theme/accent cookie sync, BackToTop hidden attribute).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f4eaf416be
commit
1179fc2810
16 files changed
+322
-108
No files matched your search
@@ -0,0 +1,58 @@
|
||||
import { expect, test } from "bun:test";
|
||||
import { Browser } from "happy-dom";
|
||||
import { renderThemeRuntime, resolveThemeConfig } from "../src/theme.ts";
|
||||
|
||||
test("shared preferences replace stale host cookies and update another open app", async () => {
|
||||
const browser = new Browser({ settings: { disableCSSFileLoading: true } });
|
||||
try {
|
||||
const first = browser.newPage();
|
||||
first.url = "https://account.example.com/";
|
||||
const second = browser.newPage();
|
||||
second.url = "https://link.example.com/";
|
||||
const a = first.mainFrame.window;
|
||||
const b = second.mainFrame.window;
|
||||
// Happy DOM coalesces equal-name host/domain cookies. Model their distinct
|
||||
// browser storage keys so the legacy-shadow migration is exercised.
|
||||
const jar = new Map<string, { name: string; value: string; domain: string; hostOnly: boolean }>();
|
||||
function cookies(win: typeof a) {
|
||||
Object.defineProperty(win.document, "cookie", {
|
||||
get() { return [...jar.values()].filter(c => c.hostOnly ? c.domain === win.location.hostname : win.location.hostname === c.domain || win.location.hostname.endsWith("." + c.domain)).map(c => `${c.name}=${c.value}`).join("; "); },
|
||||
set(raw: string) {
|
||||
const [pair, ...options] = raw.split(";");
|
||||
const split = pair!.indexOf("=");
|
||||
const name = pair!.slice(0, split), value = pair!.slice(split + 1);
|
||||
const domainOption = options.find(v => v.trim().toLowerCase().startsWith("domain="));
|
||||
const domain = domainOption ? domainOption.trim().slice(7).replace(/^\./, "") : win.location.hostname;
|
||||
const key = `${name}|${domain}`;
|
||||
if(options.some(v => v.trim().toLowerCase() === "max-age=0")) jar.delete(key);
|
||||
else jar.set(key, { name, value, domain, hostOnly: !domainOption });
|
||||
},
|
||||
});
|
||||
}
|
||||
cookies(a); cookies(b);
|
||||
a.document.cookie = "wrn-theme=light;path=/";
|
||||
b.document.cookie = "wrn-theme=light;path=/";
|
||||
a.document.cookie = "wrn-theme=dark;path=/;domain=.example.com;secure";
|
||||
a.document.cookie = "wrn-accent=rose;path=/;domain=.example.com;secure";
|
||||
const js = renderThemeRuntime(resolveThemeConfig({ palette: "emerald" }, { defaults: { domain: ".example.com", secure: true } }));
|
||||
for (const win of [a, b]) {
|
||||
win.document.documentElement.setAttribute("data-theme", "light");
|
||||
win.document.documentElement.setAttribute("data-accent", "emerald");
|
||||
win.eval(js);
|
||||
expect(win.document.documentElement.getAttribute("data-theme")).toBe("dark");
|
||||
expect(win.document.cookie.match(/wrn-theme=/g)?.length).toBe(1);
|
||||
}
|
||||
a.eval('wrnTheme.set("light");wrnAccent.set("violet");wrnCookies.set("wrn-lang","hi","language")');
|
||||
expect(b.document.cookie).toContain("wrn-theme-mode=manual");
|
||||
b.dispatchEvent(new b.Event("focus"));
|
||||
expect(b.document.documentElement.getAttribute("data-theme")).toBe("light");
|
||||
expect(b.document.documentElement.getAttribute("data-accent")).toBe("violet");
|
||||
expect(b.document.cookie).toContain("wrn-lang=hi");
|
||||
a.eval('wrnTheme.followSystem()');
|
||||
expect(b.document.cookie).toContain("wrn-theme-mode=system");
|
||||
const outsider = browser.newPage();
|
||||
outsider.url = "https://unrelated.example.net/";
|
||||
cookies(outsider.mainFrame.window);
|
||||
expect(outsider.mainFrame.window.document.cookie).toBe("");
|
||||
} finally { await browser.close(); }
|
||||
});
|
||||
Reference in new issue
Block a user