-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add theme manager context for changing theme easier
- Loading branch information
1 parent
b8717a9
commit d1f8aa5
Showing
7 changed files
with
227 additions
and
11 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,37 @@ | ||
import React from 'react'; | ||
import Button from '@material-ui/core/Button'; | ||
import red from '@material-ui/core/colors/red'; | ||
import lime from '@material-ui/core/colors/lime'; | ||
import Link from 'next/link'; | ||
|
||
const Index = () => ( | ||
<div> | ||
<Button color="primary">Hello World</Button> | ||
<Link href="/page1"> | ||
<Button>To Page1</Button> | ||
</Link> | ||
</div> | ||
); | ||
import { useThemeManagerContext } from '../src'; | ||
|
||
const theme2 = { | ||
palette: { | ||
primary: red, | ||
secondary: lime, | ||
}, | ||
}; | ||
|
||
const Index = () => { | ||
const { setTheme } = useThemeManagerContext(); | ||
const handleChangeTheme = () => { | ||
setTheme(theme2, () => { | ||
console.log('changed to theme2!'); | ||
}); | ||
}; | ||
|
||
return ( | ||
<div> | ||
<Button color="primary">Hello World</Button> | ||
<Button color="secondary" variant="outlined" onClick={handleChangeTheme}> | ||
Change Theme | ||
</Button> | ||
<Link href="/page1"> | ||
<Button>To Page1</Button> | ||
</Link> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Index; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import React, { useContext } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
|
||
const initState = { | ||
theme: {}, | ||
// eslint-disable-next-line no-unused-vars | ||
setTheme: (theme, callback) => {}, | ||
}; | ||
|
||
const ThemeManagerContext = React.createContext(initState); | ||
|
||
class ThemeManagerProvider extends React.PureComponent { | ||
constructor(props) { | ||
super(props); | ||
|
||
this.state = { | ||
theme: props.initTheme || initState.theme, | ||
}; | ||
} | ||
|
||
setTheme = (theme, callback) => { | ||
this.setState({ theme }, () => { | ||
if (callback && typeof callback === 'function') { | ||
callback(theme); | ||
} | ||
}); | ||
}; | ||
|
||
render() { | ||
const { children } = this.props; | ||
const { theme } = this.state; | ||
|
||
return ( | ||
<ThemeManagerContext.Provider | ||
value={{ | ||
theme, | ||
setTheme: this.setTheme, | ||
}} | ||
> | ||
{children} | ||
</ThemeManagerContext.Provider> | ||
); | ||
} | ||
} | ||
|
||
ThemeManagerProvider.propTypes = { | ||
children: PropTypes.any.isRequired, | ||
initTheme: PropTypes.object, | ||
}; | ||
|
||
ThemeManagerProvider.defaultProps = { | ||
initTheme: {}, | ||
} | ||
|
||
const useThemeManagerContext = () => { | ||
return useContext(ThemeManagerContext); | ||
}; | ||
|
||
const withThemeManager = BaseComponent => { | ||
const WithThemeManager = props => { | ||
return ( | ||
<ThemeManagerContext.Consumer> | ||
{ctx => { | ||
return <BaseComponent {...ctx} {...props} />; | ||
}} | ||
</ThemeManagerContext.Consumer> | ||
); | ||
}; | ||
|
||
return WithThemeManager; | ||
}; | ||
|
||
export { ThemeManagerContext as default, ThemeManagerProvider, useThemeManagerContext, withThemeManager }; |
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
export const sameArray = (arr1, arr2) => { | ||
return arr1.length === arr2.length && arr1.every(v => arr2.indexOf(v) > -1); | ||
}; | ||
|
||
/** | ||
* Deep Check if two object is same or not | ||
* | ||
* @param {*} obj1 | ||
* @param {*} obj2 | ||
*/ | ||
export default function deepCompareObj(obj1, obj2) { | ||
if (typeof obj1 !== 'object' || typeof obj2 !== 'object') { | ||
return false; | ||
} | ||
|
||
const obj1Keys = Object.keys(obj1); | ||
const obj2Keys = Object.keys(obj2); | ||
|
||
// compare keys first | ||
if (!sameArray(obj1Keys, obj2Keys)) return false; | ||
|
||
return obj1Keys.every(key => { | ||
if (Array.isArray(obj1[key])) { | ||
if (!sameArray(obj1[key], obj2[key])) { | ||
return false; | ||
} | ||
} else if (typeof obj1[key] === 'object') { | ||
return deepCompareObj(obj1[key], obj2[key]); | ||
} else if (obj1[key] !== obj2[key]) { | ||
return false; | ||
} | ||
|
||
return true; | ||
}); | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import deepCompareObj from '../../src/util/deepCompareObj'; | ||
|
||
test('input is not object', () => { | ||
const obj1 = { a: 1 }; | ||
const obj2 = 'a1'; | ||
|
||
const result1 = deepCompareObj(obj1, obj2); | ||
const result2 = deepCompareObj(obj2, obj1); | ||
|
||
expect(result1).toEqual(false); | ||
expect(result2).toEqual(false); | ||
}); | ||
|
||
test('input empty', () => { | ||
const obj1 = {}; | ||
const obj2 = {}; | ||
|
||
const result = deepCompareObj(obj1, obj2); | ||
|
||
expect(result).toEqual(true); | ||
}); | ||
|
||
test('input have nested object', () => { | ||
const obj1 = { a: { b: { b1: 111, b2: 222 } }, c: 'hello' }; | ||
const obj2 = { c: 'hello', a: { b: { b2: 222, b1: 111 } } }; | ||
|
||
const result = deepCompareObj(obj1, obj2); | ||
|
||
expect(result).toEqual(true); | ||
}); | ||
|
||
test('input have array value', () => { | ||
const obj1 = { a: [1, 2, 3] }; | ||
const obj2 = { a: [2, 3, 1] }; | ||
|
||
const result = deepCompareObj(obj1, obj2); | ||
|
||
expect(result).toEqual(true); | ||
}); | ||
|
||
test('input have different array value', () => { | ||
const obj1 = { a: [1, 2, 3] }; | ||
const obj2 = { a: [2, 3, 4] }; | ||
|
||
const result = deepCompareObj(obj1, obj2); | ||
|
||
expect(result).toEqual(false); | ||
}); | ||
|
||
test('input have different object value', () => { | ||
const obj1 = { a: { b: 1 } }; | ||
const obj2 = { a: { c: 1 } }; | ||
|
||
const result = deepCompareObj(obj1, obj2); | ||
|
||
expect(result).toEqual(false); | ||
}); | ||
|
||
test('input have different normal value', () => { | ||
const obj1 = { a: 1 }; | ||
const obj2 = { a: '1' }; | ||
|
||
const result = deepCompareObj(obj1, obj2); | ||
|
||
expect(result).toEqual(false); | ||
}); |