Skip to content

Commit

Permalink
feat: implement bootstrap theme switcher
Browse files Browse the repository at this point in the history
  • Loading branch information
paulovareiro29 committed Oct 22, 2024
1 parent 0fce327 commit 5adfe24
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 49 deletions.
124 changes: 82 additions & 42 deletions src/js/darkmode.js
Original file line number Diff line number Diff line change
@@ -1,50 +1,90 @@
function updateDarkmodeIcons() {
const isDarkmode = document.documentElement.hasAttribute('data-bs-theme')
;(() => {
'use strict'

document.querySelectorAll('[toggle-dark-mode] i').forEach((icon) => {
const remove = isDarkmode ? 'bi-moon-fill' : 'bi-sun-fill'
const add = isDarkmode ? 'bi-sun-fill' : 'bi-moon-fill'
const getStoredTheme = () => localStorage.getItem('theme')
const setStoredTheme = (theme) => localStorage.setItem('theme', theme)

icon.classList.remove(remove)
icon.classList.add(add)
})
}

function removeDarkmode() {
document.documentElement.removeAttribute('data-bs-theme')
localStorage.removeItem('theme')
updateDarkmodeIcons()
}

function setDarkmode() {
document.documentElement.setAttribute('data-bs-theme', 'dark')
localStorage.setItem('theme', 'dark')
updateDarkmodeIcons()
}

function toggleDarkmode() {
if (document.documentElement.hasAttribute('data-bs-theme')) {
removeDarkmode()
} else {
setDarkmode()
const getPreferredTheme = () => {
const storedTheme = getStoredTheme()
if (storedTheme) {
return storedTheme
}

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

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

function loadTheme() {
const theme = localStorage.getItem('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')
const btnToActive = document.querySelector(
`[data-bs-theme-value="${theme}"]`
)
const svgOfActiveBtn = btnToActive.querySelector('i[data-bs-theme-icon]')
.dataset.bsThemeIcon

if (theme) {
setDarkmode()
} else {
removeDarkmode()
document.querySelectorAll('[data-bs-theme-value]').forEach((element) => {
element.classList.remove('active')
element.setAttribute('aria-pressed', 'false')
})

const allIcons = Array.from(
document.querySelectorAll('[data-bs-theme-value] > i[data-bs-theme-icon]')
).map((i) => i.dataset.bsThemeIcon)
allIcons.forEach((i) => activeThemeIcon.classList.remove(i))

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

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

document.addEventListener('DOMContentLoaded', () => {
updateDarkmodeIcons()
document.querySelectorAll('[toggle-dark-mode]').forEach((button) => {
button.addEventListener('click', toggleDarkmode)
})
})
window
.matchMedia('(prefers-color-scheme: dark)')
.addEventListener('change', () => {
const storedTheme = getStoredTheme()
if (storedTheme !== 'light' && storedTheme !== 'dark') {
setTheme(getPreferredTheme())
}
})

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

loadTheme()
document.querySelectorAll('[data-bs-theme-value]').forEach((toggle) => {
toggle.addEventListener('click', () => {
const theme = toggle.getAttribute('data-bs-theme-value')
setStoredTheme(theme)
setTheme(theme)
showActiveTheme(theme, true)
})
})
})
})()
8 changes: 3 additions & 5 deletions src/partials/base/b_header.twig
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,9 @@
</button>
</div>
<div class='offcanvas-body d-flex flex-column justify-content-between'>
<ul class='nav flex-column align-items-start flex-xl-row fs-5 pb-3 pb-xl-0 border-bottom'>
<li>
<button toggle-dark-mode class='btn nav-link rounded-0' aria-label='Toggle dark mode'>
<i class='bi bi-moon-fill'></i>
</button>
<ul class='nav flex-column align-items-start flex-xl-row align-items-xl-center fs-5 pb-3 pb-xl-0 border-bottom'>
<li class='nav-item'>
{% include 'partials::base/b_theme-switcher.twig' %}
</li>
<li><a href='./overview' class='nav-link'>Daten</a></li>
<li><a href='#' class='nav-link'>News</a></li>
Expand Down
52 changes: 52 additions & 0 deletions src/partials/base/b_theme-switcher.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<div class='dropdown'>
<button
class='btn btn-link nav-link py-2 px-0 px-xl-2 dropdown-toggle d-flex align-items-center'
id='bd-theme'
type='button'
aria-expanded='false'
data-bs-toggle='dropdown'
data-bs-display='static'
aria-label='Umschaltthema (auto)'
>
<i class='bi bi-sun-fill my-1 theme-icon-active'></i>
<span class='d-xl-none ms-2' id='bd-theme-text'>Umschaltthema</span>
</button>
<ul class='dropdown-menu dropdown-menu-end' aria-labelledby='bd-theme-text'>
<li>
<button
type='button'
class='dropdown-item d-flex align-items-center active'
data-bs-theme-value='light'
aria-pressed='true'
>
<i class='bi bi-sun-fill me-2 opacity-50' data-bs-theme-icon='bi-sun-fill'></i>
Licht
<i class='bi bi-check2 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='bi bi-moon-stars-fill me-2 opacity-50' data-bs-theme-icon='bi-moon-stars-fill'></i>
Dunkel
<i class='bi bi-check2 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='false'
>
<i class='bi bi-circle-half me-2 opacity-50' data-bs-theme-icon='bi-circle-half'></i>
Auto
<i class='bi bi-check2 ms-auto d-none'></i>
</button>
</li>
</ul>
</div>
10 changes: 8 additions & 2 deletions src/styles/components/_header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@
--focus-ring-color: var(--color-on-primary);
}

.link {
.link,
.btn-link {
--link-color-rgb: var(--header-link-color);

&:hover {
Expand Down Expand Up @@ -78,6 +79,11 @@
border: 0;
padding: 0;
}

#bd-theme {
padding-top: 4px !important;
padding-bottom: 4px !important;
}
}

[data-bs-theme='dark'] .header {
Expand All @@ -87,7 +93,7 @@
--focus-ring-color: var(--primary);
}
}

.logo {
filter: brightness(0) invert(1);
}
Expand Down

0 comments on commit 5adfe24

Please sign in to comment.