fix(ui): move theme checkmark when theme changes in Appearance menu

The checkmark in the Appearance theme menu was rendered server-side
(if user.Theme == opt.Name), so it never moved after switching themes
in the browser.

- Always render the check for every theme option, hidden by default,
  using a new themeCheckClass(name, current) helper that returns the
  hidden class unless the option is the active theme.
- Give each theme button a data-theme attribute and add
  updateThemeIndicators() to web/src/theme.ts, which reads the applied
  theme from the body class (theme-<name>) and toggles the hidden class
  on each check accordingly.
- Call updateThemeIndicators() from changeTheme (before the async save
  and on failure), initializeTheme, and loadUserTheme so the menu stays
  in sync with the applied theme.
- Add unit test for themeCheckClass (templates/utils_test.go) and
  regenerate templ output.
This commit is contained in:
2026-08-10 13:43:32 -04:00
parent ab465d8e0e
commit 8d65e03555
5 changed files with 203 additions and 129 deletions
+5 -4
View File
@@ -98,14 +98,15 @@ templ Header(user User, currentPath string) {
<button
type="button"
@click={ "changeTheme('" + opt.Name + "'); themeOpen = false" }
class="w-full flex items-center gap-2.5 px-3 py-1.5 rounded-lg text-sm transition-colors hover:bg-surface-hover"
class="theme-btn w-full flex items-center gap-2.5 px-3 py-1.5 rounded-lg text-sm transition-colors hover:bg-surface-hover"
data-theme={ opt.Name }
style="color: var(--text-secondary);"
>
<span class="inline-block w-3.5 h-3.5 rounded-full shrink-0 ring-1 ring-black/10" style={ "background-color: " + opt.Color }></span>
<span class="flex-1 text-left">{ opt.Label }</span>
if user.Theme == opt.Name {
@Icon("check", "h-4 w-4 shrink-0")
}
<span class={ "theme-check shrink-0" + themeCheckClass(opt.Name, user.Theme) }>
@Icon("check", "h-4 w-4")
</span>
</button>
}
<div class="my-1.5 mx-3 border-t" style="border-color: color-mix(in srgb, var(--text-primary) 7%, transparent);"></div>