Skip to content

Commit

Permalink
feat: Added replaceTheme function (#1920)
Browse files Browse the repository at this point in the history
Added replaceTheme function to merge the theme passed in with the default theme.
  • Loading branch information
kuket15 authored and iRoachie committed Aug 1, 2019
1 parent f3c78e0 commit e2f2e6e
Show file tree
Hide file tree
Showing 22 changed files with 65 additions and 12 deletions.
10 changes: 6 additions & 4 deletions docs/customization.md
Expand Up @@ -229,23 +229,23 @@ const theme = {
### Using the theme in your own components

You may want to make use of the theming utilities in your own components. For
this you can use the `withTheme` HOC exported from this library. It adds two
props to the component it wraps - `theme` and `updateTheme`.
this you can use the `withTheme` HOC exported from this library. It adds three
props to the component it wraps - `theme`, `updateTheme` and `replaceTheme`.

```jsx
import React from 'react';
import { Text } from 'react-native';
import { withTheme } from 'react-native-elements';

function MyComponent(props) {
const { theme, updateTheme } = props;
const { theme, updateTheme, replaceTheme } = props;
return <Text style={{ color: theme.colors.primary }}>Yo!</Text>;
}

export default withTheme(MyComponent);
```

The `updateTheme` merges the theme passed in with the current theme.
The `updateTheme` function merges the theme passed in with the current theme.

```jsx
const theme = {
Expand All @@ -258,6 +258,8 @@ const theme = {
updateTheme({ colors: { primary: 'red' } });
```

The `replaceTheme` function merges the theme passed in with the default theme.

Don't want to wrap your components? You can use the `ThemeConsumer` component
which uses render props!

Expand Down
2 changes: 2 additions & 0 deletions src/avatar/__tests__/__snapshots__/Avatar.js.snap
Expand Up @@ -608,6 +608,7 @@ exports[`Avatar Component renders touchable if onPress given 1`] = `

exports[`Avatar Component should apply values from theme 1`] = `
<View
replaceTheme={[Function]}
style={
Object {
"backgroundColor": "transparent",
Expand Down Expand Up @@ -670,6 +671,7 @@ exports[`Avatar Component should apply values from theme 1`] = `
>
<Image
onLoadEnd={[Function]}
replaceTheme={[Function]}
source={
Object {
"uri": "https://i.imgur.com/0y8Ftya.jpg",
Expand Down
4 changes: 4 additions & 0 deletions src/buttons/__tests__/__snapshots__/ButtonGroup.js.snap
Expand Up @@ -498,6 +498,7 @@ exports[`ButtonGroup Component Disabled should disable only some items 1`] = `

exports[`ButtonGroup Component should apply values from theme 1`] = `
<View
replaceTheme={[Function]}
style={
Object {
"backgroundColor": "#fff",
Expand Down Expand Up @@ -554,6 +555,7 @@ exports[`ButtonGroup Component should apply values from theme 1`] = `
}
>
<Text
replaceTheme={[Function]}
style={
Object {
"color": "red",
Expand Down Expand Up @@ -649,6 +651,7 @@ exports[`ButtonGroup Component should apply values from theme 1`] = `
}
>
<Text
replaceTheme={[Function]}
style={
Object {
"color": "#5e6977",
Expand Down Expand Up @@ -742,6 +745,7 @@ exports[`ButtonGroup Component should apply values from theme 1`] = `
}
>
<Text
replaceTheme={[Function]}
style={
Object {
"color": "#5e6977",
Expand Down
3 changes: 3 additions & 0 deletions src/card/__tests__/__snapshots__/Card.js.snap
Expand Up @@ -2,6 +2,7 @@

exports[`Card Component should apply values from theme 1`] = `
<View
replaceTheme={[Function]}
style={
Object {
"backgroundColor": "white",
Expand Down Expand Up @@ -30,6 +31,7 @@ exports[`Card Component should apply values from theme 1`] = `
>
<View>
<Text
replaceTheme={[Function]}
style={
Object {
"color": "#43484d",
Expand Down Expand Up @@ -85,6 +87,7 @@ exports[`Card Component should apply values from theme 1`] = `
Yea b
</Text>
<View
replaceTheme={[Function]}
style={
Object {
"backgroundColor": "#bcbbc1",
Expand Down
20 changes: 14 additions & 6 deletions src/config/ThemeProvider.js
Expand Up @@ -10,13 +10,14 @@ export default class ThemeProvider extends React.Component {
constructor(props) {
super(props);

this.defaultTheme = deepmerge(
{
colors,
},
props.theme
);
this.state = {
theme: deepmerge(
{
colors,
},
props.theme
),
theme: this.defaultTheme,
};
}

Expand All @@ -26,6 +27,12 @@ export default class ThemeProvider extends React.Component {
}));
};

replaceTheme = theme => {
this.setState(() => ({
theme: deepmerge(this.defaultTheme, theme),
}));
};

getTheme = () => this.state.theme;

render() {
Expand All @@ -34,6 +41,7 @@ export default class ThemeProvider extends React.Component {
value={{
theme: this.state.theme,
updateTheme: this.updateTheme,
replaceTheme: this.replaceTheme,
}}
>
{this.props.children}
Expand Down
8 changes: 7 additions & 1 deletion src/config/__tests__/ThemeProvider.js
Expand Up @@ -17,7 +17,7 @@ describe('ThemeProvider', () => {
expect(toJson(component)).toMatchSnapshot();
});

it('should update theme', () => {
it('should update and replace theme', () => {
const component = shallow(
<ThemeProvider>
<View />
Expand All @@ -44,6 +44,12 @@ describe('ThemeProvider', () => {
},
},
});

instance.replaceTheme({});

expect(instance.state).toEqual({
theme,
});
});

it('should get the theme', () => {
Expand Down
1 change: 1 addition & 0 deletions src/config/__tests__/__snapshots__/ThemeProvider.js.snap
Expand Up @@ -4,6 +4,7 @@ exports[`ThemeProvider should work 1`] = `
<ContextProvider
value={
Object {
"replaceTheme": [Function],
"theme": Object {
"colors": Object {
"disabled": "hsl(208, 8%, 90%)",
Expand Down
3 changes: 2 additions & 1 deletion src/config/withTheme.js
Expand Up @@ -27,10 +27,11 @@ const withTheme = (WrappedComponent, themeKey) => {
);
}

const { theme, updateTheme } = context;
const { theme, updateTheme, replaceTheme } = context;
const props = {
theme,
updateTheme,
replaceTheme,
...deepmerge((themeKey && theme[themeKey]) || {}, rest),
children,
};
Expand Down
1 change: 1 addition & 0 deletions src/divider/__tests__/__snapshots__/Divider.js.snap
Expand Up @@ -2,6 +2,7 @@

exports[`Divider Component should apply values from theme 1`] = `
<View
replaceTheme={[Function]}
style={
Object {
"backgroundColor": "red",
Expand Down
1 change: 1 addition & 0 deletions src/header/__tests__/__snapshots__/Header.js.snap
Expand Up @@ -18,6 +18,7 @@ exports[`Header Component should apply values from theme 1`] = `
}
>
<Image
replaceTheme={[Function]}
style={
Array [
Object {
Expand Down
1 change: 1 addition & 0 deletions src/icons/__tests__/__snapshots__/Icon.js.snap
Expand Up @@ -172,6 +172,7 @@ exports[`Icon component should apply reverse styles 1`] = `
exports[`Icon component should apply values from theme 1`] = `
<View>
<View
replaceTheme={[Function]}
style={
Object {
"alignItems": "center",
Expand Down
1 change: 1 addition & 0 deletions src/image/__tests__/__snapshots__/Image.js.snap
Expand Up @@ -32,6 +32,7 @@ exports[`Image Component should apply values from theme 1`] = `
/>
</View>
<Image
replaceTheme={[Function]}
source={
Object {
"uri": "https://i.imgur.com/0y8Ftya.jpg",
Expand Down
4 changes: 4 additions & 0 deletions src/index.d.ts
Expand Up @@ -2019,9 +2019,12 @@ export type Theme<T = {}> = Partial<FullTheme> & T;

export type UpdateTheme = (updates: RecursivePartial<FullTheme>) => void;

export type ReplaceTheme = (updates: RecursivePartial<FullTheme>) => void;

export interface ThemeProps<T> {
theme: Theme<T>;
updateTheme: UpdateTheme;
replaceTheme: ReplaceTheme;
}

/**
Expand All @@ -2034,6 +2037,7 @@ export interface ThemeProviderProps<T> {

export class ThemeProvider<T> extends React.Component<ThemeProviderProps<T>> {
updateTheme: UpdateTheme;
replaceTheme: ReplaceTheme;

getTheme(): Theme<T>;
}
Expand Down
1 change: 1 addition & 0 deletions src/input/__tests__/__snapshots__/Input.js.snap
Expand Up @@ -732,6 +732,7 @@ exports[`Input component should apply values from theme 1`] = `
<TextInput
allowFontScaling={true}
placeholder="Enter text"
replaceTheme={[Function]}
style={
Object {
"alignSelf": "center",
Expand Down
2 changes: 2 additions & 0 deletions src/list/__tests__/__snapshots__/ListItem.js.snap
Expand Up @@ -2,6 +2,7 @@

exports[`ListItem component should apply values from theme 1`] = `
<View
replaceTheme={[Function]}
updateTheme={[Function]}
>
<View
Expand All @@ -24,6 +25,7 @@ exports[`ListItem component should apply values from theme 1`] = `
}
>
<Text
replaceTheme={[Function]}
style={
Object {
"backgroundColor": "transparent",
Expand Down
1 change: 1 addition & 0 deletions src/overlay/__tests__/__snapshots__/Overlay.js.snap
Expand Up @@ -4,6 +4,7 @@ exports[`Overlay should apply values from theme 1`] = `
<Modal
hardwareAccelerated={false}
onRequestClose={[Function]}
replaceTheme={[Function]}
theme={
Object {
"Overlay": Object {
Expand Down
7 changes: 7 additions & 0 deletions src/pricing/__tests__/__snapshots__/PricingCard.js.snap
Expand Up @@ -2,6 +2,7 @@

exports[`PricingCard component should apply values from theme 1`] = `
<View
replaceTheme={[Function]}
style={
Object {
"backgroundColor": "white",
Expand Down Expand Up @@ -29,6 +30,7 @@ exports[`PricingCard component should apply values from theme 1`] = `
}
>
<Text
replaceTheme={[Function]}
style={
Object {
"color": "#2089dc",
Expand Down Expand Up @@ -83,6 +85,7 @@ exports[`PricingCard component should apply values from theme 1`] = `
ALL YOU CAN EAT
</Text>
<Text
replaceTheme={[Function]}
style={
Object {
"fontSize": 50,
Expand Down Expand Up @@ -137,6 +140,7 @@ exports[`PricingCard component should apply values from theme 1`] = `
$0
</Text>
<Text
replaceTheme={[Function]}
style={
Object {
"color": "#86939e",
Expand Down Expand Up @@ -191,6 +195,7 @@ exports[`PricingCard component should apply values from theme 1`] = `
1 User
</Text>
<Text
replaceTheme={[Function]}
style={
Object {
"color": "#86939e",
Expand Down Expand Up @@ -245,6 +250,7 @@ exports[`PricingCard component should apply values from theme 1`] = `
Basic Support
</Text>
<Text
replaceTheme={[Function]}
style={
Object {
"color": "#86939e",
Expand Down Expand Up @@ -338,6 +344,7 @@ exports[`PricingCard component should apply values from theme 1`] = `
>
<View>
<View
replaceTheme={[Function]}
style={
Object {
"alignItems": "center",
Expand Down
2 changes: 2 additions & 0 deletions src/searchbar/__tests__/__snapshots__/SearchBar.js.snap
Expand Up @@ -46,6 +46,7 @@ exports[`SearchBar wrapper component should apply values from theme 1`] = `
>
<View>
<View
replaceTheme={[Function]}
style={
Object {
"alignItems": "center",
Expand Down Expand Up @@ -131,6 +132,7 @@ exports[`SearchBar wrapper component should apply values from theme 1`] = `
onFocus={[Function]}
placeholder="Enter search term"
platform="android"
replaceTheme={[Function]}
style={
Object {
"alignSelf": "center",
Expand Down
1 change: 1 addition & 0 deletions src/social/__tests__/__snapshots__/SocialIcon.js.snap
Expand Up @@ -2,6 +2,7 @@

exports[`SocialIcon component should apply values from theme 1`] = `
<View
replaceTheme={[Function]}
style={
Object {
"alignItems": "center",
Expand Down
2 changes: 2 additions & 0 deletions src/text/__tests__/__snapshots__/Text.js.snap
Expand Up @@ -2,6 +2,7 @@

exports[`Text Component local props should override style props on theme 1`] = `
<Text
replaceTheme={[Function]}
style={
Object {
"fontSize": 42.5,
Expand Down Expand Up @@ -63,6 +64,7 @@ exports[`Text Component should render without issues 1`] = `

exports[`Text Component should use values from the theme 1`] = `
<Text
replaceTheme={[Function]}
style={
Object {
"fontSize": 27.5,
Expand Down
1 change: 1 addition & 0 deletions src/tile/__tests__/__snapshots__/FeaturedTile.js.snap
Expand Up @@ -157,6 +157,7 @@ exports[`FeaturedTitle component should apply values from theme 1`] = `
}
/>
<Text
replaceTheme={[Function]}
style={
Object {
"backgroundColor": "rgba(0,0,0,0)",
Expand Down
1 change: 1 addition & 0 deletions src/tile/__tests__/__snapshots__/Tile.js.snap
Expand Up @@ -135,6 +135,7 @@ exports[`Tile component should apply styles from theme 1`] = `
}
>
<Text
replaceTheme={[Function]}
style={
Object {
"backgroundColor": "rgba(0,0,0,0)",
Expand Down

0 comments on commit e2f2e6e

Please sign in to comment.