HOW TO IMPLEMENT A SYSTEM-WIDE TOGGLE TO SWITCH BETWEEN THE DEFAULT CURSOR AND A CUSTOM ONE

HOW TO IMPLEMENT A SYSTEM-WIDE TOGGLE TO SWITCH BETWEEN THE DEFAULT CURSOR AND A CUSTOM ONE

This is a solution for Webpack-based project which use PUG markup instead of conventional HTML.
To save setting we are using LocalStorage and Cookies.




MARKUP

li
  .option-wrapper
    input#customCursorToggle(type="checkbox", name="customCursorToggle")
    span.label-text On/off custom cursor support
CSS/SCSS

Take a note that you have to tune styles by yourself to match your project requirements.
Moreover, CSS styles for toggler are not included!


html.normal-cursor,
html.normal-cursor * {
  cursor: auto !important;

}

html.normal-cursor a,
html.normal-cursor button,
html.normal-cursor [role="button"],
html.normal-cursor input[type="button"],
html.normal-cursor input[type="submit"],
html.normal-cursor .dish-edit svg,
html.normal-cursor #printButton,
html.normal-cursor .custom-select .selected,
html.normal-cursor #versionToggle,
html.normal-cursor #tooltipsToggle,
html.normal-cursor #startupPageToggle,
html.normal-cursor #customCursorToggle {
  cursor: pointer !important;
}


html.custom-cursor,
html.custom-cursor *,
html.custom-cursor a,
html.custom-cursor button,
html.custom-cursor [role="button"],
html.custom-cursor input[type="button"],
html.custom-cursor input[type="submit"] {
  cursor: url('../..YOUR-PATH../media/icons/cursor/arrow.png') 0 0, auto !important;
}

html.custom-cursor input[type="text"],
html.custom-cursor textarea,
html.custom-cursor [contenteditable="true"] {
  cursor: text !important;
}
JAVASCRIPT
(function () {
  const STORAGE_KEY = 'useCustomCursor';
  const COOKIE_NAME = 'useCustomCursor';
  const switchInput = document.getElementById('customCursorToggle');

  function setCookie(value) {
    // 1 year expiry. path=/ ensures site-wide.
    document.cookie = COOKIE_NAME + "=" + value + ";path=/;max-age=" + (60*60*24*365);
  }

  function applyState(enabled) {
    document.documentElement.classList.toggle('custom-cursor', enabled);
    document.documentElement.classList.toggle('normal-cursor', !enabled);
    if (switchInput && switchInput.checked !== enabled) switchInput.checked = enabled;
  }

  // init: sync from storage (if script wasn't already run)
  try {
    const saved = localStorage.getItem(STORAGE_KEY);
    applyState(saved === '1');
  } catch (e) { /* ignore */ }

  if (!switchInput) return;
  switchInput.addEventListener('change', (e) => {
    const enabled = !!e.target.checked;
    try { localStorage.setItem(STORAGE_KEY, enabled ? '1' : '0'); } catch (err) {}
    try { setCookie(enabled ? '1' : '0'); } catch (err) {}
    applyState(enabled);
  });
})();
INJECTING THE CODE

The most logical way to implement above mentioned functionality is to call logic
from some-kind of layout template or include that appears globally in the project.
In my case it is “top-panel.pug”, that includes navigational menu on all pages of the project.
Note that “require” is a mandatory word, taking into account that we are dealing with Webpack bundler.


script(defer src=require("../..YOUR-PATH../js/pages/settings/cursor-toggle.js"))