#Toggle button state

5 messages · Page 1 of 1 (latest)

gaunt veldt
#

Hi,
I am using a toggle button to switch between the light and dark mode. Currently I am using this to toggle the switch to correct option if the dark mode is selected

      document.getElementById("check").checked = true;
      document.getElementById("check2").checked = true;
    } else {
      document.getElementById("check").checked = false;
      document.getElementById("check2").checked = false;
    }
  };

and this is my toggle switch

<label for="check" class="relative h-6 w-12 cursor-pointer rounded-full bg-geraldine-500">
  <input class="peer sr-only" type="checkbox" id="check" toggle-color-scheme />
  <span class="absolute left-1 top-1 h-4/6 w-1/3 rounded-full bg-white transition-all duration-500 peer-checked:left-7 peer-checked:bg-dark-600 shadow-lg"></span>
</label>

It works, but since it's a window.onload function, the toggle switches position on every refresh or clicking to another page. Is there a better way to do this? I come from mostly html background.

agile vector
#

To get darkmode set up as soon as the js is loaded you don't want to wrap that logic inside an onload, because it's gonna wait for other resources before running which causes the flashes you witnessed.

gaunt veldt
#

This is the entire script -

<script is:inline>
  // Set "light" theme as default
  // if (!localStorage.theme) {
  //   localStorage.theme = "light";
  // }
  if (localStorage.theme === "dark" || (!("theme" in localStorage) && window.matchMedia("(prefers-color-scheme: dark)").matches)) {
    document.documentElement.classList.add("dark");
  } else {
    document.documentElement.classList.remove("dark");
  }
  function attachEvent(selector, event, fn) {
    const matches = document.querySelectorAll(selector);
    if (matches && matches.length) {
      matches.forEach((elem) => {
        elem.addEventListener(event, () => fn(elem), false);
      });
    }
  }
  window.onload = function () {
    attachEvent("[toggle-menu]", "click", function (elem) {
      elem.classList.toggle("expanded");
      document.body.classList.toggle("overflow-hidden");
      document.getElementById("menu")?.classList.toggle("hidden");
    });
    attachEvent("[toggle-color-scheme]", "click", function () {
      document.documentElement.classList.toggle("dark");
      localStorage.theme = document.documentElement.classList.contains("dark") ? "dark" : "light";
    });
    if (localStorage.theme === "dark" || (!("theme" in localStorage) && window.matchMedia("(prefers-color-scheme: dark)").matches)) {
      document.getElementById("check").checked = true;
      document.getElementById("check2").checked = true;
    } else {
      document.getElementById("check").checked = false;
      document.getElementById("check2").checked = false;
    }
  };
  window.onpageshow = function () {
    const elem = document.querySelector("[toggle-menu]");
    if (elem) {
      elem.classList.remove("expanded");
    }
    document.body.classList.remove("overflow-hidden");
    document.getElementById("menu")?.classList.add("hidden");
  };
</script>

Can I use props maybe to change the toggle state?

agile vector
#

Do you mean props passed down to that astro component?

gaunt veldt
#

yes