Quellcode durchsuchen

Added default theme (#960)

* feat: Added default theme

* Revert "feat: Added default theme"

This reverts commit a11a99f92a5a307712d76be7ac7adfbc3cc77821.

* feat: Add basic theme feature

* feat: Add theme settings

* fix: Fix default theme value

* fix: Fix CR and doc-string

* Comment out darkMode on exampleSite/hugo.yaml

Signed-off-by: hossainemruz <hossainemruz@gmail.com>

---------

Signed-off-by: hossainemruz <hossainemruz@gmail.com>
Co-authored-by: Emruz Hossain <hossainemruz@gmail.com>
JY Hsu vor 8 Monaten
Ursprung
Commit
7bc37c74c7

+ 4 - 0
assets/scripts/features/index.js

@@ -10,6 +10,10 @@ if (process.env.FEATURE_DARKMODE === '1') {
   import('./darkmode')
 }
 
+if (process.env.FEATURE_THEME === '1') {
+  import('./theme')
+}
+
 if (process.env.FEATURE_FLOWCHART === '1') {
   import('./flowchart')
 }

+ 88 - 0
assets/scripts/features/theme/index.js

@@ -0,0 +1,88 @@
+import * as params from '@params';
+const PERSISTENCE_KEY = 'theme-scheme'
+
+const themeOptions = params.theme || {}
+const THEME_DARK = typeof themeOptions.dark === 'undefined' ? true : themeOptions.dark;
+const THEME_LIGHT = typeof themeOptions.light === 'undefined' ? true : themeOptions.light;
+const THEME_DEFAULT = typeof themeOptions.default === 'undefined' ? "system" : themeOptions.default;
+
+window.addEventListener('load', async () => {
+  const menu = document.getElementById('themeMenu')
+  const $icon = document.getElementById('navbar-theme-icon-svg')
+  if (menu == null || $icon == null) return
+
+  const btns = menu.getElementsByTagName('a')
+  const iconMap = Array.from(btns).reduce((map, btn) => {
+    const $img = btn.getElementsByTagName('img')[0]
+    map[btn.dataset.scheme] = $img.src
+    return map
+  }, {})
+
+
+  function checkScheme(scheme) {
+    if (THEME_LIGHT === false) return "dark"
+    if (THEME_DARK === false) return "light"
+    return scheme
+  }
+
+  function loadScheme() {
+    return localStorage.getItem(PERSISTENCE_KEY) || loadDefaultScheme()
+  }
+
+  function loadDefaultScheme() {
+    return THEME_DEFAULT || "system"
+  }
+
+  function saveScheme(scheme) {
+    localStorage.setItem(PERSISTENCE_KEY, scheme)
+  }
+
+  function getPreferredColorScheme() {
+    const isDarkMode = window.matchMedia("(prefers-color-scheme: dark)").matches;
+    return isDarkMode ? "dark" : "light";
+  }
+
+  function setScheme(newScheme) {
+    let theme = newScheme
+    if (newScheme === 'system') {
+      theme = getPreferredColorScheme()
+    }
+    // set data-theme attribute on html tag
+    document.querySelector("html").dataset.theme = theme;
+
+    // update icon
+    $icon.src = iconMap[newScheme]
+
+    // save preference to local storage
+    saveScheme(newScheme)
+  
+    setImages(theme)
+  }
+
+  const checkedScheme = checkScheme(loadScheme())
+  setScheme(checkedScheme)
+
+  Array.from(menu.getElementsByTagName('a')).forEach((btn) => {
+    btn.addEventListener('click', () => {
+      const { scheme } = btn.dataset
+      setScheme(scheme)
+    })
+  })
+})
+
+function setImages(newScheme) {
+  const els = Array.from(document.getElementsByClassName('logo-holder'));
+  for (const el of els) {
+    const light = el.querySelector('.light-logo');
+    const dark = el.querySelector('.dark-logo');
+
+    if (newScheme === "dark" && dark !== null) {
+      if (light !== null) light.style.display = 'none'
+      dark.style.display = 'inline'
+    }
+    else {
+      if (light !== null) light.style.display = 'inline'
+      if (dark !== null) dark.style.display = 'none'
+    }
+  }
+}

+ 12 - 2
exampleSite/hugo.yaml

@@ -91,9 +91,19 @@ params:
   # Configure various features of this theme
   features:
 
-    # Enable dark theme
-    darkMode:
+    # [Deprecated] Enable dark theme
+    # This is a deprecated setting, but has not been removed to maintain backward compatibility
+    # If `theme` is set, the `darkMode` setting will be discarded.
+    # darkMode:
+    #   enable: true
+
+    # Configure theme color settings
+    theme:
       enable: true
+      services:
+        light: true # enable light theme. default "true"
+        dark: true # enable dark theme. default "true"
+        default: system # can be either light, dark or system. default "system"
 
     # Enable and configure portfolio
     portfolio:

+ 1 - 1
layouts/_default/baseof.html

@@ -12,7 +12,7 @@
     <!--================= add analytics if enabled =========================-->
     {{- partial "analytics.html" . -}}
     <script>
-      theme = localStorage.getItem('darkmode:color-scheme') || 'system';
+      theme = localStorage.getItem('theme-scheme') || localStorage.getItem('darkmode:color-scheme') || 'light';
       if (theme == 'system') {
         if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
           theme = 'dark';

+ 1 - 1
layouts/index.html

@@ -18,7 +18,7 @@
     <!--================= add analytics if enabled =========================-->
     {{- partial "analytics.html" . -}}
     <script>
-      theme = localStorage.getItem('darkmode:color-scheme') || 'system';
+      theme = localStorage.getItem('theme-scheme') || localStorage.getItem('darkmode:color-scheme') || 'light';
       if (theme == 'system') {
         if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
           theme = 'dark';

+ 13 - 2
layouts/partials/helpers/get-esbuild-options.html

@@ -69,15 +69,26 @@ params:
         #  id: foo
         #  name: bar
     
-    # The `darkMode` feature
-    darkmode:
+    # [Deprecated] The `darkMode` feature
+    # This is a deprecated setting, but has not been removed to maintain backward compatibility
+    # If `theme` is set, the `darkMode` setting will be discarded.
+    darkMode:
       enable: true
+  
+    # The `theme` feature
+    theme:
+      enable: true
+      services:
+        light: true # enable light theme. default "true"
+        dark: true # enable dark theme. default "true"
+        default: system # can be either light, dark or system. default "system"
 
 This helper will convert the above config into the following env vars:
 
   * `FEATURE_ANALYTICS=1`
   * `FEATURE_ANALYTICS_GOOGLE=1`
   * `FEATURE_DARKMODE=1`
+  * `FEATURE_THEME=1`
 
 In JS, you can use it like this:
 

+ 1 - 1
layouts/partials/navigators/navbar.html

@@ -141,7 +141,7 @@
         {{ if .IsTranslated }}
           {{ partial "navigators/lang-selector.html" . }}
         {{ end }}
-        {{ if site.Params.features.darkMode.enable }}
+        {{ if or site.Params.features.darkMode.enable site.Params.features.theme.enable }}
           {{ partial "navigators/theme-selector.html" . }}
         {{ end }}
       </ul>

+ 14 - 0
layouts/partials/navigators/theme-selector.html

@@ -1,17 +1,31 @@
+{{/*  variables for enabling/disabling various features  */}}
+{{ $darkEnabled  := true }}
+{{ $lightEnabled := true }}
+{{ if site.Params.features.theme.enable }}
+  {{ $darkEnabled   = site.Params.features.theme.services.dark   | default true }}
+  {{ $lightEnabled  = site.Params.features.theme.services.light  | default true }}
+{{ end }}
+
 <li class="nav-item dropdown">
 <a class="nav-link dropdown-toggle"  href="#" id="themeSelector" role="button"
   data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
   <img id="navbar-theme-icon-svg" class="theme-icon" src="{{ "icons/moon-svgrepo-com.svg" | relURL }}" width=20 alt="Dark Theme">
 </a>
 <div id="themeMenu" class="dropdown-menu dropdown-menu-icons-only" aria-labelledby="themeSelector">
+  {{ if $lightEnabled }}
   <a class="dropdown-item nav-link" href="#" data-scheme="light">
     <img class="theme-icon" src="{{ "icons/sun-svgrepo-com.svg" | relURL }}" width=20 alt="Light Theme">
   </a>
+  {{ end }}
+  {{ if $darkEnabled }}
   <a class="dropdown-item nav-link" href="#" data-scheme="dark">
     <img class="theme-icon" src="{{ "icons/moon-svgrepo-com.svg" | relURL }}" width=20 alt="Dark Theme">
   </a>
+  {{ end }}
+  {{ if and $lightEnabled $darkEnabled }}
   <a class="dropdown-item nav-link" href="#" data-scheme="system">
     <img class="theme-icon" src="{{ "icons/computer-svgrepo-com.svg" | relURL }}" width=20 alt="System Theme">
   </a>
+  {{ end }}
 </div>
 </li>