tickle/modules/utils/createElementStatusModes.mjs
2023-06-07 22:07:47 +02:00

52 lines
1.5 KiB
JavaScript

//@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;