Skip to content

feat: wire theme toggle to zustand store with persisted preference (Closes #476) - #579

Open
waterWang wants to merge 1 commit into
Protocol-Guild:mainfrom
waterWang:feat/476-dark-light-theme-toggle
Open

feat: wire theme toggle to zustand store with persisted preference (Closes #476)#579
waterWang wants to merge 1 commit into
Protocol-Guild:mainfrom
waterWang:feat/476-dark-light-theme-toggle

Conversation

@waterWang

Copy link
Copy Markdown

Summary

Fixes #476 — the ThemeToggle.tsx component existed but its state wasn't wired through a persistent store, and CSS variable sets were incomplete, so dark/light mode switching didn't fully work.

Changes

1. Zustand store wiring

  • New frontend/src/stores/themeStore.ts — zustand store with persist middleware persisting preference to localStorage (reuses existing payd-theme key), exposing theme, setTheme, toggleTheme
  • providers/ThemeProvider.tsx — subscribes to the store and applies data-theme attribute on the document root
  • hooks/useTheme.ts — now reads directly from the zustand store (same API: theme, toggleTheme, plus setTheme)

2. Completed CSS variable sets (both themes)

Added missing tokens to index.css for dark and light:

  • --warning + warning alpha variants
  • --accent-*, --accent2-*, --danger-*, --success-* alpha variants
  • --accent2-hover, --danger-hover
  • --accent-glow, --glass-bg, --input-bg, --input-bg-hover, --row-hover, --scrim
  • --shadow-sm, --shadow-md

3. Replaced hardcoded colors with theme-aware variables

Pages that still used raw #0a0a0c / #16161a / rgba(...) colors (which rendered identically in light mode):

  • CrossAssetPayment.tsx, Login.tsx, RevenueSplitDashboard.tsx, TransactionHistory.tsx, CashFlowForecast.tsx

Acceptance Criteria

  • Toggle switches between dark and light mode
  • Preference persists across page reloads (localStorage via zustand persist)
  • All components render correctly in both themes
  • No hard-coded colors that ignore theme variables (in touched files)

Verification

  • tsc --noEmit — 0 errors
  • vite build — 3456 modules, built successfully

…loses Protocol-Guild#476)

- Add themeStore.ts using zustand create + persist middleware for localStorage
  persistence of theme preference (pre-existing key 'payd-theme')
- Rewrite ThemeProvider to apply data-theme attribute from store state
- Rewrite useTheme hook to read theme/toggleTheme/setTheme from zustand store
- Complete CSS variable sets for both dark and light themes:
  warning, accent/danger/success/warning alpha variants, hover colors,
  input-bg, row-hover, scrim, glass-bg, shadows, accent-glow
- Replace hardcoded rgb/hex colors with theme-aware CSS variables in
  CrossAssetPayment, Login, RevenueSplitDashboard, TransactionHistory,
  CashFlowForecast pages (match semantic tokens)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add dark/light mode theme toggle that actually works

1 participant