Repository URL to install this package:
|
Version:
1.2.9 ▾
|
@skava/modules
/
___dist
/
view-container
/
styles
/
styled-components
/
src
/
models
/
ThemeProvider.js
|
|---|
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.CONTEXT_CHANNEL_SHAPE = exports.CHANNEL_NEXT = exports.CHANNEL = void 0;
var _react = _interopRequireWildcard(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _exotic = require("../../../../../exotic");
var _createBroadcast = require("../utils/create-broadcast");
var _once = _interopRequireDefault(require("../utils/once"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
// NOTE: DO NOT CHANGE, changing this is a semver major change!
const CHANNEL = '__styled-components__';
exports.CHANNEL = CHANNEL;
const CHANNEL_NEXT = `${CHANNEL}next__`;
exports.CHANNEL_NEXT = CHANNEL_NEXT;
const CONTEXT_CHANNEL_SHAPE = _propTypes.default.shape({
getTheme: _propTypes.default.func,
subscribe: _propTypes.default.func,
unsubscribe: _propTypes.default.func
});
exports.CONTEXT_CHANNEL_SHAPE = CONTEXT_CHANNEL_SHAPE;
let warnChannelDeprecated;
if (process.env.NODE_ENV !== 'production') {
warnChannelDeprecated = (0, _once.default)(() => {
// eslint-disable-next-line no-console
console.error(`Warning: Usage of \`context.${CHANNEL}\` as a function is deprecated. It will be replaced with the object on \`.context.${CHANNEL_NEXT}\` in a future version.`);
});
}
/**
* Provide a theme to an entire react component tree via context and event listeners (have to do
* both context and event emitter as pure components block context updates)
*/
let ThemeProvider = class ThemeProvider extends _react.Component {
constructor() {
super();
this.getTheme = void 0;
this.outerTheme = void 0;
this.unsubscribeToOuterId = void 0;
this.props = void 0;
this.broadcast = void 0;
this.unsubscribeToOuterId = -1;
this.getTheme = this.getTheme.bind(this);
}
componentWillMount() {
// If there is a ThemeProvider wrapper anywhere around this theme provider, merge this theme
// with the outer theme
const outerContext = this.context[CHANNEL_NEXT];
if (outerContext !== undefined) {
this.unsubscribeToOuterId = outerContext.subscribe(theme => {
this.outerTheme = theme;
if (this.broadcast !== undefined) {
this.publish(this.props.theme);
}
});
}
this.broadcast = (0, _createBroadcast.createBroadcast)(this.getTheme());
}
getChildContext() {
return _objectSpread({}, this.context, {
[CHANNEL_NEXT]: {
getTheme: this.getTheme,
subscribe: this.broadcast.subscribe,
unsubscribe: this.broadcast.unsubscribe
},
[CHANNEL]: subscriber => {
if (process.env.NODE_ENV !== 'production') {
warnChannelDeprecated();
} // Patch the old `subscribe` provide via `CHANNEL` for older clients.
const unsubscribeId = this.broadcast.subscribe(subscriber);
return () => this.broadcast.unsubscribe(unsubscribeId);
}
});
}
componentWillReceiveProps(nextProps) {
if (this.props.theme !== nextProps.theme) {
this.publish(nextProps.theme);
}
}
componentWillUnmount() {
if (this.unsubscribeToOuterId !== -1) {
this.context[CHANNEL_NEXT].unsubscribe(this.unsubscribeToOuterId);
}
} // Get the theme from the props, supporting both (outerTheme) => {} as well as object notation
getTheme(passedTheme) {
// (outerTheme: Theme) => void | Theme
const theme = passedTheme || this.props.theme;
if ((0, _exotic.isFunction)(theme)) {
const mergedTheme = theme(this.outerTheme);
if (process.env.NODE_ENV !== 'production' && !(0, _exotic.isPlainObject)(mergedTheme)) {
throw new Error(process.env.NODE_ENV !== 'production' ? '[ThemeProvider] Please return an object from your theme function, i.e. theme={() => ({})}!' : '');
}
return mergedTheme;
}
if (!(0, _exotic.isPlainObject)(theme)) {
throw new Error(process.env.NODE_ENV !== 'production' ? '[ThemeProvider] Please make your theme prop a plain object' : '');
} // (theme: Object)
return _objectSpread({}, this.outerTheme, theme);
}
publish(theme) {
// : Theme | ((outerTheme: Theme) => void)
this.broadcast.publish(this.getTheme(theme));
}
render() {
if (!this.props.children) {
return null;
}
return _react.default.Children.only(this.props.children);
}
};
ThemeProvider.childContextTypes = {
// legacy
[CHANNEL]: _propTypes.default.func,
[CHANNEL_NEXT]: CONTEXT_CHANNEL_SHAPE
};
ThemeProvider.contextTypes = {
[CHANNEL_NEXT]: CONTEXT_CHANNEL_SHAPE
};
var _default = ThemeProvider;
exports.default = _default;