react-css-themr
Advanced tools
Comparing version 1.2.0 to 1.3.0
@@ -11,2 +11,4 @@ 'use strict'; | ||
exports.themeable = themeable; | ||
var _react = require('react'); | ||
@@ -22,8 +24,6 @@ | ||
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; } | ||
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; } | ||
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 _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; } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
@@ -44,2 +44,4 @@ | ||
var THEMR_CONFIG = typeof Symbol !== 'undefined' ? Symbol('THEMR_CONFIG') : '__REACT_CSS_THEMR_CONFIG__'; | ||
exports.default = function (componentName, localTheme) { | ||
@@ -56,3 +58,15 @@ var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; | ||
validateComposeOption(optionComposeTheme); | ||
return _temp = _class = function (_Component) { | ||
var config = ThemedComponent[THEMR_CONFIG]; | ||
if (config && config.componentName === componentName) { | ||
config.localTheme = themeable(config.localTheme, localTheme); | ||
return ThemedComponent; | ||
} | ||
config = { | ||
componentName: componentName, | ||
localTheme: localTheme | ||
}; | ||
var Themed = (_temp = _class = function (_Component) { | ||
_inherits(Themed, _Component); | ||
@@ -74,6 +88,22 @@ | ||
}, { | ||
key: 'getNamespacedTheme', | ||
value: function getNamespacedTheme() { | ||
var _props = this.props; | ||
var themeNamespace = _props.themeNamespace; | ||
var theme = _props.theme; | ||
if (!themeNamespace) return theme; | ||
if (themeNamespace && !theme) throw new Error('Invalid themeNamespace use in react-css-themr. ' + 'themeNamespace prop should be used only with theme prop.'); | ||
return Object.keys(theme).filter(function (key) { | ||
return key.startsWith(themeNamespace); | ||
}).reduce(function (result, key) { | ||
return _extends({}, result, _defineProperty({}, removeNamespace(key, themeNamespace), theme[key])); | ||
}, {}); | ||
} | ||
}, { | ||
key: 'getThemeNotComposed', | ||
value: function getThemeNotComposed() { | ||
if (this.props.theme) return this.props.theme; | ||
if (localTheme) return localTheme; | ||
if (this.props.theme) return this.getNamespacedTheme(); | ||
if (config.localTheme) return config.localTheme; | ||
return this.getContextTheme(); | ||
@@ -84,3 +114,3 @@ } | ||
value: function getContextTheme() { | ||
return this.context.themr ? this.context.themr.theme[componentName] : {}; | ||
return this.context.themr ? this.context.themr.theme[config.componentName] : {}; | ||
} | ||
@@ -90,3 +120,3 @@ }, { | ||
value: function getTheme() { | ||
return this.props.composeTheme === COMPOSE_SOFTLY ? Object.assign({}, this.getContextTheme(), localTheme, this.props.theme) : themeable(themeable(this.getContextTheme(), localTheme), this.props.theme); | ||
return this.props.composeTheme === COMPOSE_SOFTLY ? _extends({}, this.getContextTheme(), config.localTheme, this.getNamespacedTheme()) : themeable(themeable(this.getContextTheme(), config.localTheme), this.getNamespacedTheme()); | ||
} | ||
@@ -96,6 +126,6 @@ }, { | ||
value: function render() { | ||
var _props = this.props; | ||
var composeTheme = _props.composeTheme; | ||
var _props2 = this.props; | ||
var composeTheme = _props2.composeTheme; | ||
var rest = _objectWithoutProperties(_props, ['composeTheme']); | ||
var rest = _objectWithoutProperties(_props2, ['composeTheme']); | ||
@@ -122,8 +152,14 @@ var renderedElement = void 0; | ||
themr: _react.PropTypes.object | ||
}, _class.propTypes = { | ||
}, _class.propTypes = _extends({}, ThemedComponent.propTypes, { | ||
composeTheme: _react.PropTypes.oneOf([COMPOSE_DEEPLY, COMPOSE_SOFTLY, DONT_COMPOSE]), | ||
theme: _react.PropTypes.object | ||
}, _class.defaultProps = { | ||
theme: _react.PropTypes.object, | ||
themeNamespace: _react.PropTypes.string | ||
}), _class.defaultProps = _extends({}, ThemedComponent.defaultProps, { | ||
composeTheme: optionComposeTheme | ||
}, _temp; | ||
}), _temp); | ||
Themed[THEMR_CONFIG] = config; | ||
return Themed; | ||
}; | ||
@@ -137,5 +173,5 @@ }; | ||
if (!theme) return style; | ||
return [].concat(_toConsumableArray(Object.keys(theme)), _toConsumableArray(Object.keys(style))).reduce(function (result, key) { | ||
return typeof theme[key] === 'string' && style[key] && theme[key].indexOf(style[key]) === -1 ? _extends({}, result, _defineProperty({}, key, style[key] + ' ' + theme[key])) : _extends({}, result, _defineProperty({}, key, theme[key] || style[key])); | ||
}, {}); | ||
return Object.keys(theme).reduce(function (result, key) { | ||
return _extends({}, result, _defineProperty({}, key, style[key] ? style[key] + ' ' + theme[key] : theme[key])); | ||
}, style); | ||
} | ||
@@ -147,2 +183,7 @@ | ||
} | ||
} | ||
function removeNamespace(key, themeNamespace) { | ||
var capitalized = key.substr(themeNamespace.length); | ||
return capitalized.slice(0, 1).toLowerCase() + capitalized.slice(1); | ||
} |
@@ -24,3 +24,9 @@ 'use strict'; | ||
}); | ||
Object.defineProperty(exports, 'themeable', { | ||
enumerable: true, | ||
get: function get() { | ||
return _themr.themeable; | ||
} | ||
}); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } |
@@ -5,3 +5,3 @@ { | ||
"homepage": "https://github.com/javivelasco/react-css-themr#readme", | ||
"version": "1.2.0", | ||
"version": "1.3.0", | ||
"main": "./lib", | ||
@@ -8,0 +8,0 @@ "author": { |
@@ -13,6 +13,22 @@ import React, { Component, PropTypes } from 'react' | ||
const THEMR_CONFIG = typeof Symbol !== 'undefined' ? | ||
Symbol('THEMR_CONFIG') : | ||
'__REACT_CSS_THEMR_CONFIG__' | ||
export default (componentName, localTheme, options = {}) => (ThemedComponent) => { | ||
const { composeTheme: optionComposeTheme, withRef: optionWithRef } = { ...DEFAULT_OPTIONS, ...options } | ||
validateComposeOption(optionComposeTheme) | ||
return class Themed extends Component { | ||
let config = ThemedComponent[THEMR_CONFIG] | ||
if (config && config.componentName === componentName) { | ||
config.localTheme = themeable(config.localTheme, localTheme) | ||
return ThemedComponent | ||
} | ||
config = { | ||
componentName, | ||
localTheme | ||
} | ||
class Themed extends Component { | ||
static displayName = `Themed ${ThemedComponent.name}`; | ||
@@ -25,7 +41,10 @@ | ||
static propTypes = { | ||
...ThemedComponent.propTypes, | ||
composeTheme: PropTypes.oneOf([ COMPOSE_DEEPLY, COMPOSE_SOFTLY, DONT_COMPOSE ]), | ||
theme: PropTypes.object | ||
theme: PropTypes.object, | ||
themeNamespace: PropTypes.string | ||
} | ||
static defaultProps = { | ||
...ThemedComponent.defaultProps, | ||
composeTheme: optionComposeTheme | ||
@@ -43,5 +62,16 @@ } | ||
getNamespacedTheme() { | ||
const { themeNamespace, theme } = this.props | ||
if (!themeNamespace) return theme | ||
if (themeNamespace && !theme) throw new Error('Invalid themeNamespace use in react-css-themr. ' + | ||
'themeNamespace prop should be used only with theme prop.') | ||
return Object.keys(theme) | ||
.filter(key => key.startsWith(themeNamespace)) | ||
.reduce((result, key) => ({ ...result, [removeNamespace(key, themeNamespace)]: theme[key] }), {}) | ||
} | ||
getThemeNotComposed() { | ||
if (this.props.theme) return this.props.theme | ||
if (localTheme) return localTheme | ||
if (this.props.theme) return this.getNamespacedTheme() | ||
if (config.localTheme) return config.localTheme | ||
return this.getContextTheme() | ||
@@ -52,3 +82,3 @@ } | ||
return this.context.themr | ||
? this.context.themr.theme[componentName] | ||
? this.context.themr.theme[config.componentName] | ||
: {} | ||
@@ -59,4 +89,4 @@ } | ||
return this.props.composeTheme === COMPOSE_SOFTLY | ||
? Object.assign({}, this.getContextTheme(), localTheme, this.props.theme) | ||
: themeable(themeable(this.getContextTheme(), localTheme), this.props.theme) | ||
? { ...this.getContextTheme(), ...config.localTheme, ...this.getNamespacedTheme() } | ||
: themeable(themeable(this.getContextTheme(), config.localTheme), this.getNamespacedTheme()) | ||
} | ||
@@ -88,11 +118,13 @@ | ||
} | ||
Themed[THEMR_CONFIG] = config | ||
return Themed | ||
} | ||
function themeable(style = {}, theme) { | ||
export function themeable(style = {}, theme) { | ||
if (!theme) return style | ||
return [ ...Object.keys(theme), ...Object.keys(style) ].reduce((result, key) => ( | ||
typeof theme[key] === 'string' && style[key] && theme[key].indexOf(style[key]) === -1 | ||
? { ...result, [key]: `${style[key]} ${theme[key]}` } | ||
: { ...result, [key]: theme[key] || style[key] } | ||
), {}) | ||
return Object.keys(theme).reduce((result, key) => ({ | ||
...result, [key]: style[key] ? `${style[key]} ${theme[key]}` : theme[key] | ||
}), style) | ||
} | ||
@@ -109,1 +141,6 @@ | ||
} | ||
function removeNamespace(key, themeNamespace) { | ||
const capitalized = key.substr(themeNamespace.length) | ||
return capitalized.slice(0, 1).toLowerCase() + capitalized.slice(1) | ||
} |
export { default as ThemeProvider } from './components/ThemeProvider' | ||
export { default as themr } from './components/themr' | ||
export { themeable } from './components/themr' |
28020
359