forked from skiff-org/skiff-ui
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
fd90e2e
commit 9f85b23
Showing
11 changed files
with
134 additions
and
21 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
2 changes: 1 addition & 1 deletion
2
built/src/components/Button/IconButton/IconButton.styles.d.ts.map
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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,2 +1,3 @@ | ||
export { AppThemeProvider, isOfTypeThemeName, ThemeContext, THEME_LOCAL_STORAGE_KEY, THEME_SELECT_VERSION, useTheme } from './AppThemeProvider'; | ||
export * from './theme'; | ||
//# sourceMappingURL=index.d.ts.map |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
Large diffs are not rendered by default.
Oops, something went wrong.
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,107 @@ | ||
import noop from 'lodash/noop'; | ||
import React, { createContext, useCallback, useContext, useEffect, useState } from 'react'; | ||
import { LocalStorageThemeMode, StorageOnlyThemeMode, ThemeMode } from 'src/types'; | ||
import { createGlobalStyle, ThemeProvider } from 'styled-components'; | ||
|
||
import { themeNames } from './theme'; | ||
|
||
export const THEME_SELECT_VERSION = '0.1.0'; | ||
|
||
// validate type (necessary if older theme still stored in local storage) | ||
export function isOfTypeThemeName(keyInput: LocalStorageThemeMode) { | ||
return keyInput === ThemeMode.LIGHT || keyInput === ThemeMode.DARK; | ||
} | ||
|
||
type ThemeContextType = { | ||
// displayed theme | ||
theme: ThemeMode; | ||
// theme in local storage | ||
storedTheme: LocalStorageThemeMode; | ||
// update theme in local storage | ||
setStoredTheme: (name: LocalStorageThemeMode) => void; | ||
}; | ||
|
||
export const ThemeContext = createContext<ThemeContextType>({ | ||
theme: ThemeMode.LIGHT, | ||
storedTheme: StorageOnlyThemeMode.SYSTEM, | ||
setStoredTheme: noop | ||
}); | ||
|
||
export const useTheme = () => useContext(ThemeContext); | ||
|
||
export const THEME_LOCAL_STORAGE_KEY = 'THEME_MODE'; | ||
|
||
const GlobalStyles = createGlobalStyle` | ||
body { | ||
font-family: 'Skiff Sans Text', sans-serif; | ||
-webkit-font-smoothing: antialiased; | ||
font-smoothing: antialiased; | ||
} | ||
`; | ||
export const AppThemeProvider: React.FC = ({ children }) => { | ||
const [themeName, setThemeName] = useState<ThemeMode>(ThemeMode.DARK); | ||
const [storedThemeState, setStoredThemeState] = useState<LocalStorageThemeMode>(StorageOnlyThemeMode.SYSTEM); | ||
|
||
let darkSystemThemeMediaQuery: MediaQueryList | undefined; | ||
if (typeof window !== 'undefined') { | ||
darkSystemThemeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); | ||
} | ||
|
||
const updateRootData = (theme: ThemeMode) => { | ||
const themeColor = themeNames[theme]; | ||
Object.keys(themeColor).forEach((key) => { | ||
document.body.style.setProperty(key, themeColor[key]); | ||
}); | ||
}; | ||
|
||
const updateThemeName = useCallback( | ||
(name: LocalStorageThemeMode, darkSystemThemeMediaQuery?: MediaQueryList) => { | ||
setStoredThemeState(name); | ||
// if name is light or dark, set it to theme | ||
if (isOfTypeThemeName(name)) { | ||
setThemeName(name as ThemeMode); | ||
updateRootData(name as ThemeMode); | ||
} else if (darkSystemThemeMediaQuery !== undefined) { | ||
// otherwise parse the system theme | ||
const themeMode = darkSystemThemeMediaQuery.matches ? ThemeMode.DARK : ThemeMode.LIGHT; | ||
setThemeName(themeMode); | ||
updateRootData(themeMode); | ||
} | ||
}, | ||
[darkSystemThemeMediaQuery] | ||
); | ||
|
||
const setStoredTheme = (name: LocalStorageThemeMode) => { | ||
// update local storage | ||
localStorage.setItem(THEME_LOCAL_STORAGE_KEY, name); | ||
updateThemeName(name, darkSystemThemeMediaQuery); | ||
}; | ||
|
||
// Get theme from localStorage when app loads | ||
useEffect(() => { | ||
// if nothing stored default to system | ||
const storedThemeMode = (localStorage.getItem(THEME_LOCAL_STORAGE_KEY) as ThemeMode) || StorageOnlyThemeMode.SYSTEM; | ||
updateThemeName(storedThemeMode, darkSystemThemeMediaQuery); | ||
}, []); | ||
|
||
// Listen to live system changes | ||
useEffect(() => { | ||
if (storedThemeState !== StorageOnlyThemeMode.SYSTEM || darkSystemThemeMediaQuery === undefined) return; | ||
const updateSystemTheme = () => updateThemeName(StorageOnlyThemeMode.SYSTEM, darkSystemThemeMediaQuery); | ||
darkSystemThemeMediaQuery.addEventListener('change', updateSystemTheme); | ||
return () => { | ||
if (darkSystemThemeMediaQuery === undefined) return; | ||
darkSystemThemeMediaQuery.removeEventListener('change', updateSystemTheme); | ||
}; | ||
}, [storedThemeState, darkSystemThemeMediaQuery, updateThemeName]); | ||
|
||
// updated `theme` object will be defined by design system and used here | ||
return ( | ||
<ThemeProvider theme={{}}> | ||
<ThemeContext.Provider value={{ theme: themeName, setStoredTheme, storedTheme: storedThemeState }}> | ||
<GlobalStyles /> | ||
{children} | ||
</ThemeContext.Provider> | ||
</ThemeProvider> | ||
); | ||
}; |
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 +1,9 @@ | ||
export { | ||
AppThemeProvider, | ||
isOfTypeThemeName, | ||
ThemeContext, | ||
THEME_LOCAL_STORAGE_KEY, | ||
THEME_SELECT_VERSION, | ||
useTheme | ||
} from './AppThemeProvider'; | ||
export * from './theme'; |