Skip to main content

Using viewtransition for dark mode in astro

I am trying to implement the new viewtransition, in my project in astro, the problem is I have found documentation on how to fix the dark mode issue when chaging routes, but I am using a little different code and because of that it does not work, my code:

  // Get the theme toggle input
  const themeToggle: HTMLInputElement = document.querySelector(
    '.theme-switch input[type="checkbox"]'
  );

  // Get the current theme from local storage
  const currentTheme = localStorage.getItem("theme");

  // If the current local storage item can be found
  if (currentTheme) {
    // Set the body data-theme attribute to match the local storage item
    document.documentElement.setAttribute("data-theme", currentTheme);

    // If the current theme is dark, check the theme toggle
    if (currentTheme === "dark") {
      themeToggle.checked = true;
    }
  }

  // Function that will switch the theme based on the if the theme toggle is checked or not
  function switchTheme(e) {
    if (e.target.checked) {
      document.documentElement.setAttribute("data-theme", "dark");
      localStorage.setItem("theme", "dark");
    } else {
      document.documentElement.setAttribute("data-theme", "default");
      localStorage.setItem("theme", "default");
    }
  }

  // Add an event listener to the theme toggle, which will switch the theme
  themeToggle.addEventListener("change", switchTheme, false);
  document.addEventListener("astro:after-swap", switchTheme, false);
  /* TOGGLE  */
  .theme-switch-wrapper {
    margin-inline: 20px;
    display: inline-block;
    /* justify-content: flex-end; */
    /* align-items: center; */
  }

  .theme-switch {
    display: inline-block;
    height: 34px;
    position: relative;
    width: 60px;
  }

  .theme-switch input {
    display: none;
  }

  .slider {
    background-color: #dddddd;
    bottom: 0;
    cursor: pointer;
    left: 0;
    position: absolute;
    right: 0;
    top: 0;
    transition: 0.4s;
    border-radius: 34px;
  }

  .slider:before {
    background-color: #fff;
    bottom: 4px;
    content: "";
    height: 26px;
    left: 4px;
    position: absolute;
    transition: 0.4s;
    width: 26px;
    border-radius: 50%;
  }

  input:checked + .slider {
    background-color: #8758ff;
  }

  input:checked + .slider:before {
    transform: translateX(26px);
  }

  .slider svg {
    color: #222;
    position: absolute;
    transition: opacity 0.2s ease 0s, transform 0.35s ease 0s;
    pointer-events: none;
  }

  .feather-moon {
    opacity: 0;
    left: 9px;
    bottom: 9px;
    transform: translateX(4px);
  }

  .feather-sun {
    opacity: 1;
    right: 10px;
    bottom: 9px;
    transform: translateX(0px);
  }

  input:checked + .slider .feather-moon {
    opacity: 1;
    transform: translateX(0);
  }

  input:checked + .slider .feather-sun {
    opacity: 0;
    transform: translateX(-4px);
  }
<div class="theme-switch-wrapper py-2 mt-1">
  <label class="theme-switch" for="checkbox">
    <input type="checkbox" id="checkbox" />
    <div class="slider">
      <svg
        xmlns="http://www.w3.org/2000/svg"
        width="16"
        height="16"
        viewBox="0 0 24 24"
        fill="#FCD53F"
        stroke="currentColor"
        stroke-width="2"
        stroke-linecap="round"
        stroke-linejoin="round"
        class="feather feather-sun"
      >
        <circle cx="12" cy="12" r="5"></circle>
        <line x1="12" y1="1" x2="12" y2="3"></line>
        <line x1="12" y1="21" x2="12" y2="23"></line>
        <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
        <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
        <line x1="1" y1="12" x2="3" y2="12"></line>
        <line x1="21" y1="12" x2="23" y2="12"></line>
        <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
        <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
      </svg>
      <svg
        xmlns="http://www.w3.org/2000/svg"
        width="16"
        height="16"
        viewBox="0 0 24 24"
        fill="#FCD53F"
        stroke="currentColor"
        stroke-width="2"
        stroke-linecap="round"
        stroke-linejoin="round"
        class="feather feather-moon"
      >
        <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
      </svg>
    </div>
  </label>
</div>

So the Problem is I am using a checkbox for the project and most of the projects I've seen that use darkmode with viewtransitions, they use buttons, but my problem I think is that as I am using the change method of the checkbox, and the function I am using, it is made for used when the checkbox changes state, but to make the dark mode button persistent I have to use this EventListener:

  document.addEventListener("astro:after-swap", switchTheme, false);

and because it is not triggered by the checkbox that is why it does not work, those are my thoughts but I don't know how to fix it so please help me.

the real problem is that the button works but when I change routes it goes to default theme, but the checkbox is still on, so the localstorage that is supposed to be persistent, it is not

Via Active questions tagged javascript - Stack Overflow https://ift.tt/pzcOI1j

Comments

Popular posts from this blog

Prop `className` did not match in next js app

I have written a sample code ( Github Link here ). this is a simple next js app, but giving me error when I refresh the page. This seems to be the common problem and I tried the fix provided in the internet but does not seem to fix my issue. The error is Warning: Prop className did not match. Server: "MuiBox-root MuiBox-root-1" Client: "MuiBox-root MuiBox-root-2". Did changes for _document.js, modified _app.js as mentioned in official website and solutions in stackoverflow. but nothing seems to work. Could someone take a look and help me whats wrong with the code? Via Active questions tagged javascript - Stack Overflow https://ift.tt/2FdjaAW

How to show number of registered users in Laravel based on usertype?

i'm trying to display data from the database in the admin dashboard i used this: <?php use Illuminate\Support\Facades\DB; $users = DB::table('users')->count(); echo $users; ?> and i have successfully get the correct data from the database but what if i want to display a specific data for example in this user table there is "usertype" that specify if the user is normal user or admin i want to user the same code above but to display a specific usertype i tried this: <?php use Illuminate\Support\Facades\DB; $users = DB::table('users')->count()->WHERE usertype =admin; echo $users; ?> but it didn't work, what am i doing wrong? source https://stackoverflow.com/questions/68199726/how-to-show-number-of-registered-users-in-laravel-based-on-usertype

Why is my reports service not connecting?

I am trying to pull some data from a Postgres database using Node.js and node-postures but I can't figure out why my service isn't connecting. my routes/index.js file: const express = require('express'); const router = express.Router(); const ordersCountController = require('../controllers/ordersCountController'); const ordersController = require('../controllers/ordersController'); const weeklyReportsController = require('../controllers/weeklyReportsController'); router.get('/orders_count', ordersCountController); router.get('/orders', ordersController); router.get('/weekly_reports', weeklyReportsController); module.exports = router; My controllers/weeklyReportsController.js file: const weeklyReportsService = require('../services/weeklyReportsService'); const weeklyReportsController = async (req, res) => { try { const data = await weeklyReportsService; res.json({data}) console