import $ from "jquery";
import throttle from "lodash/throttle";
import CustomProperty from "./CustomProperty";
import MainMenu from "./MainMenu";
/**
* The main application file. You can import it as many times as you want,
* and you will get the same instance
* @class App
*/
class App {
#customProperties = {};
/**
* @private
* @type {Object}
*/
#resizeHandlers = {};
/**
* @public
* @type {MainMenu}
*/
mainMenu;
constructor() {
this.mainMenu = new MainMenu();
this.#setCustomProperties();
window.addEventListener(
"resize",
throttle(() => {
Object.values(this.#resizeHandlers).map((fn) => fn.call(this));
}, 250),
);
}
#setCustomProperties() {
// screen-height
this.addCustomProperty("screen-height", innerHeight + "px");
this.subscribeResize("screen-height", () => {
this.#customProperties["screen-height"].value = innerHeight + "px";
});
// header-height
this.addCustomProperty("header-height", $("#header").outerHeight() + "px");
this.subscribeResize("header-height", () => {
this.#customProperties["header-height"].value =
$("#header").outerHeight() + "px";
});
}
/**
* Creates CustomProperty and keeps it in App instance
* @param {string} name The CSS property name
* @param {string|number} value The CSS property value
* @param {HTMLElement} [ctx=document.documentElement] The DOM Element style with apply to
* @returns this
* @example
* import app from 'App';
* app.addCustomProperty('hello', 'world');
*/
addCustomProperty(name, value, ctx = document.documentElement) {
this.#customProperties[name] = new CustomProperty(name, value, ctx);
return this;
}
/**
* Get CSS property from App instance
* @param {string} name The CSS property name
* @returns {any}
* @example
* import app from 'App';
* app.getCustomProperty('hello');
*/
getCustomProperty(name) {
return this.#customProperties[name].value;
}
/**
* Add handler to window resize event
* @param {string} name The handler identifier
* @param {fn} handler The callback to run on window resize
* @returns this
* @example
* import app from 'App';
* app.subscribeResize('my-resize-handler', () => {console.log('I'm listening to resize')});
*/
subscribeResize(name, handler) {
this.#resizeHandlers[name] = handler;
return this;
}
/**
* Removes handler from window resize event
* @param {string} name The handler identifier
* @returns this
* @example
* import app from 'App';
* app.unsubscribeResize('my-resize-handler');
*/
unsubscribeResize(name) {
delete this.#resizeHandlers[name];
return this;
}
}
let app = app || new App();
export default app;
Source