AdminLTE icon indicating copy to clipboard operation
AdminLTE copied to clipboard

[BUG] Bootstrap 5.3 Theme Switch javascript needs to load in the header

Open burdittw opened this issue 1 year ago • 8 comments

Describe the bug Because the current script is in the bottom of the body it loads after the page renders and creates a white flash on the screen. If you refresh the page over and over really fast, you will really see it. In order to get rid of the flash the code needs to be loaded before the page renders. On the Bootstrap page they do this by calling the color-modes.js file in the header. Another way to get rid of it might be to have an overlay screen load first but that seems like a lot of work for a fix and not knowing how others will use the project.

To Reproduce Steps to reproduce the behavior:

  1. Load the page
  2. Flip to dark mode
  3. Hit "Ctrl + R" really fast a few times
  4. Watch the screen flash white then turn to dark.

Expected behavior Page should render dark without the white page loading first then flipping over to dark while loading

Environment (please complete the following information):

  • AdminLTE Version: v4.0-alpha1
  • Operating System: Windows 11/10
  • Browser (Version): Edge(Latest)/Chrome(Latest)

burdittw avatar Mar 24 '23 03:03 burdittw

@danny007in the theme button has also been updated on the Bootstrap 5.3 docs site.

Here is the changed color-modes.js that is modified to work with your changes as well:

/*!
 * Color mode toggler for Bootstrap's docs (https://getbootstrap.com/)
 * Copyright 2011-2023 The Bootstrap Authors
 * Licensed under the Creative Commons Attribution 3.0 Unported License.
 */

(() => {
  'use strict'

  const storedTheme = localStorage.getItem('theme')

  const getPreferredTheme = () => {
    if (storedTheme) {
      return storedTheme
    }

    return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
  }

  const setTheme = function (theme) {
    if (theme === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches) {
      document.documentElement.setAttribute('data-bs-theme', 'dark')
    } else {
      document.documentElement.setAttribute('data-bs-theme', theme)
    }
  }

  setTheme(getPreferredTheme())

  const showActiveTheme = (theme, focus = false) => {
    const themeSwitcher = document.querySelector('#bd-theme')

    if (!themeSwitcher) {
      return
    }

    const themeSwitcherText = document.querySelector('#bd-theme-text')
    const activeThemeIcon = document.querySelector('.theme-icon-active i')
    const btnToActive = document.querySelector(`[data-bs-theme-value="${theme}"]`)
    const svgOfActiveBtn = btnToActive.querySelector('i').getAttribute('class')

    for (const element of document.querySelectorAll('[data-bs-theme-value]')) {
      element.classList.remove('active')
      element.setAttribute('aria-pressed', 'false')
    }

    btnToActive.classList.add('active')
    btnToActive.setAttribute('aria-pressed', 'true')
    activeThemeIcon.setAttribute('class', svgOfActiveBtn)
    const themeSwitcherLabel = `${themeSwitcherText.textContent} (${btnToActive.dataset.bsThemeValue})`
    themeSwitcher.setAttribute('aria-label', themeSwitcherLabel)

    if (focus) {
      themeSwitcher.focus()
    }
  }

  window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
    if (storedTheme !== 'light' || storedTheme !== 'dark') {
      setTheme(getPreferredTheme())
    }
  })

  window.addEventListener('DOMContentLoaded', () => {
    showActiveTheme(getPreferredTheme())

    for (const toggle of document.querySelectorAll('[data-bs-theme-value]')) {
      toggle.addEventListener('click', () => {
        const theme = toggle.getAttribute('data-bs-theme-value')
        localStorage.setItem('theme', theme)
        setTheme(theme)
        showActiveTheme(theme, true)
      })
    }
  })
})()

And here is the new <li> element for in the topbar.astro:

<li class="nav-item dropdown">
        <button
          class="btn btn-link nav-link py-2 px-0 px-lg-2 dropdown-toggle d-flex align-items-center"
          id="bd-theme"
          type="button"
          aria-expanded="false"
          data-bs-toggle="dropdown"
          data-bs-display="static"
        >
          <span class="theme-icon-active">
            <i class="my-1"></i>
          </span>
          <span class="d-lg-none ms-2" id="bd-theme-text">Toggle theme</span>
        </button>
        <ul
          class="dropdown-menu dropdown-menu-end"
          aria-labelledby="bd-theme-text"
          style="--bs-dropdown-min-width: 8rem;"
        >
          <li>
            <button
              type="button"
              class="dropdown-item d-flex align-items-center active"
              data-bs-theme-value="light"
              aria-pressed="false"
            >
              <i class="fa-regular fa-sun me-2"></i>
              Light
              <i class="fa-solid fa-check ms-auto d-none"></i>
            </button>
          </li>
          <li>
            <button
              type="button"
              class="dropdown-item d-flex align-items-center"
              data-bs-theme-value="dark"
              aria-pressed="false"
            >
              <i class="fa-solid fa-moon me-2"></i>
              Dark
              <i class="fa-solid fa-check ms-auto d-none"></i>
            </button>
          </li>
          <li>
            <button
              type="button"
              class="dropdown-item d-flex align-items-center"
              data-bs-theme-value="auto"
              aria-pressed="true"
            >
              <i class="fa-solid fa-circle-half-stroke me-2"
              ></i>
              Auto
              <i class="fa-solid fa-check ms-auto d-none"></i>
            </button>
          </li>
        </ul>
      </li>

burdittw avatar Mar 29 '23 08:03 burdittw

@burdittw can you create PR in this branch https://github.com/ColorlibHQ/AdminLTE/tree/v4-dev

danny007in avatar May 23 '23 09:05 danny007in

Sure I will try to get some time in and make this PR.

burdittw avatar May 31 '23 06:05 burdittw

So, is this done then?

burdittw avatar May 31 '23 07:05 burdittw

So, is this done then?

I added your code, so please check is that working fine, or else please create PR

danny007in avatar May 31 '23 08:05 danny007in

Alright I will check it out later and let you know.

burdittw avatar May 31 '23 08:05 burdittw

So, is the theme toggler going to be added to the main project or just in the documentation? I see what you added to the documentation, but it has not been added to the project itself.

burdittw avatar Sep 03 '23 08:09 burdittw