//@ts-check /** * * Creates exclusive states for an HTML element. These states are added as classes * and can be used to drive CSS changes. * @param {string[]} allModes A string list of all possible modes. It's advised * to prepend (`state-` or `mode-` to each for clarity) * @param {Element} [element] the element to add the classes to. Defaults to the * document's body */ export const createElementStatusModes = (allModes, element = document.body) => { /** * @param {any} mode * @returns {mode is number} */ const isValidIndex = (mode) => typeof mode === "number" && mode >= 0 && mode < allModes.length; /** * Sets a status mode (class name) on the element. * Pass a falsy value to clear all modes * @param {number|null|undefined|false} mode */ const set = (mode = false) => { mode = isValidIndex(mode) ? mode : -1; const modeClass = allModes[mode]; if (modeClass && element.classList.contains(modeClass)) { return; } element.classList.remove(...allModes); element.classList.add(modeClass); }; /** * Verifies which of the given classes is set. * @returns {string|undefined} the class if there is one */ const get = () => allModes.find((className) => element.classList.contains(className)); /** * @param {number} state */ const is = (state) => isValidIndex(state) && document.body.classList.contains(allModes[state]); return { set, get, is }; }; export default createElementStatusModes;