UNPKG

10.6 kBJavaScriptView Raw
1Object.defineProperty(exports, "__esModule", {
2 value: true
3});
4exports.withStylesPropTypes = exports.css = undefined;
5
6var _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; };
7
8var _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; }; }();
9
10exports.withStyles = withStyles;
11
12var _react = require('react');
13
14var _react2 = _interopRequireDefault(_react);
15
16var _propTypes = require('prop-types');
17
18var _propTypes2 = _interopRequireDefault(_propTypes);
19
20var _hoistNonReactStatics = require('hoist-non-react-statics');
21
22var _hoistNonReactStatics2 = _interopRequireDefault(_hoistNonReactStatics);
23
24var _deepmerge = require('deepmerge');
25
26var _deepmerge2 = _interopRequireDefault(_deepmerge);
27
28var _constants = require('react-with-direction/dist/constants');
29
30var _brcast = require('react-with-direction/dist/proptypes/brcast');
31
32var _brcast2 = _interopRequireDefault(_brcast);
33
34var _ThemedStyleSheet = require('./ThemedStyleSheet');
35
36var _ThemedStyleSheet2 = _interopRequireDefault(_ThemedStyleSheet);
37
38function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
39
40function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
41
42function _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; }
43
44function _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; }
45
46function _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; }
47
48// Add some named exports to assist in upgrading and for convenience
49var css = exports.css = _ThemedStyleSheet2['default'].resolveLTR;
50var withStylesPropTypes = exports.withStylesPropTypes = {
51 styles: _propTypes2['default'].object.isRequired, // eslint-disable-line react/forbid-prop-types
52 theme: _propTypes2['default'].object.isRequired, // eslint-disable-line react/forbid-prop-types
53 css: _propTypes2['default'].func.isRequired
54};
55
56var EMPTY_STYLES = {};
57var EMPTY_STYLES_FN = function EMPTY_STYLES_FN() {
58 return EMPTY_STYLES;
59};
60
61function baseClass(pureComponent) {
62 if (pureComponent) {
63 if (!_react2['default'].PureComponent) {
64 throw new ReferenceError('withStyles() pureComponent option requires React 15.3.0 or later');
65 }
66
67 return _react2['default'].PureComponent;
68 }
69
70 return _react2['default'].Component;
71}
72
73var contextTypes = _defineProperty({}, _constants.CHANNEL, _brcast2['default']);
74
75var defaultDirection = _constants.DIRECTIONS.LTR;
76
77function withStyles(styleFn) {
78 var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
79 _ref$stylesPropName = _ref.stylesPropName,
80 stylesPropName = _ref$stylesPropName === undefined ? 'styles' : _ref$stylesPropName,
81 _ref$themePropName = _ref.themePropName,
82 themePropName = _ref$themePropName === undefined ? 'theme' : _ref$themePropName,
83 _ref$cssPropName = _ref.cssPropName,
84 cssPropName = _ref$cssPropName === undefined ? 'css' : _ref$cssPropName,
85 _ref$flushBefore = _ref.flushBefore,
86 flushBefore = _ref$flushBefore === undefined ? false : _ref$flushBefore,
87 _ref$pureComponent = _ref.pureComponent,
88 pureComponent = _ref$pureComponent === undefined ? false : _ref$pureComponent;
89
90 var styleDefLTR = void 0;
91 var styleDefRTL = void 0;
92 var currentThemeLTR = void 0;
93 var currentThemeRTL = void 0;
94 var BaseClass = baseClass(pureComponent);
95
96 function getResolveMethod(direction) {
97 return direction === _constants.DIRECTIONS.LTR ? _ThemedStyleSheet2['default'].resolveLTR : _ThemedStyleSheet2['default'].resolveRTL;
98 }
99
100 function getCurrentTheme(direction) {
101 return direction === _constants.DIRECTIONS.LTR ? currentThemeLTR : currentThemeRTL;
102 }
103
104 function getStyleDef(direction, wrappedComponentName) {
105 var currentTheme = getCurrentTheme(direction);
106 var styleDef = direction === _constants.DIRECTIONS.LTR ? styleDefLTR : styleDefRTL;
107
108 var registeredTheme = _ThemedStyleSheet2['default'].get();
109
110 // Return the existing styles if they've already been defined
111 // and if the theme used to create them corresponds to the theme
112 // registered with ThemedStyleSheet
113 if (styleDef && currentTheme === registeredTheme) {
114 return styleDef;
115 }
116
117 if (process.env.NODE_ENV !== 'production' && typeof performance !== 'undefined' && performance.mark !== undefined) {
118 performance.mark('react-with-styles.createStyles.start');
119 }
120
121 var isRTL = direction === _constants.DIRECTIONS.RTL;
122
123 if (isRTL) {
124 styleDefRTL = styleFn ? _ThemedStyleSheet2['default'].createRTL(styleFn) : EMPTY_STYLES_FN;
125
126 currentThemeRTL = registeredTheme;
127 styleDef = styleDefRTL;
128 } else {
129 styleDefLTR = styleFn ? _ThemedStyleSheet2['default'].createLTR(styleFn) : EMPTY_STYLES_FN;
130
131 currentThemeLTR = registeredTheme;
132 styleDef = styleDefLTR;
133 }
134
135 if (process.env.NODE_ENV !== 'production' && typeof performance !== 'undefined' && performance.mark !== undefined) {
136 performance.mark('react-with-styles.createStyles.end');
137
138 performance.measure('\uD83D\uDC69\u200D\uD83C\uDFA8 withStyles(' + String(wrappedComponentName) + ') [create styles]', 'react-with-styles.createStyles.start', 'react-with-styles.createStyles.end');
139 }
140
141 return styleDef;
142 }
143
144 function getState(direction, wrappedComponentName) {
145 return {
146 resolveMethod: getResolveMethod(direction),
147 styleDef: getStyleDef(direction, wrappedComponentName)
148 };
149 }
150
151 return function () {
152 function withStylesHOC(WrappedComponent) {
153 var wrappedComponentName = WrappedComponent.displayName || WrappedComponent.name || 'Component';
154
155 // NOTE: Use a class here so components are ref-able if need be:
156 // eslint-disable-next-line react/prefer-stateless-function
157
158 var WithStyles = function (_BaseClass) {
159 _inherits(WithStyles, _BaseClass);
160
161 function WithStyles(props, context) {
162 _classCallCheck(this, WithStyles);
163
164 var _this = _possibleConstructorReturn(this, (WithStyles.__proto__ || Object.getPrototypeOf(WithStyles)).call(this, props, context));
165
166 var direction = _this.context[_constants.CHANNEL] ? _this.context[_constants.CHANNEL].getState() : defaultDirection;
167
168 _this.state = getState(direction, wrappedComponentName);
169 return _this;
170 }
171
172 _createClass(WithStyles, [{
173 key: 'componentDidMount',
174 value: function () {
175 function componentDidMount() {
176 var _this2 = this;
177
178 if (this.context[_constants.CHANNEL]) {
179 // subscribe to future direction changes
180 this.channelUnsubscribe = this.context[_constants.CHANNEL].subscribe(function (direction) {
181 _this2.setState(getState(direction, wrappedComponentName));
182 });
183 }
184 }
185
186 return componentDidMount;
187 }()
188 }, {
189 key: 'componentWillUnmount',
190 value: function () {
191 function componentWillUnmount() {
192 if (this.channelUnsubscribe) {
193 this.channelUnsubscribe();
194 }
195 }
196
197 return componentWillUnmount;
198 }()
199 }, {
200 key: 'render',
201 value: function () {
202 function render() {
203 var _ref2;
204
205 // As some components will depend on previous styles in
206 // the component tree, we provide the option of flushing the
207 // buffered styles (i.e. to a style tag) **before** the rendering
208 // cycle begins.
209 //
210 // The interfaces provide the optional "flush" method which
211 // is run in turn by ThemedStyleSheet.flush.
212 if (flushBefore) {
213 _ThemedStyleSheet2['default'].flush();
214 }
215
216 var _state = this.state,
217 resolveMethod = _state.resolveMethod,
218 styleDef = _state.styleDef;
219
220
221 return _react2['default'].createElement(WrappedComponent, _extends({}, this.props, (_ref2 = {}, _defineProperty(_ref2, themePropName, _ThemedStyleSheet2['default'].get()), _defineProperty(_ref2, stylesPropName, styleDef()), _defineProperty(_ref2, cssPropName, resolveMethod), _ref2)));
222 }
223
224 return render;
225 }()
226 }]);
227
228 return WithStyles;
229 }(BaseClass);
230
231 WithStyles.WrappedComponent = WrappedComponent;
232 WithStyles.displayName = 'withStyles(' + String(wrappedComponentName) + ')';
233 WithStyles.contextTypes = contextTypes;
234 if (WrappedComponent.propTypes) {
235 WithStyles.propTypes = (0, _deepmerge2['default'])({}, WrappedComponent.propTypes);
236 delete WithStyles.propTypes[stylesPropName];
237 delete WithStyles.propTypes[themePropName];
238 delete WithStyles.propTypes[cssPropName];
239 }
240 if (WrappedComponent.defaultProps) {
241 WithStyles.defaultProps = (0, _deepmerge2['default'])({}, WrappedComponent.defaultProps);
242 }
243
244 return (0, _hoistNonReactStatics2['default'])(WithStyles, WrappedComponent);
245 }
246
247 return withStylesHOC;
248 }();
249}
\No newline at end of file