mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-09-28 14:34:09 -03:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0dd8d74032 |
+1
-1
@@ -81,7 +81,7 @@ body {
|
|||||||
--badge-skip-refresh-glow: var(--color-skip-refresh-glow);
|
--badge-skip-refresh-glow: var(--color-skip-refresh-glow);
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme="dark"] {
|
:root[data-theme="dark"] {
|
||||||
--bg-color: var(--bg-base);
|
--bg-color: var(--bg-base);
|
||||||
--text-color: var(--text-primary);
|
--text-color: var(--text-primary);
|
||||||
--text-muted: var(--text-secondary);
|
--text-muted: var(--text-secondary);
|
||||||
|
|||||||
@@ -572,7 +572,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Dark mode: use each preset's dark-mode accent lightness for visibility.
|
/* Dark mode: use each preset's dark-mode accent lightness for visibility.
|
||||||
These match the --color-accent-l values from [data-theme="dark"][data-theme-preset="..."]
|
These match the --color-accent-l values from :root[data-theme="dark"][data-theme-preset="..."]
|
||||||
in tokens/colors.css so the swatch accurately previews what the theme looks like. */
|
in tokens/colors.css so the swatch accurately previews what the theme looks like. */
|
||||||
|
|
||||||
[data-theme="dark"] .preset-swatch-default {
|
[data-theme="dark"] .preset-swatch-default {
|
||||||
|
|||||||
@@ -78,7 +78,7 @@
|
|||||||
--favorite-glow: oklch(65% 0.15 85 / 0.5);
|
--favorite-glow: oklch(65% 0.15 85 / 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme="dark"] {
|
:root[data-theme="dark"] {
|
||||||
--bg-base: #1a1a1a;
|
--bg-base: #1a1a1a;
|
||||||
--bg-elevated: oklch(25% 0.02 256 / 0.98);
|
--bg-elevated: oklch(25% 0.02 256 / 0.98);
|
||||||
--bg-overlay: oklch(0% 0 0 / 0.75);
|
--bg-overlay: oklch(0% 0 0 / 0.75);
|
||||||
@@ -118,7 +118,7 @@
|
|||||||
|
|
||||||
/* ── Preset: Nord ──────────────────────────────────────────── */
|
/* ── Preset: Nord ──────────────────────────────────────────── */
|
||||||
|
|
||||||
[data-theme-preset="nord"] {
|
:root[data-theme-preset="nord"] {
|
||||||
--color-accent-h: 213;
|
--color-accent-h: 213;
|
||||||
--color-accent-c: 0.18;
|
--color-accent-c: 0.18;
|
||||||
--color-accent-l: 62%;
|
--color-accent-l: 62%;
|
||||||
@@ -152,7 +152,7 @@
|
|||||||
--favorite-glow: oklch(72% 0.14 85 / 0.5);
|
--favorite-glow: oklch(72% 0.14 85 / 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme="dark"][data-theme-preset="nord"] {
|
:root[data-theme="dark"][data-theme-preset="nord"] {
|
||||||
--color-accent-h: 213;
|
--color-accent-h: 213;
|
||||||
--color-accent-c: 0.18;
|
--color-accent-c: 0.18;
|
||||||
--color-accent-l: 68%;
|
--color-accent-l: 68%;
|
||||||
@@ -188,7 +188,7 @@
|
|||||||
|
|
||||||
/* ── Preset: Midnight ───────────────────────────────────────── */
|
/* ── Preset: Midnight ───────────────────────────────────────── */
|
||||||
|
|
||||||
[data-theme-preset="midnight"] {
|
:root[data-theme-preset="midnight"] {
|
||||||
--color-accent-h: 300;
|
--color-accent-h: 300;
|
||||||
--color-accent-c: 0.15;
|
--color-accent-c: 0.15;
|
||||||
--color-accent-l: 52%;
|
--color-accent-l: 52%;
|
||||||
@@ -222,7 +222,7 @@
|
|||||||
--favorite-glow: oklch(72% 0.16 85 / 0.5);
|
--favorite-glow: oklch(72% 0.16 85 / 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme="dark"][data-theme-preset="midnight"] {
|
:root[data-theme="dark"][data-theme-preset="midnight"] {
|
||||||
--color-accent-h: 300;
|
--color-accent-h: 300;
|
||||||
--color-accent-c: 0.14;
|
--color-accent-c: 0.14;
|
||||||
--color-accent-l: 68%;
|
--color-accent-l: 68%;
|
||||||
@@ -258,7 +258,7 @@
|
|||||||
|
|
||||||
/* ── Preset: Monokai ───────────────────────────────────────── */
|
/* ── Preset: Monokai ───────────────────────────────────────── */
|
||||||
|
|
||||||
[data-theme-preset="monokai"] {
|
:root[data-theme-preset="monokai"] {
|
||||||
--color-accent-h: 190;
|
--color-accent-h: 190;
|
||||||
--color-accent-c: 0.24;
|
--color-accent-c: 0.24;
|
||||||
--color-accent-l: 72%;
|
--color-accent-l: 72%;
|
||||||
@@ -291,7 +291,7 @@
|
|||||||
--favorite-glow: oklch(72% 0.16 85 / 0.5);
|
--favorite-glow: oklch(72% 0.16 85 / 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme="dark"][data-theme-preset="monokai"] {
|
:root[data-theme="dark"][data-theme-preset="monokai"] {
|
||||||
--color-accent-h: 190;
|
--color-accent-h: 190;
|
||||||
--color-accent-c: 0.24;
|
--color-accent-c: 0.24;
|
||||||
--color-accent-l: 72%;
|
--color-accent-l: 72%;
|
||||||
@@ -326,7 +326,7 @@
|
|||||||
|
|
||||||
/* ── Preset: Dracula ───────────────────────────────────────── */
|
/* ── Preset: Dracula ───────────────────────────────────────── */
|
||||||
|
|
||||||
[data-theme-preset="dracula"] {
|
:root[data-theme-preset="dracula"] {
|
||||||
--color-accent-h: 265;
|
--color-accent-h: 265;
|
||||||
--color-accent-c: 0.24;
|
--color-accent-c: 0.24;
|
||||||
--color-accent-l: 68%;
|
--color-accent-l: 68%;
|
||||||
@@ -359,7 +359,7 @@
|
|||||||
--favorite-glow: oklch(72% 0.16 85 / 0.5);
|
--favorite-glow: oklch(72% 0.16 85 / 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme="dark"][data-theme-preset="dracula"] {
|
:root[data-theme="dark"][data-theme-preset="dracula"] {
|
||||||
--color-accent-h: 265;
|
--color-accent-h: 265;
|
||||||
--color-accent-c: 0.24;
|
--color-accent-c: 0.24;
|
||||||
--color-accent-l: 72%;
|
--color-accent-l: 72%;
|
||||||
@@ -394,7 +394,7 @@
|
|||||||
|
|
||||||
/* ── Preset: Solarized ─────────────────────────────────────── */
|
/* ── Preset: Solarized ─────────────────────────────────────── */
|
||||||
|
|
||||||
[data-theme-preset="solarized"] {
|
:root[data-theme-preset="solarized"] {
|
||||||
--color-accent-h: 175;
|
--color-accent-h: 175;
|
||||||
--color-accent-c: 0.18;
|
--color-accent-c: 0.18;
|
||||||
--color-accent-l: 55%;
|
--color-accent-l: 55%;
|
||||||
@@ -429,7 +429,7 @@
|
|||||||
--favorite-glow: oklch(68% 0.16 75 / 0.5);
|
--favorite-glow: oklch(68% 0.16 75 / 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme="dark"][data-theme-preset="solarized"] {
|
:root[data-theme="dark"][data-theme-preset="solarized"] {
|
||||||
--color-accent-h: 175;
|
--color-accent-h: 175;
|
||||||
--color-accent-c: 0.18;
|
--color-accent-c: 0.18;
|
||||||
--color-accent-l: 60%;
|
--color-accent-l: 60%;
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
import { describe, it, expect } from 'vitest';
|
||||||
|
import { readFileSync } from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
// Regression guard: theme palette tokens may only be declared on the root element.
|
||||||
|
//
|
||||||
|
// `applyTheme()` (static/js/utils/uiHelpers.js, and Header.setThemeMode) mirrors
|
||||||
|
// the active mode onto <body> as `data-theme="dark"`, but the theme *preset* is
|
||||||
|
// only ever written to <html> (`data-theme-preset`). While the token blocks in
|
||||||
|
// tokens/colors.css used the bare attribute selector `[data-theme="dark"]`, the
|
||||||
|
// body matched that block on its own and re-declared the DEFAULT dark palette
|
||||||
|
// (#1a1a1a / #2d2d2d), shadowing the preset palette it inherited from <html>.
|
||||||
|
// The page painted the selected preset's accent but the default preset's
|
||||||
|
// backgrounds/surfaces/text, and flipped into that state ~200ms after load when
|
||||||
|
// initTheme() first touched <body> — the accent-tinted background flash on
|
||||||
|
// reload and nav-tab switches, visible under every preset except "default".
|
||||||
|
// Root-scoping the token blocks keeps <body>'s data-theme inert.
|
||||||
|
describe('Theme token scope', () => {
|
||||||
|
const repoRoot = path.resolve(__dirname, '../../..');
|
||||||
|
const read = (rel) => readFileSync(path.join(repoRoot, rel), 'utf-8');
|
||||||
|
const stripComments = (css) => css.replace(/\/\*[\s\S]*?\*\//g, '');
|
||||||
|
|
||||||
|
const COLOR_TOKENS = read('static/css/tokens/colors.css');
|
||||||
|
const BASE_CSS = read('static/css/base.css');
|
||||||
|
|
||||||
|
// Selectors that declare a palette token, e.g. `--bg-base:` / `--lora-surface:`.
|
||||||
|
const tokenDeclaringSelectors = (css) => {
|
||||||
|
const selectors = [];
|
||||||
|
const ruleRe = /([^{}]+)\{([^{}]*)\}/g;
|
||||||
|
let match;
|
||||||
|
while ((match = ruleRe.exec(stripComments(css)))) {
|
||||||
|
const selector = match[1].trim();
|
||||||
|
const declaresPaletteToken = /(^|[;\s])--(?:bg|surface|text|border|color|favorite|lora|badge|card)-[\w-]+\s*:/.test(
|
||||||
|
match[2]
|
||||||
|
);
|
||||||
|
if (declaresPaletteToken) selectors.push(selector);
|
||||||
|
}
|
||||||
|
return selectors;
|
||||||
|
};
|
||||||
|
|
||||||
|
const isRootScoped = (selector) =>
|
||||||
|
selector.split(',').every((part) => /^\s*(:root|html)\b/.test(part));
|
||||||
|
|
||||||
|
it('declares every colors.css palette token on :root', () => {
|
||||||
|
const selectors = tokenDeclaringSelectors(COLOR_TOKENS);
|
||||||
|
expect(selectors.length).toBeGreaterThan(0);
|
||||||
|
expect(selectors.filter((selector) => !isRootScoped(selector))).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('declares every base.css palette alias on :root', () => {
|
||||||
|
const selectors = tokenDeclaringSelectors(BASE_CSS);
|
||||||
|
expect(selectors.length).toBeGreaterThan(0);
|
||||||
|
expect(selectors.filter((selector) => !isRootScoped(selector))).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('keeps dark/preset token blocks anchored to the root element', () => {
|
||||||
|
const css = stripComments(COLOR_TOKENS);
|
||||||
|
expect(css).toContain(':root[data-theme="dark"] {');
|
||||||
|
for (const preset of ['nord', 'midnight', 'monokai', 'dracula', 'solarized']) {
|
||||||
|
expect(css).toContain(`:root[data-theme-preset="${preset}"] {`);
|
||||||
|
expect(css).toContain(`:root[data-theme="dark"][data-theme-preset="${preset}"] {`);
|
||||||
|
}
|
||||||
|
// No bare attribute selector may open a rule: <body> carries data-theme
|
||||||
|
// without the preset, so such a block would re-declare the default palette.
|
||||||
|
expect(css).not.toMatch(/(^|\n)\s*\[data-theme/);
|
||||||
|
expect(stripComments(BASE_CSS)).not.toMatch(/(^|\n)\s*\[data-theme/);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user