52 lines
1.5 KiB
JavaScript
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;
|