-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Theme switching: Create theme/styling hooks and context components #21667
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
96 commits
Select commit
Hold shift + click to select a range
7d538de
Implement ThemeProvider with only one animated color (WIP)
92b9835
Wrap app with ThemeProvider
7aa60de
use animated color for app background
288160e
add change listener to useIsLightMode
81f2f94
Removing shouldKeyReportActionsByID
chiragsalian fb3b662
Merge branch 'main' into @chrispader/theme-switching
564e5b0
fix: wrong imports
774856d
move hooks to actual function body
866344a
fix: missing React import
63e8323
add flex 1
1d9c20c
fix: move ThemeProvider into ComposeProviders
55b04f7
Merge branch 'main' into @chrispader/theme-switching
5c2ad33
subscribe to system color theme and add ONYXKEY
fc0c32d
update ThemeProvider
6122a37
chore: update reanimated
1a20110
add missing useEffect dependency
9d8aafd
remove color animation from NavigationRoot
bf67d21
move reanimated babel plugin to last position
8adeef7
Add theme switching button to Expensify main component
698ae62
Add color animation to ReportScreen
5f0c824
update reanimated again
26d12a1
downgrade rea to 3.0.0
a4d11b0
move animation test to Expensify component
71d6744
update REA
1b7a1a9
add patch for reanimated bug (https://github.com/react-navigation/rea…
f340e6f
add random view with animated color
798f57a
downgrade cocoapods version
fb722f2
use ComposeProviders for ThemeProvider
d294ea7
extract theme color interpolation into hook
cd481d5
use default dark colors as ThemeContext default value
7b33416
update demonstration view
96416d2
handle the case when there is no theme set yet
1ce89f7
simplify demo
f555698
move light color values into an external object
4ea846f
Merge branch 'main' into @chrispader/theme-switching
e80d068
improve when theme animation is triggered
68e554c
update "useIsLightMode" hook into "useColorPreference"
4c268e0
add StylesProvider, useStyles and useTheme hook
b493fc1
fix eslint errors
6b504ed
reset NavigationRoot
62e96ce
Merge branch 'main' into @chrispader/theme-switching
4275e90
add color theme preferences
4e32f73
move demo to ReportScreen
72d5925
update pods
92b0a96
Merge branch 'main' into @chrispader/theme-switching
ca8bc6e
Merge branch 'main' into @chrispader/theme-switching
6c655b1
fix: linting
3c23fd2
Merge branch 'main' into @chrispader/theme-switching
df0f050
rename certain files
90dbc19
re-write documentation so it fits the new file structure
b3bd015
fix import
6360b9a
Merge branch 'main' into @chrispader/theme-switching
72e2e06
rename useColorPreference hook to useThemePreference
a09f3f9
Merge branch 'main' into @chrispader/theme-switching
9779bda
rename styles file back
ffa2087
fix: demo
48bac2b
Merge branch 'main' into @chrispader/theme-switching
7d85d8c
rename ThemeStylesProvider and remove animations
5c99ef1
Merge branch 'main' into @chrispader/theme-switching
99fa85e
remove extra line
0295709
add DEFAULT_THEME to useThemePreference hook
e4e9016
remove REA ThemeProvider
12d5417
add back line
1d8659d
add back color value
5384efb
use constant color theme values
f640466
remove changes to preferences
decf617
remove ColorThemePage
e83d9d0
Merge branch 'main' into @chrispader/theme-switching
d0c7471
update ThemeStylesContext name
a48328a
fix: consistent naming
a2fe0a6
fix: ThemeStylesProvider name
a1cb1b5
Update src/ONYXKEYS.js
chrispader 1e01bcf
Merge branch 'main' into @chrispader/theme-switching
chrispader 656bdf9
fix: theme name consistency and comments
chrispader 5274bf7
Merge branch '@chrispader/theme-switching' of github.com:margelo/expe…
chrispader 7db4a93
remove mock light theme
e638d8e
add comment
14b2b6d
fix: wrong variable
8358a20
update context variable names
9b6d3a8
fix: prettier
97def5a
Merge branch 'main' into @chrispader/theme-switching
5661be1
fix: legacy REA code
chrispader c342542
update comment
chrispader b91894a
use value from CONST
chrispader 99eef40
update conditionals
chrispader 1aee573
move default theme to `CONST.THEME`
chrispader de29201
Merge branch 'main' into @chrispader/theme-switching
c3da152
remove reanimated patch file
c1d67ce
add comment about reanimated plugin
chrispader b3f939b
Merge branch 'main' into @chrispader/theme-switching
d4ac193
Merge branch 'main' into @chrispader/theme-switching
chrispader abd5b2c
add prop types comments
chrispader 51ab4d4
add PreferredThemeProvider
chrispader 74ec10f
remove Onyx.connect and add comment
chrispader fa306fc
Merge branch 'main' into @chrispader/theme-switching
chrispader 73935f0
remove unused import
chrispader File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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,6 @@ | ||
| import React from 'react'; | ||
| import styles from './styles'; | ||
|
|
||
| const ThemeStylesContext = React.createContext(styles); | ||
|
|
||
| export default ThemeStylesContext; |
This file contains hidden or 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,37 @@ | ||
| /* eslint-disable react/jsx-props-no-spreading */ | ||
| import React, {useMemo} from 'react'; | ||
| import PropTypes from 'prop-types'; | ||
| import useTheme from './themes/useTheme'; | ||
| import StylesContext from './ThemeStylesContext'; | ||
| import defaultStyles from './styles'; | ||
|
|
||
| const propTypes = { | ||
| /** Rendered child component */ | ||
| children: PropTypes.node.isRequired, | ||
|
chrispader marked this conversation as resolved.
|
||
| }; | ||
|
|
||
| function ThemeStylesProvider(props) { | ||
| const theme = useTheme(); | ||
|
|
||
| const appContentStyle = useMemo( | ||
| () => ({ | ||
| ...defaultStyles.appContent, | ||
| backgroundColor: theme.appBG, | ||
| }), | ||
| [theme.appBG], | ||
| ); | ||
|
|
||
| const styles = useMemo( | ||
| () => ({ | ||
| ...defaultStyles, | ||
| appContent: appContentStyle, | ||
| }), | ||
| [appContentStyle], | ||
| ); | ||
|
|
||
| return <StylesContext.Provider value={styles}>{props.children}</StylesContext.Provider>; | ||
| } | ||
| ThemeStylesProvider.propTypes = propTypes; | ||
| ThemeStylesProvider.displayName = 'ThemeStylesProvider'; | ||
|
|
||
| export default ThemeStylesProvider; | ||
This file contains hidden or 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,6 @@ | ||
| import React from 'react'; | ||
| import defaultColors from './default'; | ||
|
|
||
| const ThemeContext = React.createContext(defaultColors); | ||
|
|
||
| export default ThemeContext; |
This file contains hidden or 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,27 @@ | ||
| /* eslint-disable react/jsx-props-no-spreading */ | ||
| import React, {useMemo} from 'react'; | ||
| import PropTypes from 'prop-types'; | ||
| import ThemeContext from './ThemeContext'; | ||
| import useThemePreference from './useThemePreference'; | ||
| import CONST from '../../CONST'; | ||
|
|
||
| // Going to eventually import the light theme here too | ||
| import darkTheme from './default'; | ||
|
|
||
| const propTypes = { | ||
| /** Rendered child component */ | ||
| children: PropTypes.node.isRequired, | ||
|
chrispader marked this conversation as resolved.
|
||
| }; | ||
|
|
||
| function ThemeProvider(props) { | ||
| const themePreference = useThemePreference(); | ||
|
|
||
| const theme = useMemo(() => (themePreference === CONST.THEME.LIGHT ? /* TODO: replace with light theme */ darkTheme : darkTheme), [themePreference]); | ||
|
|
||
| return <ThemeContext.Provider value={theme}>{props.children}</ThemeContext.Provider>; | ||
| } | ||
|
|
||
| ThemeProvider.propTypes = propTypes; | ||
| ThemeProvider.displayName = 'ThemeProvider'; | ||
|
|
||
| export default ThemeProvider; | ||
This file contains hidden or 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,14 @@ | ||
| import {useContext} from 'react'; | ||
| import ThemeContext from './ThemeContext'; | ||
|
|
||
| function useTheme() { | ||
| const theme = useContext(ThemeContext); | ||
|
|
||
| if (!theme) { | ||
| throw new Error('StylesContext was null! Are you sure that you wrapped the component under a <ThemeProvider>?'); | ||
| } | ||
|
|
||
| return theme; | ||
| } | ||
|
|
||
| export default useTheme; |
This file contains hidden or 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,28 @@ | ||
| import {useState, useEffect, useContext} from 'react'; | ||
| import {Appearance} from 'react-native'; | ||
| import CONST from '../../CONST'; | ||
| import {PreferredThemeContext} from '../../components/OnyxProvider'; | ||
|
|
||
| function useThemePreference() { | ||
| const [themePreference, setThemePreference] = useState(CONST.THEME.DEFAULT); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Setting a default value for |
||
| const [systemTheme, setSystemTheme] = useState(); | ||
| const preferredThemeContext = useContext(PreferredThemeContext); | ||
|
|
||
| useEffect(() => { | ||
| // This is used for getting the system theme, that can be set in the OS's theme settings. This will always return either "light" or "dark" and will update automatically if the OS theme changes. | ||
| const systemThemeSubscription = Appearance.addChangeListener(({colorScheme}) => setSystemTheme(colorScheme)); | ||
| return systemThemeSubscription.remove; | ||
| }, []); | ||
|
|
||
| useEffect(() => { | ||
| const theme = preferredThemeContext || CONST.THEME.DEFAULT; | ||
|
|
||
| // If the user chooses to use the device theme settings, we need to set the theme preference to the system theme | ||
| if (theme === CONST.THEME.SYSTEM) setThemePreference(systemTheme); | ||
| else setThemePreference(theme); | ||
| }, [preferredThemeContext, systemTheme]); | ||
|
|
||
| return themePreference; | ||
| } | ||
|
|
||
| export default useThemePreference; | ||
This file contains hidden or 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,14 @@ | ||
| import {useContext} from 'react'; | ||
| import ThemeStylesContext from './ThemeStylesContext'; | ||
|
|
||
| function useThemeStyles() { | ||
| const themeStyles = useContext(ThemeStylesContext); | ||
|
|
||
| if (!themeStyles) { | ||
| throw new Error('StylesContext was null! Are you sure that you wrapped the component under a <ThemeStylesProvider>?'); | ||
| } | ||
|
|
||
| return themeStyles; | ||
| } | ||
|
|
||
| export default useThemeStyles; |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.