@ou-imdt/utils
Version:
Utility library for interactive media development
57 lines (46 loc) • 1.68 kB
JavaScript
import { id, defaultState } from '../Base.js';
// TODO look into stylesheet module - a stylesheet can be adopted by multiple shadowRoots with changes reflected where adopted
// defines a prop to store a CSSStyleSheet instance adopted by document
export const styleSheet = Symbol('styleSheet');
// defines a prop to
export const preferShadow = Symbol('preferShadowStyles');
/**
* manages a light DOM stylesheet to expose internal styling
*/
export default (superClass) => class StyleSheetMixin extends superClass {
static get [defaultState]() {
return {
...super[defaultState],
[preferShadow]: true,
[styleSheet]: null
};
};
constructor() {
super();
this[styleSheet] = new CSSStyleSheet();
};
get #root() {
return (this[preferShadow] && this.shadowRoot) ? this.shadowRoot : document;
}
connectedCallback() {
super.connectedCallback();
this.#root.adoptedStyleSheets.push(this[styleSheet]);
}
disconnectedCallback() {
super.disconnectedCallback();
const index = this.#root.adoptedStyleSheets.indexOf(this[styleSheet]);
this.#root.adoptedStyleSheets.splice(index, 1);
}
updateStyleSheet(styles) {
// console.log('update style sheet', { styles, sheet: this[styleSheet], root: this.#root, current: this[styleSheet].cssRules });
this[styleSheet].replaceSync(styles);
if (this.#root === document) {
// scope styles
[...this[styleSheet].cssRules].forEach((rule, index) => {
if (!(rule instanceof CSSStyleRule)) return;
this[styleSheet].deleteRule(index);
this[styleSheet].insertRule(`#${this[id]} ${rule.cssText}`, index);
});
}
}
}