reactnative 프로젝트에서 여러개의 테마를 적용시켜야했다.
프로젝트에서 tailwind(nativewind) 설정(v4.x.x)이 되어있는 상태에서의 설명을 작성한다.
변수를 사용하고 싶은 부분에 아래와 같이 var로 변수 설정을 한다.
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./App.{js,jsx,ts,tsx}",
"./src/**/*.{js,jsx,ts,tsx}"
],
presets: [require("nativewind/preset")],
theme: {
extend: {
colors: {
'primary': 'var(--color-primary)',
},
},
},
plugins: [],
};
tailwind.config.js에서 설정한 변수이름과 같은 이름으로 테마를 설정한다.
나는 테마 이름을 숫자 인덱스로 관리할 예정이어서 theme-<number>로 테마이름을 만들고 그 안에 변수 설정을 하였다.
예를 들어서 theme-0의 primary색은 #60a5fa가 된다.
@tailwind base;
@tailwind components;
@tailwind utilities;
.theme-0 {
--color-primary: #60a5fa;
--color-background: #1f2937;
}
.theme-1 {
--color-primary: #ef4444;
--color-background: #d1fae5;
}
사용하려는 컴포넌트의 루트에
<View className={`theme-${theme} flex-1`}></View>
로 감싼다.
나는 전역 변수로 테마를 관리하고 싶어서 아래처럼 했다.
export default function App() {
const selectedTheme = useThemeStore((state) => state.selectedTheme);
return (
<GestureHandlerRootView style={{flex:1}}>
<SafeAreaProvider>
<NavigationContainer>
<StatusBar barStyle="light-content" translucent={true}/>
<View className={`theme-${selectedTheme?.themeIndex} flex-1`}>
<Stack/>
</View>
</NavigationContainer>
</SafeAreaProvider>
</GestureHandlerRootView>
);
}
className에 들어가는 theme변수가 global.css에서 본인이 설정한 테마 이름과 같으면, 그 테마에 설정된 변수들이 모두 사용된다. 따라서 아래처럼 useState로 간단하게 관리해도 된다.
const [theme,setTheme] = useState('theme-0')
...
<View className={`${theme}`}>
<Button onPress={()=>{setTheme('theme-1')}}/>
</View>
사용하고자 하는 컴포넌트에서 기존과 같은 방법으로 사용하면 된다. 아주 편하다.
<View className="bg-primary"/>