Skip to content
Cojeev UI

Theme toggle

Actions

A controlled light/dark switch with a morphing sun and moon and a smooth organic page reveal.

React · copy into your project · light and dark themes

Try it

Loading preview…

Take it with you

Copy the example, API and usage notes for your editor or AI assistant.

Add to your project

Terminal
npx shadcn@latest add https://luv-jeri.github.io/cojeev-ui/r/theme-toggle.json

The command includes the component’s shared dependencies. Your project keeps editable source files.

Include the complete example

This example also composes card, typography. Install its parts together:

Terminal
npx shadcn@latest add https://luv-jeri.github.io/cojeev-ui/r/theme-toggle.json https://luv-jeri.github.io/cojeev-ui/r/card.json https://luv-jeri.github.io/cojeev-ui/r/typography.json

Using theme toggle

  • The destination theme opens through a slower organic reveal with a varied viewport origin. Explicit origin options remain available; reduced motion and Motion Off settle immediately.

  • Pass mode and onModeChange. Keep persistence in the application.

  • Call applyTheme(nextMode, quiet) to animate the document theme, or update your own theme scope.

  • Use the shared motion preference so reduced motion and Motion Off switch immediately.

API

Compose the exported parts below. The prop types are read from the React source during the registry build.

Native element or underlying primitive props are inherited where declared, including accessible labels, event handlers and refs.

ThemeToggleProps

PropTypeRequired
modeThemeModeYes
onModeChange(mode: ThemeMode, details?:ThemeChangeDetails) => voidYes
showLabelbooleanNo
labelReact.ReactNodeNo
responsive

Keep a label on desktop and the same 44px icon target on small screens.

booleanNo

Accessibility

  • The button exposes a named switch and aria-checked.

  • Both keyboard Space and Enter change the controlled mode.

States and appearance

lightdarkfocuseddisabledreduced-motion

For conditional content, keep a MotionPresence boundary around keyed MotionSurface children. The shared entrance and exit states work with native primitives and respect your motion preference.

Try pointer and keyboard interaction, and switch the appearance control in the navigation to compare light and dark mode. Motion respects reduced motion preferences.