Coloriginz Design Systemshadcn custom registry

@col/theme-switcher

Versie: 1.0.0 Toegevoegd: 2026-08-04

Herkomst

Geëxtraheerd uit growerportal2/src/components/theme-switcher.tsx: een ghost icon-knop die het thema laat cyclen tussen licht, donker en systeem.

Waarvoor

Eén knop om het thema te wisselen, met een icoon dat het huidige thema toont. Klikken cyclet light → dark → system → light. Past zowel in een bovenbalk als naast @col/user-panel in een zijbalk — het is bewust een losstaand component zonder mening over waar het staat.

Gebruik het niet als je meer dan drie themamodi nodig hebt, of een aparte knop per modus wilt — dit is bewust één knop die cyclet, geen keuzemenu.

Wat je app moet leveren

Prop Type Betekenis
theme 'light' | 'dark' | 'system' Het huidige thema. Verplicht.
onChange (theme: Theme) => void Aangeroepen met het volgende thema in de cyclus wanneer er geklikt wordt. Verplicht.
labels { light?, dark?, system? } Labels voor de title-tooltip. Zonder een label voor het volgende thema valt de tooltip terug op de themanaam zelf ("light", "dark", "system").

Dit component is controlled en volledig ontkoppeld van next-themes. De bron gebruikt useTheme() uit next-themes en houdt een mounted-guard aan om een hydration mismatch te voorkomen — de server weet het thema nog niet (het zit in localStorage), de client na de eerste render wel. Zonder die guard render je server en client verschillend en klaagt React erover. Die guard hoort in de app die dit item installeert:

'use client'

import { useTheme } from 'next-themes'
import { useEffect, useState } from 'react'
import { ThemeSwitcher } from '@/components/nav/theme-switcher'

export function ThemeSwitcherStarter() {
  const { theme, setTheme } = useTheme()
  const [mounted, setMounted] = useState(false)
  useEffect(() => setMounted(true), [])

  if (!mounted) return null

  return <ThemeSwitcher theme={(theme as 'light' | 'dark' | 'system') ?? 'system'} onChange={setTheme} />
}

Bestanden

Bestand Landt in Soort
theme-switcher.tsx components/nav/ beheerd

Upstream shadcn-afhankelijkheden: button. Geen cssVars.

Gebruikt door

App Sinds versie Opmerkingen
— — Nog geen consumers. growerportal2 is de bron van dit patroon en draait nog op zijn eigen kopie in src/components/theme-switcher.tsx, inclusief de next-themes-koppeling en mounted-guard die hier bewust niet in zitten.

Bewuste keuzes

Bekende beperkingen