Skip to content

Commit a3d8d7a

Browse files
dkimmich-onventisjson-derulo
authored andcommitted
feat: allow custom root selector
1 parent a314ee5 commit a3d8d7a

File tree

3 files changed

+52
-1
lines changed

3 files changed

+52
-1
lines changed

projects/material-css-vars/src/lib/material-css-vars.service.spec.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,4 +218,32 @@ describe("MaterialCssVarsService", () => {
218218
);
219219
});
220220
});
221+
222+
describe("_getRootElement", () => {
223+
it("should return the html if no root selector is set", () => {
224+
const rootElement = service["_getRootElement"](undefined);
225+
226+
expect(rootElement).toBe(document.documentElement);
227+
});
228+
229+
it("should return the element matching the root selector", () => {
230+
const mockElement = document.createElement("app-root");
231+
const spy = spyOn(document, "querySelector").and.returnValue(mockElement);
232+
233+
const rootElement = service["_getRootElement"]("app-root");
234+
235+
expect(rootElement).toBe(mockElement);
236+
expect(spy).toHaveBeenCalledWith("app-root");
237+
});
238+
239+
it("should warn and fall back to the html element if the passed root selector cannot be found", () => {
240+
spyOn(console, "warn");
241+
spyOn(document, "querySelector").and.returnValue(null);
242+
243+
const rootElement = service["_getRootElement"]("non-existing");
244+
245+
expect(rootElement).toBe(document.documentElement);
246+
expect(console.warn).toHaveBeenCalledTimes(1);
247+
});
248+
});
221249
});

projects/material-css-vars/src/lib/material-css-vars.service.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
RendererFactory2,
66
RendererStyleFlags2,
77
DOCUMENT,
8+
isDevMode,
89
} from "@angular/core";
910
import { Numberify, RGBA, TinyColor } from "@ctrl/tinycolor";
1011
import {
@@ -58,7 +59,7 @@ export class MaterialCssVarsService {
5859
@Inject(MATERIAL_CSS_VARS_CFG) cfg: MaterialCssVariablesConfig,
5960
) {
6061
this.renderer = rendererFactory.createRenderer(null, null);
61-
this.ROOT = this.document.documentElement;
62+
this.ROOT = this._getRootElement(cfg.rootSelector);
6263

6364
this.cfg = {
6465
...DEFAULT_MAT_CSS_CFG,
@@ -433,4 +434,20 @@ export class MaterialCssVarsService {
433434
const darkest = Math.min(luminance1, luminance2);
434435
return (brightest + 0.05) / (darkest + 0.05);
435436
}
437+
438+
private _getRootElement(rootSelector: string | undefined): HTMLElement {
439+
if (typeof rootSelector !== "string") {
440+
return this.document.documentElement;
441+
}
442+
const rootElement = document.querySelector<HTMLElement>(rootSelector);
443+
if (rootElement) {
444+
return rootElement;
445+
}
446+
if (isDevMode()) {
447+
console.warn(
448+
`[MaterialCssVars] Could not find root element: ${rootSelector}. Falling back to HTML element.`,
449+
);
450+
}
451+
return this.document.documentElement;
452+
}
436453
}

projects/material-css-vars/src/lib/model.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ export interface MaterialCssVariablesConfig {
5454
darkThemeClass: string;
5555
lightThemeClass: string;
5656

57+
/**
58+
* Selector to which the CSS variables are added.
59+
* If not specified, the document's HTML element is used.
60+
*/
61+
rootSelector?: string;
62+
5763
colorMap: MaterialCssColorMapperEntry[];
5864
sortedHues: HueValue[];
5965

0 commit comments

Comments
 (0)