Clean-up styles and JS controller, use radios

This commit is contained in:
Jason Zimdars
2025-12-10 16:15:45 -06:00
parent dc6696940c
commit 2d359fa230
3 changed files with 23 additions and 45 deletions
+6 -9
View File
@@ -11,22 +11,19 @@
--btn-background: var(--color-ink-lightest);
--btn-border-radius: 0.4em;
--btn-border-size: 0;
--btn-gap: 0.3lh;
--btn-gap: 0.1lh;
--btn-padding: 1em;
--icon-size: 2em;
column-gap: var(--inline-space);
flex: 1;
flex-direction: column;
position: relative;
white-space: nowrap;
&[aria-selected="true"] {
background-color: var(--color-selected);
@media (any-hover: hover) {
&:hover {
background-color: var(--color-selected);
}
}
&:has(input:checked) {
--btn-background: var(--color-selected);
--btn-color: var(--color-ink);
}
@media (max-width: 479px) {
+8 -30
View File
@@ -5,25 +5,18 @@ export default class extends Controller {
connect() {
this.#applyStoredTheme()
this.#updateButtons()
}
setLight() {
this.#setTheme("light")
document.documentElement.setAttribute("data-theme", "light")
this.#updateButtons()
}
setDark() {
this.#setTheme("dark")
document.documentElement.setAttribute("data-theme", "dark")
this.#updateButtons()
}
setAuto() {
this.#setTheme("auto")
document.documentElement.removeAttribute("data-theme")
this.#updateButtons()
}
get #storedTheme() {
@@ -32,36 +25,21 @@ export default class extends Controller {
#setTheme(theme) {
localStorage.setItem("theme", theme)
theme === "auto" ? document.documentElement.removeAttribute("data-theme") : document.documentElement.setAttribute("data-theme", theme)
this.#updateButtons()
}
#applyStoredTheme() {
const storedTheme = this.#storedTheme
if (storedTheme === "light") {
document.documentElement.setAttribute("data-theme", "light")
} else if (storedTheme === "dark") {
document.documentElement.setAttribute("data-theme", "dark")
} else {
// auto - don't set data-theme, let CSS media query handle it
document.documentElement.removeAttribute("data-theme")
}
this.#setTheme(this.#storedTheme)
}
#updateButtons() {
const storedTheme = this.#storedTheme
// Reset all buttons
if (this.hasLightBtnTarget) this.lightButtonTarget.removeAttribute("aria-selected")
if (this.hasDarkBtnTarget) this.darkButtonTarget.removeAttribute("aria-selected")
if (this.hasAutoBtnTarget) this.autoButtonTarget.removeAttribute("aria-selected")
// Highlight active button
if (storedTheme === "light" && this.hasLightBtnTarget) {
this.lightButtonTarget.setAttribute("aria-selected", "true")
} else if (storedTheme === "dark" && this.hasDarkBtnTarget) {
this.darkButtonTarget.setAttribute("aria-selected", "true")
} else if (this.hasAutoBtnTarget) {
this.autoButtonTarget.setAttribute("aria-selected", "true")
}
if (this.lightButtonTarget) { this.lightButtonTarget.checked = (storedTheme === "light") }
if (this.darkButtonTarget) { this.darkButtonTarget.checked = (storedTheme === "dark") }
if (this.autoButtonTarget) { this.autoButtonTarget.checked = (storedTheme !== "light" && storedTheme !== "dark") }
}
}
+9 -6
View File
@@ -2,19 +2,22 @@
<strong class="divider txt-large">Appearance</strong>
<div class="theme-switcher flex gap max-width justify-center txt-small margin-block-start-half">
<button type="button" class="btn theme-switcher__btn" data-action="click->theme#setLight" data-theme-target="lightBtn">
<label class="btn theme-switcher__btn">
<%= icon_tag "sun" %>
<span class="overflow-ellipsis">Always light</span>
</button>
<input type="radio" name="theme" data-action="click->theme#setLight" data-theme-target="lightButton">
</label>
<button type="button" class="btn theme-switcher__btn" data-action="click->theme#setDark" data-theme-target="darkBtn">
<label class="btn theme-switcher__btn" >
<%= icon_tag "moon" %>
<span class="overflow-ellipsis">Always dark</span>
</button>
<input type="radio" name="theme" data-action="click->theme#setDark" data-theme-target="darkButton">
</label>
<button type="button" class="btn theme-switcher__btn" data-action="click->theme#setAuto" data-theme-target="autoBtn">
<label class="btn theme-switcher__btn">
<%= icon_tag "monitor" %>
<span class="overflow-ellipsis">Same as OS</span>
</button>
<input type="radio" name="theme" data-action="click->theme#setAuto" data-theme-target="autoButton">
</label>
</div>
</section>