Theme Provider
Theme context provider with light, dark, and system mode support.
Installation#
npx @aniui/cli add theme-providerLightDark
Light mode enabled
Web preview — components render natively on iOS & Android
import { ThemeProvider } from "@/components/ui/theme-provider";
export default function App() {
return (
<ThemeProvider defaultTheme="system">
{/* Your app content */}
</ThemeProvider>
);
}Usage#
app/_layout.tsx
import { ThemeProvider } from "@/components/ui/theme-provider";
export default function App() {
return (
<ThemeProvider defaultTheme="system">
{/* Your app content */}
</ThemeProvider>
);
}useTheme Hook#
Access the current theme, resolved theme, and theme controls from any child component.
Using useTheme
import { useTheme } from "@/components/ui/theme-provider";
export function ThemeToggle() {
const { theme, resolvedTheme, setTheme, toggleTheme } = useTheme();
return (
<Button onPress={toggleTheme}>
{resolvedTheme === "dark" ? "Switch to Light" : "Switch to Dark"}
</Button>
);
}PropTypeDefault
theme"light" | "dark" | "system"-resolvedTheme"light" | "dark"-setTheme(theme: Theme) => void-toggleTheme() => void-Props#
PropTypeDefault
childrenReact.ReactNode-defaultTheme"light" | "dark" | "system""system"classNamestring-Accessibility#
ThemeProvidercontext for light/dark/system mode.- Respects the user's system-level accessibility preferences for color scheme.
Source#
components/ui/theme-provider.tsx
import React, { createContext, useCallback, useContext, useEffect, useState } from "react";
import { useColorScheme as useNativeColorScheme } from "react-native";
import { cn } from "@/lib/utils";
import { View } from "react-native";
type Theme = "light" | "dark" | "system";
const ThemeContext = createContext<{
theme: Theme;
resolvedTheme: "light" | "dark";
setTheme: (theme: Theme) => void;
toggleTheme: () => void;
}>({
theme: "system",
resolvedTheme: "light",
setTheme: () => {},
toggleTheme: () => {},
});
export function useTheme() {
return useContext(ThemeContext);
}
export interface ThemeProviderProps {
children: React.ReactNode;
defaultTheme?: Theme;
storageKey?: string;
className?: string;
}
export function ThemeProvider({
children,
defaultTheme = "system",
className,
}: ThemeProviderProps) {
const systemScheme = useNativeColorScheme();
const [theme, setThemeState] = useState<Theme>(defaultTheme);
const resolvedTheme: "light" | "dark" =
theme === "system" ? (systemScheme ?? "light") : theme;
const setTheme = useCallback((newTheme: Theme) => {
setThemeState(newTheme);
}, []);
const toggleTheme = useCallback(() => {
setThemeState((prev) => {
if (prev === "system") return systemScheme === "dark" ? "light" : "dark";
return prev === "dark" ? "light" : "dark";
});
}, [systemScheme]);
return (
<ThemeContext.Provider value={{ theme, resolvedTheme, setTheme, toggleTheme }}>
<View className={cn(resolvedTheme === "dark" ? "dark" : "", "flex-1 bg-background", className)}>
{children}
</View>
</ThemeContext.Provider>
);
}