web: fix theme not applying to document correctly (#10721)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens L.
2024-08-01 15:08:09 +02:00
committed by GitHub
parent 63ff967d79
commit bd8d35bf3f
2 changed files with 27 additions and 12 deletions

View File

@ -126,7 +126,7 @@ export class AKElement extends LitElement {
ev?.matches || this._mediaMatcher?.matches
? UiThemeEnum.Light
: UiThemeEnum.Dark;
this._activateTheme(root, theme);
this._activateTheme(theme, root);
};
this._mediaMatcherHandler(undefined);
this._mediaMatcher.addEventListener("change", this._mediaMatcherHandler);
@ -138,7 +138,7 @@ export class AKElement extends LitElement {
this._mediaMatcher.removeEventListener("change", this._mediaMatcherHandler);
this._mediaMatcher = undefined;
}
this._activateTheme(root, theme);
this._activateTheme(theme, root);
}
static themeToStylesheet(theme?: UiThemeEnum): CSSStyleSheet | undefined {
@ -148,7 +148,11 @@ export class AKElement extends LitElement {
return undefined;
}
_activateTheme(root: DocumentOrShadowRoot, theme: UiThemeEnum) {
/**
* Directly activate a given theme, accepts multiple document/ShadowDOMs to apply the stylesheet
* to. The stylesheets are applied to each DOM in order. Does nothing if the given theme is already active.
*/
_activateTheme(theme: UiThemeEnum, ...roots: DocumentOrShadowRoot[]) {
if (theme === this._activeTheme) {
return;
}
@ -163,12 +167,19 @@ export class AKElement extends LitElement {
this.setAttribute("theme", theme);
const stylesheet = AKElement.themeToStylesheet(theme);
const oldStylesheet = AKElement.themeToStylesheet(this._activeTheme);
if (stylesheet) {
root.adoptedStyleSheets = [...root.adoptedStyleSheets, ensureCSSStyleSheet(stylesheet)];
}
if (oldStylesheet) {
root.adoptedStyleSheets = root.adoptedStyleSheets.filter((v) => v !== oldStylesheet);
}
roots.forEach((root) => {
if (stylesheet) {
root.adoptedStyleSheets = [
...root.adoptedStyleSheets,
ensureCSSStyleSheet(stylesheet),
];
}
if (oldStylesheet) {
root.adoptedStyleSheets = root.adoptedStyleSheets.filter(
(v) => v !== oldStylesheet,
);
}
});
this._activeTheme = theme;
this.requestUpdate();
}

View File

@ -50,15 +50,19 @@ export class Interface extends AKElement implements AkInterface {
this.dataset.akInterfaceRoot = "true";
}
_activateTheme(root: DocumentOrShadowRoot, theme: UiThemeEnum): void {
_activateTheme(theme: UiThemeEnum, ...roots: DocumentOrShadowRoot[]): void {
if (theme === this._activeTheme) {
return;
}
console.debug(
`authentik/interface[${rootInterface()?.tagName.toLowerCase()}]: Enabling theme ${theme}`,
);
super._activateTheme(document as unknown as DocumentOrShadowRoot, theme);
super._activateTheme(root, theme);
// Special case for root interfaces, as they need to modify the global document CSS too
// Instead of calling ._activateTheme() twice, we insert the root document in the call
// since multiple calls to ._activateTheme() would not do anything after the first call
// as the theme is already enabled.
roots.unshift(document as unknown as DocumentOrShadowRoot);
super._activateTheme(theme, ...roots);
}
async getTheme(): Promise<UiThemeEnum> {