// tailwind.config.js
module.exports = {
theme: {
extend: {
colors: {
primary: 'rgb(var(--color-primary)/<alpha-value>)',
},
},
},
};
// config.ts
export const config = {
light: vars({
'--color-primary': '51 51 51',
}),
dark: vars({
'--color-primary': '240 240 240',
}),
};
// App.tsx
import { GluestackUIProvider } from '@/components/ui/gluestack-ui-provider';
import { Box } from '@/components/ui/box';
import { Button, ButtonText } from '@/components/ui/Button';
import { useState } from 'react';
export default function App() {
const [colorMode, setColorMode] = (useState < 'light') | ('dark' > 'light');
return (
<GluestackUIProvider mode={colorMode}>
<Box className="bg-primary flex-1">
<Button
onPress={() => {
setColorMode(colorMode === 'light' ? 'dark' : 'light');
}}
>
<ButtonText>Toggle color mode</ButtonText>
</Button>
</Box>
</GluestackUIProvider>
);
}
// App.tsx
import { GluestackUIProvider } from '@/components/ui/gluestack-ui-provider';
import { Box } from '@/components/ui/box';
import { Button, ButtonText } from '@/components/ui/Button';
import { useState } from 'react';
export default function App() {
const [colorMode, setColorMode] = (useState < 'light') | ('dark' > 'light');
return (
<GluestackUIProvider mode={colorMode}>
<Box className="bg-white dark:bg-black flex-1">
<Button
onPress={() => {
setColorMode(colorMode === 'light' ? 'dark' : 'light');
}}
>
<ButtonText>Toggle color mode</ButtonText>
</Button>
</Box>
</GluestackUIProvider>
);
}
// tailwind.config.js
module.exports = {
darkMode: process.env.DARK_MODE ? process.env.DARK_MODE : 'media',
// rest of the config
};
{
"scripts": {
"android": "DARK_MODE=media expo start --android",
"ios": "DARK_MODE=media expo start --ios",
"web": "DARK_MODE=class expo start --web"
}
}
npm i @react-native-async-storage/async-storage
// components/ui/ThemeProvider/ThemeProvider.tsx
"use client";
import React, { createContext, useState, useEffect, useContext } from "react";
import AsyncStorage from "@react-native-async-storage/async-storage";
type Theme = "light" | "dark";
interface ThemeContextType {
theme: Theme;
toggleTheme: () => void;
}
export const ThemeContext = createContext<ThemeContextType | undefined>(
undefined
);
export const ThemeProvider = ({ children }: { children: React.ReactNode }) => {
const [theme, setTheme] = useState<Theme>("light");
useEffect(() => {
(async () => {
const savedTheme = (await AsyncStorage.getItem("theme")) as
| Theme
| "light";
if (savedTheme) {
setTheme(savedTheme);
AsyncStorage.setItem("theme", savedTheme);
}
})();
}, []);
const toggleTheme = () => {
const newTheme = theme === "light" ? "dark" : "light";
setTheme(newTheme);
AsyncStorage.setItem("theme", newTheme);
};
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
};
export const useTheme = () => {
const context = useContext(ThemeContext);
if (context === undefined) {
throw new Error("useTheme must be used within a ThemeProvider");
}
return context;
};