330 lines
12 KiB
JavaScript
330 lines
12 KiB
JavaScript
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
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; };
|
|
|
|
var _react = require('react');
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _propTypes = require('prop-types');
|
|
|
|
var _propTypes2 = _interopRequireDefault(_propTypes);
|
|
|
|
var _theming = require('theming');
|
|
|
|
var _theming2 = _interopRequireDefault(_theming);
|
|
|
|
var _jss = require('./jss');
|
|
|
|
var _jss2 = _interopRequireDefault(_jss);
|
|
|
|
var _compose = require('./compose');
|
|
|
|
var _compose2 = _interopRequireDefault(_compose);
|
|
|
|
var _getDisplayName = require('./getDisplayName');
|
|
|
|
var _getDisplayName2 = _interopRequireDefault(_getDisplayName);
|
|
|
|
var _ns = require('./ns');
|
|
|
|
var ns = _interopRequireWildcard(_ns);
|
|
|
|
var _contextTypes = require('./contextTypes');
|
|
|
|
var _contextTypes2 = _interopRequireDefault(_contextTypes);
|
|
|
|
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)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
|
|
|
|
var env = process.env.NODE_ENV;
|
|
|
|
// Like a Symbol
|
|
var dynamicStylesNs = Math.random();
|
|
|
|
/*
|
|
* # Use cases
|
|
*
|
|
* - Unthemed component accepts styles object
|
|
* - Themed component accepts styles creator function which takes theme as a single argument
|
|
* - Multiple instances will re-use the same static sheet via sheets manager
|
|
* - Sheet manager identifies static sheets by theme as a key
|
|
* - For unthemed components theme is an empty object
|
|
* - The very first instance will add static sheet to sheets manager
|
|
* - Every further instances will get that static sheet from sheet manager
|
|
* - Every mount of every instance will call method `sheetsManager.manage`,
|
|
* thus incrementing reference counter.
|
|
* - Every unmount of every instance will call method `sheetsManager.unmanage`,
|
|
* thus decrementing reference counter.
|
|
* - `sheetsManager.unmanage` under the hood will detach static sheet once reference
|
|
* counter is zero.
|
|
* - Dynamic styles are not shared between instances
|
|
*
|
|
*/
|
|
|
|
var getStyles = function getStyles(stylesOrCreator, theme) {
|
|
if (typeof stylesOrCreator !== 'function') {
|
|
return stylesOrCreator;
|
|
}
|
|
return stylesOrCreator(theme);
|
|
};
|
|
|
|
// Returns an object with array property as a key and true as a value.
|
|
var toMap = function toMap(arr) {
|
|
return arr.reduce(function (map, prop) {
|
|
map[prop] = true;
|
|
return map;
|
|
}, {});
|
|
};
|
|
|
|
var defaultInjectProps = {
|
|
sheet: false,
|
|
classes: true,
|
|
theme: true
|
|
};
|
|
|
|
var managersCounter = 0;
|
|
|
|
/**
|
|
* Wrap a Component into a JSS Container Component.
|
|
*
|
|
* @param {Object|Function} stylesOrCreator
|
|
* @param {Component} InnerComponent
|
|
* @param {Object} [options]
|
|
* @return {Component}
|
|
*/
|
|
|
|
exports['default'] = function (stylesOrCreator, InnerComponent) {
|
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
|
|
var isThemingEnabled = typeof stylesOrCreator === 'function';
|
|
|
|
var _options$theming = options.theming,
|
|
theming = _options$theming === undefined ? _theming2['default'] : _options$theming,
|
|
inject = options.inject,
|
|
optionsJss = options.jss,
|
|
sheetOptions = _objectWithoutProperties(options, ['theming', 'inject', 'jss']);
|
|
|
|
var injectMap = inject ? toMap(inject) : defaultInjectProps;
|
|
var themeListener = theming.themeListener;
|
|
|
|
var displayName = (0, _getDisplayName2['default'])(InnerComponent);
|
|
var defaultClassNamePrefix = env === 'production' ? undefined : displayName + '-';
|
|
var noTheme = {};
|
|
var managerId = managersCounter++;
|
|
var manager = new _jss.SheetsManager();
|
|
var defaultProps = _extends({}, InnerComponent.defaultProps);
|
|
delete defaultProps.classes;
|
|
|
|
var Jss = function (_Component) {
|
|
_inherits(Jss, _Component);
|
|
|
|
function Jss(props, context) {
|
|
_classCallCheck(this, Jss);
|
|
|
|
var _this = _possibleConstructorReturn(this, (Jss.__proto__ || Object.getPrototypeOf(Jss)).call(this, props, context));
|
|
|
|
_initialiseProps.call(_this);
|
|
|
|
var theme = isThemingEnabled ? themeListener.initial(context) : noTheme;
|
|
|
|
_this.state = _this.createState({ theme: theme }, props);
|
|
return _this;
|
|
}
|
|
|
|
_createClass(Jss, [{
|
|
key: 'componentWillMount',
|
|
value: function componentWillMount() {
|
|
this.manage(this.state);
|
|
}
|
|
}, {
|
|
key: 'componentDidMount',
|
|
value: function componentDidMount() {
|
|
if (isThemingEnabled) {
|
|
this.unsubscribeId = themeListener.subscribe(this.context, this.setTheme);
|
|
}
|
|
}
|
|
}, {
|
|
key: 'componentWillReceiveProps',
|
|
value: function componentWillReceiveProps(nextProps, nextContext) {
|
|
this.context = nextContext;
|
|
var dynamicSheet = this.state.dynamicSheet;
|
|
|
|
if (dynamicSheet) dynamicSheet.update(nextProps);
|
|
}
|
|
}, {
|
|
key: 'componentWillUpdate',
|
|
value: function componentWillUpdate(nextProps, nextState) {
|
|
if (isThemingEnabled && this.state.theme !== nextState.theme) {
|
|
var newState = this.createState(nextState, nextProps);
|
|
this.manage(newState);
|
|
this.manager.unmanage(this.state.theme);
|
|
this.setState(newState);
|
|
}
|
|
}
|
|
}, {
|
|
key: 'componentDidUpdate',
|
|
value: function componentDidUpdate(prevProps, prevState) {
|
|
// We remove previous dynamicSheet only after new one was created to avoid FOUC.
|
|
if (prevState.dynamicSheet !== this.state.dynamicSheet) {
|
|
this.jss.removeStyleSheet(prevState.dynamicSheet);
|
|
}
|
|
}
|
|
}, {
|
|
key: 'componentWillUnmount',
|
|
value: function componentWillUnmount() {
|
|
if (this.unsubscribeId) {
|
|
themeListener.unsubscribe(this.context, this.unsubscribeId);
|
|
}
|
|
|
|
this.manager.unmanage(this.state.theme);
|
|
if (this.state.dynamicSheet) {
|
|
this.state.dynamicSheet.detach();
|
|
}
|
|
}
|
|
}, {
|
|
key: 'createState',
|
|
value: function createState(_ref, _ref2) {
|
|
var theme = _ref.theme,
|
|
dynamicSheet = _ref.dynamicSheet;
|
|
var userClasses = _ref2.classes;
|
|
|
|
var contextSheetOptions = this.context[ns.sheetOptions];
|
|
if (contextSheetOptions && contextSheetOptions.disableStylesGeneration) {
|
|
return { theme: theme, dynamicSheet: dynamicSheet, classes: {} };
|
|
}
|
|
|
|
var classNamePrefix = defaultClassNamePrefix;
|
|
var staticSheet = this.manager.get(theme);
|
|
|
|
if (contextSheetOptions && contextSheetOptions.classNamePrefix) {
|
|
classNamePrefix = contextSheetOptions.classNamePrefix + classNamePrefix;
|
|
}
|
|
|
|
if (!staticSheet) {
|
|
var styles = getStyles(stylesOrCreator, theme);
|
|
staticSheet = this.jss.createStyleSheet(styles, _extends({}, sheetOptions, contextSheetOptions, {
|
|
meta: displayName + ', ' + (isThemingEnabled ? 'Themed' : 'Unthemed') + ', Static',
|
|
classNamePrefix: classNamePrefix
|
|
}));
|
|
this.manager.add(theme, staticSheet);
|
|
staticSheet[dynamicStylesNs] = (0, _jss.getDynamicStyles)(styles);
|
|
}
|
|
|
|
var dynamicStyles = staticSheet[dynamicStylesNs];
|
|
|
|
if (dynamicStyles) {
|
|
dynamicSheet = this.jss.createStyleSheet(dynamicStyles, _extends({}, sheetOptions, contextSheetOptions, {
|
|
meta: displayName + ', ' + (isThemingEnabled ? 'Themed' : 'Unthemed') + ', Dynamic',
|
|
classNamePrefix: classNamePrefix,
|
|
link: true
|
|
}));
|
|
}
|
|
|
|
var defaultClasses = InnerComponent.defaultProps ? InnerComponent.defaultProps.classes : {};
|
|
var jssClasses = dynamicSheet ? (0, _compose2['default'])(staticSheet.classes, dynamicSheet.classes) : staticSheet.classes;
|
|
var classes = _extends({}, defaultClasses, jssClasses, userClasses);
|
|
|
|
return { theme: theme, dynamicSheet: dynamicSheet, classes: classes };
|
|
}
|
|
}, {
|
|
key: 'manage',
|
|
value: function manage(_ref3) {
|
|
var theme = _ref3.theme,
|
|
dynamicSheet = _ref3.dynamicSheet;
|
|
|
|
var contextSheetOptions = this.context[ns.sheetOptions];
|
|
if (contextSheetOptions && contextSheetOptions.disableStylesGeneration) {
|
|
return;
|
|
}
|
|
var registry = this.context[ns.sheetsRegistry];
|
|
|
|
var staticSheet = this.manager.manage(theme);
|
|
if (registry) registry.add(staticSheet);
|
|
|
|
if (dynamicSheet) {
|
|
dynamicSheet.update(this.props).attach();
|
|
if (registry) registry.add(dynamicSheet);
|
|
}
|
|
}
|
|
}, {
|
|
key: 'render',
|
|
value: function render() {
|
|
var _state = this.state,
|
|
theme = _state.theme,
|
|
dynamicSheet = _state.dynamicSheet,
|
|
classes = _state.classes;
|
|
|
|
var _props = this.props,
|
|
innerRef = _props.innerRef,
|
|
props = _objectWithoutProperties(_props, ['innerRef']);
|
|
|
|
var sheet = dynamicSheet || this.manager.get(theme);
|
|
|
|
if (injectMap.sheet && !props.sheet) props.sheet = sheet;
|
|
if (isThemingEnabled && injectMap.theme && !props.theme) props.theme = theme;
|
|
|
|
// We have merged classes already.
|
|
if (injectMap.classes) props.classes = classes;
|
|
|
|
return _react2['default'].createElement(InnerComponent, _extends({ ref: innerRef }, props));
|
|
}
|
|
}, {
|
|
key: 'jss',
|
|
get: function get() {
|
|
return this.context[ns.jss] || optionsJss || _jss2['default'];
|
|
}
|
|
}, {
|
|
key: 'manager',
|
|
get: function get() {
|
|
var managers = this.context[ns.managers];
|
|
|
|
// If `managers` map is present in the context, we use it in order to
|
|
// let JssProvider reset them when new response has to render server-side.
|
|
if (managers) {
|
|
if (!managers[managerId]) {
|
|
managers[managerId] = new _jss.SheetsManager();
|
|
}
|
|
return managers[managerId];
|
|
}
|
|
|
|
return manager;
|
|
}
|
|
}]);
|
|
|
|
return Jss;
|
|
}(_react.Component);
|
|
|
|
Jss.displayName = 'Jss(' + displayName + ')';
|
|
Jss.InnerComponent = InnerComponent;
|
|
Jss.contextTypes = _extends({}, _contextTypes2['default'], isThemingEnabled && themeListener.contextTypes);
|
|
Jss.propTypes = {
|
|
innerRef: _propTypes2['default'].func
|
|
};
|
|
Jss.defaultProps = defaultProps;
|
|
|
|
var _initialiseProps = function _initialiseProps() {
|
|
var _this2 = this;
|
|
|
|
this.setTheme = function (theme) {
|
|
return _this2.setState({ theme: theme });
|
|
};
|
|
};
|
|
|
|
return Jss;
|
|
}; |