Skip to content

ThemeProvider + useTheme hook #4

@mathieusouflis

Description

@mathieusouflis

What to build

A React context component and hook that manage dark/light mode — reading system preference, persisting manual choices, and applying the .dark class to <html> so PandaCSS token conditions activate.

Set up:

  • ThemeProvider component: on mount reads localStorage for stored preference → falls back to window.matchMedia('prefers-color-scheme: dark') → defaults to light. Applies/removes .dark on <html>.
  • Listens to system preference changes via matchMedia event listener — applies in real time when no manual preference is stored.
  • useTheme() hook returning { theme, setTheme, toggleTheme }. setTheme writes to localStorage.
  • Works in Next.js App Router, Next.js Pages, Vite, and TanStack Start (no server-only APIs called at import time).
  • Dark mode toggle wired into Storybook toolbar using ThemeProvider so Storybook previews match real app behavior.

Tests (Vitest + Testing Library):

  • Correct class applied to <html> on mount given: localStorage has stored preference, localStorage is empty + system prefers dark, localStorage is empty + system prefers light.
  • setTheme updates localStorage.
  • System preference listener updates theme when no manual preference is stored.

Acceptance criteria

  • Wrapping an app with <ThemeProvider> applies .dark to <html> when system prefers dark and no localStorage preference exists
  • useTheme().toggleTheme() switches the class and persists the new preference to localStorage
  • Refreshing the page respects the stored localStorage preference over system preference
  • Storybook has a working dark/light toggle in its toolbar
  • All three test scenarios pass

Blocked by

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions