Make a mixin for loading a stylesheet for components, including HMR auto-update support (only in devMode)
This commit is contained in:
parent
fde3881653
commit
f2c169c077
4 changed files with 121 additions and 55 deletions
80
module/components/mixins/Styles.mjs
Normal file
80
module/components/mixins/Styles.mjs
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/**
|
||||
* @param {HTMLElement} Base
|
||||
*/
|
||||
export function StyledShadowElement(Base) {
|
||||
return class extends Base {
|
||||
/**
|
||||
* The path to the CSS that is loaded
|
||||
* @type {string}
|
||||
*/
|
||||
static _stylePath;
|
||||
|
||||
/**
|
||||
* The stringified CSS to use
|
||||
* @type {string}
|
||||
*/
|
||||
static _styles;
|
||||
|
||||
/**
|
||||
* The HTML element of the stylesheet
|
||||
* @type {HTMLStyleElement}
|
||||
*/
|
||||
_style;
|
||||
|
||||
/** @type {ShadowRoot} */
|
||||
_shadow;
|
||||
|
||||
/**
|
||||
* The hook ID for this element's CSS hot reload
|
||||
* @type {number}
|
||||
*/
|
||||
#cssHmr;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this._shadow = this.attachShadow({ mode: `open` });
|
||||
this._style = document.createElement(`style`);
|
||||
this._shadow.appendChild(this._style);
|
||||
};
|
||||
|
||||
#mounted = false;
|
||||
connectedCallback() {
|
||||
if (this.#mounted) return;
|
||||
|
||||
this._getStyles();
|
||||
|
||||
if (game.settings.get(`dotdungeon`, `devMode`)) {
|
||||
this.#cssHmr = Hooks.on(`dd-hmr:css`, (data) => {
|
||||
if (data.path.endsWith(this.constructor._stylePath)) {
|
||||
this._style.innerHTML = data.content;
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
this.#mounted = true;
|
||||
};
|
||||
|
||||
disconnectedCallback() {
|
||||
if (!this.#mounted) return;
|
||||
if (this.#cssHmr != null) {
|
||||
Hooks.off(`dd-hmr:css`, this.#cssHmr);
|
||||
this.#cssHmr = null;
|
||||
};
|
||||
this.#mounted = false;
|
||||
};
|
||||
|
||||
_getStyles() {
|
||||
if (this.constructor._styles) {
|
||||
this._style.innerHTML = this.constructor._styles;
|
||||
} else {
|
||||
fetch(`./systems/dotdungeon/.styles/${this.constructor._stylePath}`)
|
||||
.then(r => r.text())
|
||||
.then(t => {
|
||||
this.constructor._styles = t;
|
||||
this._style.innerHTML = t;
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue