import deepmerge from 'deepmerge'; import React, {useContext} from 'react'; import defaultTheme from './themes/default'; import $Colors from './themes/variable'; import $Theme from './themes/theme'; import $Layout from './themes/layout'; export const ThemeContext = React.createContext(defaultTheme); export type Theme = typeof defaultTheme & {[key: string]: any}; export type PartialTheme = Partial; export interface ThemeProviderProps { value?: PartialTheme; children?: React.ReactNode; } export const ThemeProvider = (props: ThemeProviderProps) => { const theme = {...defaultTheme, ...props.value}; return {props.children}; }; export interface UseThemeContextProps { theme?: PartialTheme; } export const useTheme = (props: UseThemeContextProps = {}) => { const theme = useContext(ThemeContext); return {...theme, ...props.theme}; }; export interface WithThemeProps { themeStyles: (theme: Theme) => T; styles?: S; children: ( // fix: styles[`${size}RawText`] styles: T & {[key: string]: any}, theme: Theme, ) => React.ReactNode; } /** * Component can extends this props */ export type WithThemeStyles = {styles?: Partial}; export class WithTheme extends React.Component> { static defaultProps = { themeStyles: () => {}, }; getStyles = (theme: Theme) => { const {themeStyles, styles} = this.props; const defaultThemeStyles = themeStyles(theme); if (styles) { // TODO: check these styles has changed // merge styles from user defined return deepmerge(defaultThemeStyles, styles); } return defaultThemeStyles; }; render() { return {(theme) => this.props.children(this.getStyles(theme), theme)}; } } export {$Colors, $Theme, $Layout};