nuke-theme-provider
Version:
主题换肤
259 lines (223 loc) • 10.1 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
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 _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 _rax = require('rax');
var _hoistNonReactStatics = require('hoist-non-react-statics');
var _hoistNonReactStatics2 = _interopRequireDefault(_hoistNonReactStatics);
var _theme = require('./theme');
var _theme2 = _interopRequireDefault(_theme);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
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; } /** @jsx createElement */
// import pickby from 'lodash.pickby';
// function throwConnectStyleError(errorMessage, componentDisplayName) {
// throw Error(
// `${errorMessage} - when connecting ${componentDisplayName} component to style.`
// );
// }
// 处理 componentStyle 有多层的情况,例如:
// componentStyle: {
// Card : {
// normal:{
// width:100,
// height:100
// },
// footer:{
// flex:1
// }
// } ,
// [Card.Item]:{
// wrap:{
// backgroundColor:'#cccccc'
// }
// },
// [Card.Item.Button]:{
// primary:{
// backgroundColor:'#cccccc'
// }
// }
// }
var cacheStatic = void 0;
function getTheme(context) {
if (context.theme) {
cacheStatic = context.theme;
}
// Fallback to a default theme if the component isn't
// rendered in a StyleProvider.
// return Theme.get(namespace) || Theme.getDefaultTheme();
// var a = Theme.get();
return context.theme || cacheStatic || _theme2.default.getDefaultTheme();
}
/**
* 过滤,传递需要的样式到子节点
* @param {[object]} componentStyle [样式]
* @param {[string]} componentDisplayName [组件名]
* @param {[array]} parentPath [父级路径]
* @return {[type]} [description]
*/
// function injectToChildFilter(
// componentStyle,
// componentDisplayName,
// parentPath = []
// ) {
// return pickby(componentStyle, (value, key) => {
// let nextPath = [...parentPath];
// nextPath.push(componentDisplayName);
// let maxCurrentStyleKey = nextPath.join('.');
// //当前 keyPath 是否是currentPath 的子路径, 例如 keyPath : Cart.Item.Button, currentPath: Cart.Item, return true
// return (
// key.indexOf(maxCurrentStyleKey) === 0 && key.length > maxCurrentStyleKey
// );
// });
// }
/**
* add display name property in each componeent to prevent being aliasd.
*/
exports.default = function () {
var componentStyleProvider = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
function getComponentDisplayName(WrappedComponent) {
return WrappedComponent.displayName || WrappedComponent.name || 'Component';
}
return function wrapWithStyledComponent(WrappedComponent) {
var _class, _temp;
var componentDisplayName = getComponentDisplayName(WrappedComponent);
var StyledComponent = (_temp = _class = function (_Component) {
_inherits(StyledComponent, _Component);
function StyledComponent(props, context) {
_classCallCheck(this, StyledComponent);
var _this = _possibleConstructorReturn(this, (StyledComponent.__proto__ || Object.getPrototypeOf(StyledComponent)).call(this, props, context));
var style = props.style;
var theme = getTheme(context);
_this.displayName = componentDisplayName;
var componentStyle = componentStyleProvider(theme.themeStyle);
_this.setWrappedInstance = _this.setWrappedInstance.bind(_this);
var finalStyle = _this.getFinalStyle(componentStyle, context, style);
_this.state = {
style: finalStyle,
componentStyle: componentStyle,
addedProps: _this.resolveAddedProps()
};
return _this;
}
_createClass(StyledComponent, [{
key: 'getChildContext',
value: function getChildContext() {
return {
// parentStyle: injectToChildFilter(
// this.state.componentStyle,
// this.displayName,
// this.currentPath
// ),
namespace: this.getNamespace(),
// this.context.parentStyle :
// this.state.childrenStyle,
// resolveStyle: this.resolveConnectedComponentStyle,
parentPath: this.getParentPath()
};
}
}, {
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps, nextContext) {
var theme = getTheme(nextContext);
var componentStyle = componentStyleProvider(theme.themeStyle);
var style = nextProps.style;
var finalStyle = this.getFinalStyle(componentStyle, nextContext, style);
this.setState({
style: finalStyle
});
}
// getStyleFromKlsName(klassName) {
// // console.log(klassName);
// }
}, {
key: 'getFinalStyle',
value: function getFinalStyle(componentStyle, context, style) {
var currentPath = context.parentPath ? [].concat(_toConsumableArray(context.parentPath)) : [];
currentPath.push(this.displayName);
var stylesObject = {};
for (var i = 0; i < currentPath.length; i++) {
var key = currentPath.slice(currentPath.length - 1 - i).join('.');
if (componentStyle[key]) {
stylesObject = _extends({}, stylesObject, componentStyle[key]);
}
}
return _extends({}, stylesObject, style);
}
}, {
key: 'getParentPath',
value: function getParentPath() {
if (!this.context.parentPath) {
return [this.displayName];
}
return [].concat(_toConsumableArray(this.context.parentPath), [this.displayName]);
}
}, {
key: 'getNamespace',
value: function getNamespace() {
return this.context.namespace || 'Nuke';
}
}, {
key: 'setNativeProps',
value: function setNativeProps(nativeProps) {
if (this.wrappedInstance.setNativeProps) {
this.wrappedInstance.setNativeProps(nativeProps);
}
}
}, {
key: 'setWrappedInstance',
value: function setWrappedInstance(component) {
var _this2 = this;
if (component && component._root) {
this._root = component._root;
} else {
this._root = component;
}
this.wrappedInstance = this._root;
this.wrappedInstance && Object.keys(this.wrappedInstance).forEach(function (attr) {
if (!_this2[attr]) {
_this2[attr] = _this2.wrappedInstance[attr];
}
});
}
}, {
key: 'resolveAddedProps',
value: function resolveAddedProps() {
var addedProps = {};
if (options.withRef) {
addedProps.ref = 'wrappedInstance';
}
return addedProps;
}
}, {
key: 'render',
value: function render() {
var _state = this.state,
addedProps = _state.addedProps,
style = _state.style;
return (0, _rax.createElement)(WrappedComponent, _extends({}, this.props, addedProps, { themeStyle: style, ref: this.setWrappedInstance }));
}
}]);
return StyledComponent;
}(_rax.Component), _class.contextTypes = {
theme: _rax.PropTypes.object,
parentPath: _rax.PropTypes.array,
namespace: _rax.PropTypes.string
}, _class.childContextTypes = {
parentPath: _rax.PropTypes.array,
parentStyle: _rax.PropTypes.object,
namespace: _rax.PropTypes.string
}, _class.propTypes = {
// Element style that overrides any other style of the component
style: _rax.PropTypes.object
}, _class.WrappedComponent = WrappedComponent, _temp);
// return StyledComponent;
return (0, _hoistNonReactStatics2.default)(StyledComponent, WrappedComponent);
};
};
module.exports = exports['default'];
;