-
Hi, I have a project that need to use dynamic theme. I had no issue using v1 but couldn't find a way to make it work with v2. const ThemeProvider = ({
children,
appTheme = theme,
}: PropsWithChildren<{ appTheme?: Theme }>): JSX.Element => {
const [newTheme, setNewTheme] = useState(appTheme);
const deviceSize = useDeviceSize();
const colorTheme = 'light';
useEffect(() => {
setNewTheme({
...appTheme,
colors: getThemeColor(colorTheme),
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [colorTheme]);
useEffect(() => {
const { isMobileWidth, isTabletWidth, isDesktopWidth } = getDeviceWidth(deviceSize);
const nTheme = {
...theme,
typography: getTypography(deviceSize),
devices: {
...theme.devices,
isMobileWidth,
isTabletWidth,
isDesktopWidth,
},
};
setNewTheme(nTheme);
}, [deviceSize]);
return <UnistylesTheme theme={newTheme}>{children}</UnistylesTheme>;
}; Above is the code how I use the style with v1. useDeviceSize() will dynamically get screen size as you dragging the browser and change the size. newTheme will be set to new if deviceSize or colorTheme are changed. And I can pass the newTheme down using UnistylesTheme. So I can get something like isDesktopWidth from theme and render different layout based on it. But I could not find a way to do it if UnistylesTheme is removed from v2. Is there a way to achieve the same purpose? Thanks a lot in advance. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 8 replies
-
No worries, that's super easy!
More info: https://reactnativeunistyles.vercel.app/reference/theming/#create-a-theme Keep in mind that with v2 you can define multiple themes (like light and dark)! So you can share your colors on the theme level colors: getThemeColor(colorTheme), <- define it in theme
More info: https://reactnativeunistyles.vercel.app/reference/breakpoints/ You can remove them from theme and access it with
const ThemeProvider = ({
children,
appTheme = theme,
}: PropsWithChildren<{ appTheme?: Theme }>): JSX.Element => {
-const [newTheme, setNewTheme] = useState(appTheme);
const deviceSize = useDeviceSize();
const colorTheme = 'light';
useEffect(() => {
- setNewTheme({
- ...appTheme,
- colors: getThemeColor(colorTheme),
- });
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [colorTheme]);
-useEffect(() => {
- const { isMobileWidth, isTabletWidth, isDesktopWidth } = getDeviceWidth(deviceSize);
// define it in theme
- const nTheme = {
- ...theme,
- typography: getTypography(deviceSize),
- devices: {
- ...theme.devices,
- isMobileWidth,
- isTabletWidth,
- isDesktopWidth,
- },
- };
- setNewTheme(nTheme);
- }, [deviceSize]);
- return <UnistylesTheme theme={newTheme}>{children}</UnistylesTheme>;
};
4.1 Define breakpoints to replace
const ThemeProvider = ({
children,
currentThemeName,
}: PropsWithChildren<{ appTheme?: Theme }>): JSX.Element => {
useEffect(() => {
if (UnistylesRuntime.themeName !== currentThemeName) {
// it will auto switch the theme
UnistylesRuntime.setTheme(currentThemeName)
}
}, [currentThemeName])
return children
}
typography: getTypography(deviceSize), Depending on what it does you can move it to static theme or create a dynamic plugin: https://reactnativeunistyles.vercel.app/reference/plugins/
https://reactnativeunistyles.vercel.app/reference/breakpoints/#how-to-use-breakpoints I hope it will help you to convert your app to v2. Fell free to ask any additional questions! |
Beta Was this translation helpful? Give feedback.
I believe there is a more efficient way to approach this, @ryan-brs. You can actually name your breakpoints whatever you prefer. For instance, you could define them as follows:
After registering them, you can easily access the breakpoint flag in your component like this:
Reference: Use Styles - Basic Usage Breakpoint
I guess you can also replace other dynamic parts and finalize your themes to be static.