forked from hackorum-dev/hackorum
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy paththeme_controller.js
More file actions
69 lines (54 loc) · 1.91 KB
/
theme_controller.js
File metadata and controls
69 lines (54 loc) · 1.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import { Controller } from "@hotwired/stimulus"
const STORAGE_KEY = "hackorum-theme"
const DEFAULT_THEME = "light"
export default class extends Controller {
static targets = ["icon", "label", "button"]
connect() {
this.applyInitialTheme()
}
toggle(event) {
if (event && event.type !== "change") {
event.preventDefault()
}
const nextTheme = this.currentTheme === "dark" ? "light" : "dark"
this.setTheme(nextTheme)
}
select(event) {
event.preventDefault()
const { themeValue } = event.currentTarget.dataset
this.setTheme(themeValue)
}
applyInitialTheme() {
const storedTheme = window.localStorage.getItem(STORAGE_KEY)
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches
const initialTheme = storedTheme || (prefersDark ? "dark" : DEFAULT_THEME)
this.setTheme(initialTheme, { persist: false })
}
setTheme(theme, { persist = true } = {}) {
const normalizedTheme = theme === "dark" ? "dark" : "light"
document.documentElement.dataset.theme = normalizedTheme
if (persist) {
window.localStorage.setItem(STORAGE_KEY, normalizedTheme)
}
this.updateToggle(normalizedTheme)
}
updateToggle(theme) {
if (this.hasLabelTarget) {
this.labelTarget.textContent = theme === "dark" ? "Dark" : "Light"
}
if (this.hasIconTarget) {
this.iconTarget.classList.remove("fa-moon", "fa-sun")
this.iconTarget.classList.add(theme === "dark" ? "fa-sun" : "fa-moon")
}
this.element.setAttribute("aria-pressed", theme === "dark")
this.element.setAttribute("title", `Switch to ${theme === "dark" ? "light" : "dark"} mode`)
if (this.hasButtonTarget) {
this.buttonTargets.forEach((button) => {
button.classList.toggle("is-active", button.dataset.themeValue === theme)
})
}
}
get currentTheme() {
return document.documentElement.dataset.theme || DEFAULT_THEME
}
}