mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-12 12:06:16 -08:00
fix(ui): scope the dark app surface to body.dark-theme
The global `.dark-theme { background: var(--mat-sys-surface) !important }`
rule was inert while --mat-sys-surface did not exist. Now that it resolves,
it also painted every component that carries `dark-theme` only for its
tokens: the playback diagnostic's alternative sources lost their #161b24
surface to #121316, in the light app theme too. Move the background to
body.dark-theme, the element SettingsService toggles, and drop the fullscreen
channel panel's !important override that only existed to outrank the old
rule.
theme-tokens.e2e.ts checks in both themes that a nested `dark-theme`
element keeps its own background and that the dark body takes the surface.
Without this change, the nested element reads rgb(18, 19, 22).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
14fd2897e2
commit
d08a9f90d0
3 files changed
+46
-7
No files matched your search
@@ -46,6 +46,18 @@ async function outlineContrast(
|
||||
}, fillSelector);
|
||||
}
|
||||
|
||||
/** Resolves a CSS color (including var() and color-mix()) to rgb()/rgba(). */
|
||||
async function resolveColor(page: Page, value: string): Promise<string> {
|
||||
return page.evaluate((css) => {
|
||||
const probe = document.createElement('div');
|
||||
probe.style.color = css;
|
||||
document.body.appendChild(probe);
|
||||
const color = getComputedStyle(probe).color;
|
||||
probe.remove();
|
||||
return color;
|
||||
}, value);
|
||||
}
|
||||
|
||||
async function systemVariable(page: Page, name: string): Promise<string> {
|
||||
return page.evaluate(
|
||||
(variable) =>
|
||||
@@ -87,6 +99,30 @@ test.describe('Theme tokens', () => {
|
||||
'--mat-sys-surface'
|
||||
);
|
||||
|
||||
// The dark surface belongs to the app host. Components that
|
||||
// carry `dark-theme` for its tokens (the fullscreen channel
|
||||
// panel, the diagnostic's alternative sources) keep their own.
|
||||
const backgrounds = await page.evaluate(() => {
|
||||
const nested = document.createElement('div');
|
||||
nested.className = 'dark-theme';
|
||||
nested.style.background = 'rgb(22, 27, 36)';
|
||||
document.body.appendChild(nested);
|
||||
const result = {
|
||||
nested: getComputedStyle(nested).backgroundColor,
|
||||
body: getComputedStyle(document.body).backgroundColor,
|
||||
};
|
||||
nested.remove();
|
||||
return result;
|
||||
});
|
||||
expect(backgrounds.nested, `nested in ${theme} theme`).toBe(
|
||||
'rgb(22, 27, 36)'
|
||||
);
|
||||
if (theme === 'dark') {
|
||||
expect(backgrounds.body).toBe(
|
||||
await resolveColor(page, 'var(--mat-sys-surface)')
|
||||
);
|
||||
}
|
||||
|
||||
// Form-field overrides must reach Material's --mat-* tokens
|
||||
// (the retired --mdc-* names were ignored): the outline takes
|
||||
// the app's 10px shape instead of the 4px M3 default.
|
||||
|
||||
@@ -164,8 +164,14 @@ textarea,
|
||||
}
|
||||
|
||||
// ─── Dark Theme ───────────────────────────────────────────────────────────────
|
||||
.dark-theme {
|
||||
// Only the app host takes the dark surface: components such as the fullscreen
|
||||
// channel panel and the playback diagnostic's alternative sources carry
|
||||
// `dark-theme` for its tokens while painting their own surfaces.
|
||||
body.dark-theme {
|
||||
background: var(--mat-sys-surface) !important;
|
||||
}
|
||||
|
||||
.dark-theme {
|
||||
color-scheme: dark;
|
||||
|
||||
// Refined scrollbar for dark mode
|
||||
|
||||
+3
-6
@@ -117,13 +117,10 @@
|
||||
visibility 0s linear 220ms;
|
||||
}
|
||||
|
||||
// The controls' glass fill over the video. The panel carries `dark-theme` for its tokens, and the app's global
|
||||
// `.dark-theme { background: var(--mat-sys-surface) !important }`
|
||||
// (apps/web/src/styles.scss) would replace this gradient with the flat
|
||||
// surface — or with no background at all where that token is not defined —
|
||||
// so the compound selector and `!important` are required to out-rank it.
|
||||
// The controls' glass fill over the video. The panel carries `dark-theme` for
|
||||
// its tokens only; the app's dark surface is scoped to body.dark-theme.
|
||||
.fullscreen-channel-panel.dark-theme {
|
||||
background: rgba(12, 16, 23, 0.72) !important;
|
||||
background: rgba(12, 16, 23, 0.72);
|
||||
}
|
||||
|
||||
.fullscreen-channel-panel--open {
|
||||
|
||||
Reference in new issue
Block a user