Created
December 29, 2019 03:41
-
-
Save jonstuebe/7a38638dbfc3e6c92139af9ba04ddfee to your computer and use it in GitHub Desktop.
React Native styling support for StyleSheet.create
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { StyleSheet } from "react-native"; | |
/* | |
Example: Normal Theme | |
----------- | |
const themes = { | |
default: { | |
colors: { | |
error: "red" | |
} | |
}, | |
alt: { | |
colors: { | |
error: "purple" | |
} | |
} | |
}; | |
... | |
const activeTheme = useTheme(); // or some other way of getting the active theme | |
return ( | |
<ExampleComponent style={themeStyle({ activeTheme }, styles, "text")} /> | |
); | |
... | |
const styles = createThemedStyle(themes, ({ colors }) => ({ | |
text: { | |
color: colors.error | |
}, | |
root: { | |
flex: 1 | |
} | |
})); | |
----------- | |
Example: Normal Theme w/ Dark Mode Support | |
----------- | |
const themes = { | |
default: { | |
light: { | |
colors: { | |
error: "red" | |
} | |
}, | |
dark: { | |
colors: { | |
error: "green" | |
} | |
} | |
}, | |
alt: { | |
light: { | |
colors: { | |
error: "purple" | |
} | |
}, | |
dark: { | |
colors: { | |
error: "yellow" | |
} | |
} | |
} | |
}; | |
... | |
const activeTheme = useTheme(); // or some other way of getting the active theme | |
const isDarkMode = useDarkMode(); | |
return ( | |
<ExampleComponent style={themeStyle({ activeTheme, activeSubTheme: isDarkMode ? "dark" : "light" }, styles, "text")} /> | |
); | |
... | |
const styles = createThemedStyle( | |
themes, | |
({ colors }) => ({ | |
text: { | |
color: colors.error | |
}, | |
root: { | |
flex: 1 | |
} | |
}), | |
true // this enables the subTheme lookup (a.k.a. light/dark) | |
); | |
----------- | |
*/ | |
export interface StyleObject { | |
[key: string]: any; | |
} | |
export interface SubTheme { | |
[key: string]: StyleObject; | |
} | |
export type Theme = | |
| { | |
[key: string]: SubTheme | |
} | |
| SubTheme; | |
export interface Themes { | |
[key: string]: Theme; | |
} | |
export function createThemedStyle( | |
themes: Themes, | |
styleFn: (theme: Theme) => any, | |
subThemeEnabled = false | |
): { | |
[key: string]: StyleObject | |
} { | |
return Object.keys(themes).reduce((acc, name) => { | |
if (subThemeEnabled) { | |
return { | |
...acc, | |
...Object.keys(themes[name]).reduce((acc, subTheme) => { | |
return { | |
...acc, | |
[`${name}_${subTheme}`]: StyleSheet.create( | |
styleFn(themes[name][subTheme]) | |
) | |
}; | |
}, {}) | |
}; | |
} | |
return { | |
...acc, | |
[name]: StyleSheet.create(styleFn(themes[name])) | |
}; | |
}, {}); | |
} | |
export function themedStyle( | |
{ | |
activeTheme, | |
activeSubTheme | |
}: { | |
activeTheme: string, | |
activeSubTheme?: string | |
}, | |
styles: { | |
[key: string]: StyleObject | |
}, | |
key: string | |
) { | |
if (activeSubTheme) { | |
return styles[`${activeTheme}_${activeSubTheme}`][key]; | |
} | |
return styles[activeTheme][key]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment