content: var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
  
  import React from 'react';
  import PropTypes from 'prop-types';
  import createBroadcast from 'brcast';
  import themeListener, { CHANNEL } from './themeListener';
  import exactProp from '../utils/exactProp';
  
  /**
   * This component takes a `theme` property.
   * It makes the `theme` available down the React tree thanks to React context.
   * This component should preferably be used at **the root of your component tree**.
   */
  class MuiThemeProvider extends React.Component {
  
    constructor(props, context) {
      super(props, context);
  
      // Get the outer theme from the context, can be null
      this.broadcast = createBroadcast();
      this.unsubscribeId = null;
      this.outerTheme = null;
      this.outerTheme = themeListener.initial(context);
      // Propagate the theme so it can be accessed by the children
      this.broadcast.setState(this.mergeOuterLocalTheme(this.props.theme));
    }
  
    getChildContext() {
      return {
        [CHANNEL]: this.broadcast,
        muiThemeProviderOptions: {
          sheetsManager: this.props.sheetsManager,
          disableStylesGeneration: this.props.disableStylesGeneration
        }
      };
    }
  
    componentDidMount() {
      // Subscribe on the outer theme, if present
      this.unsubscribeId = themeListener.subscribe(this.context, outerTheme => {
        this.outerTheme = outerTheme;
        // Forward the parent theme update to the children
        this.broadcast.setState(this.mergeOuterLocalTheme(this.props.theme));
      });
    }
  
    componentWillReceiveProps(nextProps) {
      // Propagate a local theme update
      if (this.props.theme !== nextProps.theme) {
        this.broadcast.setState(this.mergeOuterLocalTheme(nextProps.theme));
      }
    }
  
    componentWillUnmount() {
      if (this.unsubscribeId !== null) {
        themeListener.unsubscribe(this.context, this.unsubscribeId);
      }
    }
    // We are not using the React state in order to avoid unnecessary rerender.
  
  
    // Simple merge between the outer theme and the local theme
    mergeOuterLocalTheme(localTheme) {
      // To support composition of theme.
      if (typeof localTheme === 'function') {
        return localTheme(this.outerTheme);
      }
  
      if (!this.outerTheme) {
        return localTheme;
      }
  
      return _extends({}, this.outerTheme, localTheme);
    }
  
    render() {
      return this.props.children;
    }
  }
  
  MuiThemeProvider.defaultProps = {
    disableStylesGeneration: false,
    sheetsManager: null
  };
  MuiThemeProvider.propTypes = {
    /**
     * You can only provide a single element with react@15, a node with react@16.
     */
    children: PropTypes.node.isRequired,
    /**
     * You can disable the generation of the styles with this option.
     * It can be useful when traversing the React tree outside of the HTML
     * rendering step on the server.
     * Let's say you are using react-apollo to extract all
     * the queries made by the interface server side.
     * You can significantly speed up the traversal with this property.
     */
    disableStylesGeneration: PropTypes.bool,
    /**
     * The sheetsManager is used to deduplicate style sheet injection in the page.
     * It's deduplicating using the (theme, styles) couple.
     * On the server, you should provide a new instance for each request.
     */
    sheetsManager: PropTypes.object,
    /**
     * A theme object.
     */
    theme: PropTypes.oneOfType([PropTypes.object, PropTypes.func]).isRequired
  };
  
  MuiThemeProvider.childContextTypes = _extends({}, themeListener.contextTypes, {
    muiThemeProviderOptions: PropTypes.object
  });
  
  MuiThemeProvider.contextTypes = themeListener.contextTypes;
  
  // Add a wrapper component to generate some helper messages in the development
  // environment.
  // eslint-disable-next-line import/no-mutable-exports
  let MuiThemeProviderWrapper = MuiThemeProvider;
  
  if (process.env.NODE_ENV !== 'production') {
    MuiThemeProviderWrapper = props => React.createElement(MuiThemeProvider, props);
    MuiThemeProviderWrapper.propTypes = exactProp(MuiThemeProvider.propTypes, 'MuiThemeProvider');
  }
  
  export default MuiThemeProviderWrapper;