Skip to content

Instantly share code, notes, and snippets.

@jonstuebe
Created December 29, 2019 03:41
Show Gist options
  • Save jonstuebe/7a38638dbfc3e6c92139af9ba04ddfee to your computer and use it in GitHub Desktop.
Save jonstuebe/7a38638dbfc3e6c92139af9ba04ddfee to your computer and use it in GitHub Desktop.
React Native styling support for StyleSheet.create
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