Added default theme (#960)
* feat: Added default theme
* Revert "feat: Added default theme"
This reverts commit a11a99f92a
.
* 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>
This commit is contained in:
parent
3ce670e2a5
commit
7bc37c74c7
8 changed files with 134 additions and 7 deletions
|
@ -10,6 +10,10 @@ if (process.env.FEATURE_DARKMODE === '1') {
|
||||||
import('./darkmode')
|
import('./darkmode')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (process.env.FEATURE_THEME === '1') {
|
||||||
|
import('./theme')
|
||||||
|
}
|
||||||
|
|
||||||
if (process.env.FEATURE_FLOWCHART === '1') {
|
if (process.env.FEATURE_FLOWCHART === '1') {
|
||||||
import('./flowchart')
|
import('./flowchart')
|
||||||
}
|
}
|
||||||
|
|
88
assets/scripts/features/theme/index.js
Normal file
88
assets/scripts/features/theme/index.js
Normal file
|
@ -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'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -91,9 +91,19 @@ params:
|
||||||
# Configure various features of this theme
|
# Configure various features of this theme
|
||||||
features:
|
features:
|
||||||
|
|
||||||
# Enable dark theme
|
# [Deprecated] Enable dark theme
|
||||||
darkMode:
|
# 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
|
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
|
# Enable and configure portfolio
|
||||||
portfolio:
|
portfolio:
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<!--================= add analytics if enabled =========================-->
|
<!--================= add analytics if enabled =========================-->
|
||||||
{{- partial "analytics.html" . -}}
|
{{- partial "analytics.html" . -}}
|
||||||
<script>
|
<script>
|
||||||
theme = localStorage.getItem('darkmode:color-scheme') || 'system';
|
theme = localStorage.getItem('theme-scheme') || localStorage.getItem('darkmode:color-scheme') || 'light';
|
||||||
if (theme == 'system') {
|
if (theme == 'system') {
|
||||||
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||||
theme = 'dark';
|
theme = 'dark';
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
<!--================= add analytics if enabled =========================-->
|
<!--================= add analytics if enabled =========================-->
|
||||||
{{- partial "analytics.html" . -}}
|
{{- partial "analytics.html" . -}}
|
||||||
<script>
|
<script>
|
||||||
theme = localStorage.getItem('darkmode:color-scheme') || 'system';
|
theme = localStorage.getItem('theme-scheme') || localStorage.getItem('darkmode:color-scheme') || 'light';
|
||||||
if (theme == 'system') {
|
if (theme == 'system') {
|
||||||
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||||
theme = 'dark';
|
theme = 'dark';
|
||||||
|
|
|
@ -69,15 +69,26 @@ params:
|
||||||
# id: foo
|
# id: foo
|
||||||
# name: bar
|
# name: bar
|
||||||
|
|
||||||
# The `darkMode` feature
|
# [Deprecated] The `darkMode` feature
|
||||||
darkmode:
|
# 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
|
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:
|
This helper will convert the above config into the following env vars:
|
||||||
|
|
||||||
* `FEATURE_ANALYTICS=1`
|
* `FEATURE_ANALYTICS=1`
|
||||||
* `FEATURE_ANALYTICS_GOOGLE=1`
|
* `FEATURE_ANALYTICS_GOOGLE=1`
|
||||||
* `FEATURE_DARKMODE=1`
|
* `FEATURE_DARKMODE=1`
|
||||||
|
* `FEATURE_THEME=1`
|
||||||
|
|
||||||
In JS, you can use it like this:
|
In JS, you can use it like this:
|
||||||
|
|
||||||
|
|
|
@ -141,7 +141,7 @@
|
||||||
{{ if .IsTranslated }}
|
{{ if .IsTranslated }}
|
||||||
{{ partial "navigators/lang-selector.html" . }}
|
{{ partial "navigators/lang-selector.html" . }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ if site.Params.features.darkMode.enable }}
|
{{ if or site.Params.features.darkMode.enable site.Params.features.theme.enable }}
|
||||||
{{ partial "navigators/theme-selector.html" . }}
|
{{ partial "navigators/theme-selector.html" . }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -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">
|
<li class="nav-item dropdown">
|
||||||
<a class="nav-link dropdown-toggle" href="#" id="themeSelector" role="button"
|
<a class="nav-link dropdown-toggle" href="#" id="themeSelector" role="button"
|
||||||
data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
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">
|
<img id="navbar-theme-icon-svg" class="theme-icon" src="{{ "icons/moon-svgrepo-com.svg" | relURL }}" width=20 alt="Dark Theme">
|
||||||
</a>
|
</a>
|
||||||
<div id="themeMenu" class="dropdown-menu dropdown-menu-icons-only" aria-labelledby="themeSelector">
|
<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">
|
<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">
|
<img class="theme-icon" src="{{ "icons/sun-svgrepo-com.svg" | relURL }}" width=20 alt="Light Theme">
|
||||||
</a>
|
</a>
|
||||||
|
{{ end }}
|
||||||
|
{{ if $darkEnabled }}
|
||||||
<a class="dropdown-item nav-link" href="#" data-scheme="dark">
|
<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">
|
<img class="theme-icon" src="{{ "icons/moon-svgrepo-com.svg" | relURL }}" width=20 alt="Dark Theme">
|
||||||
</a>
|
</a>
|
||||||
|
{{ end }}
|
||||||
|
{{ if and $lightEnabled $darkEnabled }}
|
||||||
<a class="dropdown-item nav-link" href="#" data-scheme="system">
|
<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">
|
<img class="theme-icon" src="{{ "icons/computer-svgrepo-com.svg" | relURL }}" width=20 alt="System Theme">
|
||||||
</a>
|
</a>
|
||||||
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue