1.1.0 • Published 6 years ago
@carimus/react-native-theme-provider v1.1.0
@carimus/react-native-theme-provider
A React Native package that wraps @callstack/react-theme-provider
to add in some React Native-specific goodies.
See the react-theme-provider's docs for usage details.
Additions
withStyleSheet
When you call createTheming, the returned object will also contain a withStyleSheet property which creates a
HOC when called with styles that injects a styleSheet into the component props.
In short this allows you to declare a component's stylesheet as a function of the theme, analogous to Material UI's
withStyles.
Usage
withStyleSheet(styles, [options]) => ((YourComponent) => ThemedComponent)Calling withStyleSheet returns a higher order component which you call with your component in order to inject
a stylesheet based on the theme into your component.
Arguments
styles((function(theme: object, props?: object): object) | object): If an object,stylesis passed throughStyleSheet.create()and given straight to the wrapped component asstyleSheet. If it's a function, it will be called with thetheme(and possibly the props as the second arg ifoptions.withPropsis set totrue, not the default) and it should return an object which will be passed throughStyleSheet.create()and given to the wrapped component asstyleSheet.options(objectoptional):options.name(string; optional): Used when generating the display name of the wrapper component, otherwiseYourComponent.displayName || YourComponent.nameis used.options.propName(string; optional, defaults to'styleSheet'): The name of the prop to pass the generated and compiled stylesheet as toYourComponentoptions.forwardTheme(boolean; optional, defaults totrue): Iftrue(the default), the theme will be passed intoYourComponenton thethemeprop.options.withProps(boolean; optional, defaults tofalse): This has no effect ifstylesis an object. Iftrue, the incoming props will be passed to yourstylesfunction as the second argument. Important note: this disables caching of the compiled stylesheet. The performance hit is marginal but if performance is crucial to this component, you should instead prefer to conditionally apply styles in your styleSheet in the render function of your component based on the props of interest, and, of course, appropriately implementshouldComponentUpdateor similar.options.propagate(boolean; optional, defaults totrue): Iftrue(the default), will also wrapYourComponentin theThemeProviderso that the final theme (i.e. including any merged in styles) will propagate into the subtree. This isn't strictly necessary if the theme is never modified and you have theThemeProviderat the root of your app, but if you manually update thethemeby providing athemeprop which will be merged into the contextual theme per the behaviour ofwithTheme, then you need to leave this astruein order for themed components in the subtree to use the same modified theme. If you don't want this (i.e. if you want components in the subtree to use the original theme), set this tofalse.
Notes
- The returned function is a HOC which you use to wrap your component. All props will be forwarded to your component
with the addition of the
styleSheetandthemeprops (both are configurable viaoptions). themeis the original theme object that was passed tocreateThemingstyleSheetis the result ofStyleSheet.create()called on thestylesobject (or the result of callingstylesif it's a function given thethemeand optionally theprops).- If
stylesis a function andoptions.withPropsis false, the result of callingstyleswith a given theme is cached.styleswon't be called again to generate thestyleSheeton future renders unless thethemechanges. withStyleSheetimplieswithThemeso all behaviour thatwithThemeexhibits applies towithStyleSheetas well. For example, the component can be called with athemeprop and thatthemewill be merged into the contextual theme.
Example
theme.js
import { createTheming } from '@carimus/react-native-theme-provider';
const theme = {
palette: {
background: '#000000',
foreground: '#FFFFFF',
},
};
export const {
ThemeProvider,
withTheme,
useTheme,
withStyleSheet,
} = createTheming(theme);FooComponent.js
import { View, Text } from 'react-native';
import { withStyleSheet } from './theme';
const styles = (theme) => ({
root: {
backgroundColor: theme.palette.background,
},
text: {
color: theme.palette.foreground,
},
});
function FooComponent({ styleSheet, children }) {
return (
<View style={styleSheet.root}>
<Text style={styleSheet.text}>{children}</Text>
</View>
);
}
export default withStyleSheet(styles)(FooComponent);TODO
- [
withStyleSheet] Advanced caching in order to cache compiled styleSheets even whenwithPropsistrue. - Some generic HOC that isn't dependent on a
theme(i.e. isn't a result ofcreateTheming) that can still somehow accept a theme dynamically from context and apply/merge it in to a default theme. For generic components to except a theme somehow but have sane defaults.