feat: Add basic theme feature
This commit is contained in:
parent
8c6aa5ac09
commit
dd1ede93d9
3 changed files with 105 additions and 1 deletions
|
@ -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')
|
||||
}
|
||||
|
|
91
assets/scripts/features/theme/index.js
Normal file
91
assets/scripts/features/theme/index.js
Normal file
|
@ -0,0 +1,91 @@
|
|||
const PERSISTENCE_KEY = 'lightmode:color-scheme'
|
||||
|
||||
const THEME_DARK = typeof process.env.FEATURE_THEME_DARK === 'undefined' ? false : process.env.FEATURE_THEME_DARK;
|
||||
const THEME_LIGHT = typeof process.env.FEATURE_THEME_LIGHT === 'undefined' ? false : process.env.FEATURE_THEME_LIGHT;
|
||||
const THEME_DEFAULT = typeof process.env.FEATURE_THEME_DEFAULT === 'system' ? false : process.env.FEATURE_THEME_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 (scheme === "light" && THEME_LIGHT) {
|
||||
return "light"
|
||||
}
|
||||
if (scheme === "dark" && THEME_DARK) {
|
||||
return "dark"
|
||||
}
|
||||
return "system"
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
setScheme(loadScheme())
|
||||
|
||||
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'
|
||||
}
|
||||
}
|
||||
}
|
|
@ -69,15 +69,24 @@ params:
|
|||
# id: foo
|
||||
# name: bar
|
||||
|
||||
# The `darkMode` feature
|
||||
# The `darkMode` feature. It's a deprecated setting but keep backward compatibility
|
||||
darkmode:
|
||||
enable: true
|
||||
|
||||
# Configure theme settings
|
||||
theme:
|
||||
enable: true
|
||||
services:
|
||||
light: true # enable light theme. default "true"
|
||||
dark: true # enable dark theme. default "true"
|
||||
defaultTheme: light # 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:
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue