dark-mode.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /*!
  2. * This is a Docsy-adapted version of https://github.com/twbs/examples/blob/main/color-modes/js/color-modes.js.
  3. *
  4. * Original header:
  5. *
  6. * Color mode toggler for Bootstrap's docs (https://getbootstrap.com/)
  7. * Copyright 2011-2024 The Bootstrap Authors
  8. * Licensed under the Creative Commons Attribution 3.0 Unported License.
  9. */
  10. (() => {
  11. 'use strict'
  12. const themeKey = 'td-color-theme'
  13. const getStoredTheme = () => localStorage.getItem(themeKey)
  14. const setStoredTheme = theme => localStorage.setItem(themeKey, theme)
  15. const getPreferredTheme = () => {
  16. const storedTheme = getStoredTheme()
  17. if (storedTheme) {
  18. return storedTheme
  19. }
  20. return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
  21. }
  22. const setTheme = theme => {
  23. if (theme === 'auto') {
  24. document.documentElement.setAttribute('data-bs-theme', (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'))
  25. } else {
  26. document.documentElement.setAttribute('data-bs-theme', theme)
  27. }
  28. }
  29. setTheme(getPreferredTheme())
  30. const showActiveTheme = (theme, focus = false) => {
  31. const themeSwitcher = document.querySelector('#bd-theme')
  32. if (!themeSwitcher) {
  33. return
  34. }
  35. const themeSwitcherText = document.querySelector('#bd-theme-text')
  36. const activeThemeIcon = document.querySelector('.theme-icon-active use')
  37. const btnToActive = document.querySelector(`[data-bs-theme-value="${theme}"]`)
  38. const svgOfActiveBtn = btnToActive.querySelector('svg use').getAttribute('href')
  39. document.querySelectorAll('[data-bs-theme-value]').forEach(element => {
  40. element.classList.remove('active')
  41. element.setAttribute('aria-pressed', 'false')
  42. })
  43. btnToActive.classList.add('active')
  44. btnToActive.setAttribute('aria-pressed', 'true')
  45. activeThemeIcon.setAttribute('href', svgOfActiveBtn)
  46. if (themeSwitcherText) {
  47. const themeSwitcherLabel = `${themeSwitcherText.textContent} (${btnToActive.dataset.bsThemeValue})`
  48. themeSwitcher.setAttribute('aria-label', themeSwitcherLabel)
  49. }
  50. if (focus) {
  51. themeSwitcher.focus()
  52. }
  53. }
  54. window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
  55. const storedTheme = getStoredTheme()
  56. if (storedTheme !== 'light' && storedTheme !== 'dark') {
  57. setTheme(getPreferredTheme())
  58. }
  59. })
  60. window.addEventListener('DOMContentLoaded', () => {
  61. showActiveTheme(getPreferredTheme())
  62. document.querySelectorAll('[data-bs-theme-value]')
  63. .forEach(toggle => {
  64. toggle.addEventListener('click', () => {
  65. const theme = toggle.getAttribute('data-bs-theme-value')
  66. setStoredTheme(theme)
  67. setTheme(theme)
  68. showActiveTheme(theme, true)
  69. })
  70. })
  71. })
  72. })()