Guest User

Untitled

a guest
Feb 16th, 2019
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.30 KB | None | 0 0
  1. // @flow
  2. import * as React from 'react';
  3. import PropTypes from 'prop-types';
  4.  
  5.  
  6. const contextTypes = {
  7. insertCss: PropTypes.func,
  8. };
  9. type StylesContextType = KeyValueOfType<Object>;
  10. const { Provider, Consumer } = React.createContext<StylesContextType>({});
  11. const getThemeFromContext = <Theme>(id: string, context: StylesContextType): Theme | void => {
  12. const theme = context[id];
  13.  
  14. if (!theme) {
  15. return;
  16. }
  17.  
  18. return (theme: any);
  19. };
  20.  
  21.  
  22. type StyleThemeResolverType<Theme, Props> = (Props, Theme | void) => Theme | void;
  23.  
  24. type StyleThemeParams<Theme, Props> = {
  25. id: string,
  26. styles: Array<Object>,
  27. resolveTheme?: StyleThemeResolverType<Theme, Props>,
  28. };
  29.  
  30. type StyleThemeProviderType<Theme, Props> = {
  31. <Props>(Theme): (React.ComponentType<Props>) => React.ComponentType<Props>,
  32. $$styleThemeId: string,
  33. $$styleThemeStyles: Array<Object>,
  34. $$styleThemeResolver: StyleThemeResolverType<Theme, Props>,
  35. }
  36.  
  37. export function createStyleTheme<Theme, Props>(
  38. { id, styles, resolveTheme }: StyleThemeParams<Theme, Props>,
  39. ): StyleThemeProviderType<Theme, Props> {
  40. const defaultResolver = (props, styleTheme) => styleTheme;
  41. const resolver = resolveTheme || defaultResolver;
  42.  
  43. const styleThemeProvider = (theme) => (Component) => (props) => (
  44. <Consumer>
  45. {(context) => (
  46. <Provider value={{ ...context, [id]: theme }}>
  47. <Component {...props} />
  48. </Provider>
  49. )}
  50. </Consumer>
  51. );
  52.  
  53. styleThemeProvider.$$styleThemeId = id;
  54. styleThemeProvider.$$styleThemeStyles = styles;
  55. styleThemeProvider.$$styleThemeResolver = resolver;
  56.  
  57. return styleThemeProvider;
  58. }
  59.  
  60.  
  61. export type StyleThemePropType = {
  62. s: Object,
  63. };
  64.  
  65. type StylesType<Theme, Props> =
  66. | CssModuleType
  67. | StyleThemeProviderType<Theme, Props>;
  68.  
  69. function withStyles<Theme: Object, Props: Object>(styles: StylesType<Theme, Props>) {
  70. let getStyles;
  71. let resolveStyles: (Props, StylesContextType) => Theme | void;
  72.  
  73. if (typeof styles.$$styleThemeResolver === 'function') {
  74. const resolver = styles.$$styleThemeResolver;
  75.  
  76. getStyles = () => styles.$$styleThemeStyles;
  77. resolveStyles = (props, context) => {
  78. const stylesTheme = getThemeFromContext(styles.$$styleThemeId, context);
  79.  
  80. return resolver(props, stylesTheme);
  81. };
  82. } else {
  83. getStyles = () => [styles];
  84. resolveStyles = () => {};
  85. }
  86.  
  87. return function wrapWithStyles(
  88. ComposedComponent: React.ComponentType<Props & StyleThemePropType>,
  89. ): React.ComponentType<Props> {
  90. class WithStyles extends React.PureComponent<Props> {
  91. removeCss: Function;
  92.  
  93. constructor(props, context) {
  94. super(props, context);
  95.  
  96. this.removeCss = context.insertCss(...getStyles());
  97. }
  98.  
  99. componentWillUnmount() {
  100. if (this.removeCss) {
  101. setTimeout(this.removeCss, 0);
  102. }
  103. }
  104.  
  105. render() {
  106. return (
  107. <Consumer>
  108. {(context) => {
  109. const s = resolveStyles(this.props, context);
  110.  
  111. return (
  112. <ComposedComponent s={s} {...this.props} />
  113. );
  114. }}
  115. </Consumer>
  116. );
  117. }
  118. }
  119.  
  120. const displayName = ComposedComponent.displayName || ComposedComponent.name || '';
  121.  
  122. WithStyles.displayName = `WithStyles(${displayName})`;
  123. WithStyles.contextTypes = contextTypes;
  124.  
  125. return WithStyles;
  126. };
  127. }
  128.  
  129. export default withStyles;
Add Comment
Please, Sign In to add comment