Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

aesthetic

Package Overview
Dependencies
Maintainers
1
Versions
81
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

aesthetic - npm Package Compare versions

Comparing version 1.7.1 to 2.0.0-0

esm/helpers/createStyleElement.js

52

CHANGELOG.md

@@ -0,1 +1,53 @@

# 2.0.0
Aesthetic has been rewritten to properly support specificity, new at-rules, and global styles.
Styles are no longer transformed on mount and will now be transformed on render using a new
stylesheet layer. Furthermore, unified syntax now supports most common at-rules, and a new
`@font-face` structure.
[View the migration guide!](../../MIGRATE_2.0.md)
#### 💥 Breaking
* Requires IE 11+.
* Requires `WeakMap` support.
* Removed React Native support (it was finicky and only supported by 1 adapter).
* Removed `aesthetic-utils` package (any remaining helpers were moved to core).
* Removed the `classes` function.
* Use the `transform` function provided by `createStyler` instead.
* Removed `ClassNamesPropType` and `ClassOrStylesPropType` prop types.
* Use the `StylesPropType` instead.
* Refactored `Aesthetic#transformStyles` and `Adapter#transform` to now require an array of style
declarations.
* Will now return a single combined class name for increased specificity.
* Refactored `createStyler` to return 2 functions, `style` and `transform`.
* The `style` function is an HOC factory and works like the original 1.0 return value.
* The `transform` function is now required to generate class names from style declarations.
* Renamed the HOC `wrappedComponent` static property to `WrappedComponent`.
* Renamed the HOC `theme` prop (to toggle themes) to `themeName`.
* Inherited and parent styles are no longer passed as the HOC styler callback 2nd argument.
* Unified Syntax
* The `@font-face` unified syntax rule has been rewritten to support multiple variations of the
same font family.
* The object key is now the font family name, instead of a random name.
* The object value can now be an array of font face style declarations.
* The `srcPaths` property, an array of paths, is now required (instead of `src`).
#### 🚀 New
* Added a new adapter, `TypeStyle`.
* Added `Aesthetic#createStyleSheet` for converting a component's styles into an adapter
specific stylesheet.
* The component's current props are passed as the 2nd argument to the HOC styler callback.
* Inherited and parent styles are now automatically deep merged when extending.
* Added `Adapter#create` for creating and adapting stylesheets.
* Updated `Aesthetic#registerTheme` to use the new global styles system.
* The current theme declarations will be passed to styled components under the `theme` prop.
* The previous `theme` prop was renamed to `themeName`.
* The `Aesthetic` `themePropName` option now controls this new prop.
* Unified Syntax
* Added new `@charset`, `@global`, `@import`, `@namespace`, `@page`, `@supports`, and `@viewport`
at-rules (varies between adapters).
* Added a new property `local` for use within `@font-face` (the source `local()` value).
#### 🛠 Internal
* Rewritten Flowtype definitions.
# 1.7.1 - 11/10/17

@@ -2,0 +54,0 @@ #### 🛠 Internal

9

esm/Adapter.js

@@ -11,4 +11,2 @@ import _extends from 'babel-runtime/helpers/extends';

this.bypassNativeStyleSheet = false;
this.native = false;
this.options = {};

@@ -20,4 +18,9 @@

_createClass(Adapter, [{
key: 'create',
value: function create(styleSheet) {
return styleSheet;
}
}, {
key: 'transform',
value: function transform(styleName, declarations) {
value: function transform() {
throw new Error(this.constructor.name + ' must define the `transform` method.');

@@ -24,0 +27,0 @@ }

@@ -0,1 +1,2 @@

import _toConsumableArray from 'babel-runtime/helpers/toConsumableArray';
import _extends from 'babel-runtime/helpers/extends';

@@ -10,5 +11,7 @@ import _classCallCheck from 'babel-runtime/helpers/classCallCheck';

import { isObject } from 'aesthetic-utils';
import deepMerge from 'lodash.merge';
import isObject from './helpers/isObject';
import stripClassPrefix from './helpers/stripClassPrefix';
import Adapter from './Adapter';
import _withStyles from './style';

@@ -21,4 +24,3 @@ var Aesthetic = function () {

this.cache = {};
this.native = false;
this.cache = new WeakMap();
this.options = {

@@ -28,3 +30,3 @@ defaultTheme: '',

pure: false,
stylesPropName: 'classNames',
stylesPropName: 'styles',
themePropName: 'theme'

@@ -42,19 +44,12 @@ };

_createClass(Aesthetic, [{
key: 'extendTheme',
value: function extendTheme(parentThemeName, themeName) {
var theme = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var globals = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
return this.registerTheme(themeName, deepMerge({}, this.getTheme(parentThemeName), theme), globals);
}
}, {
key: 'getStyles',
value: function getStyles(styleName) {
key: 'createStyleSheet',
value: function createStyleSheet(styleName) {
var themeName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
var props = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var parentStyleName = this.parents[styleName];
var declarations = this.styles[styleName];
var styleSheet = this.styles[styleName];
if ("production" !== process.env.NODE_ENV) {
if (!declarations) {
if (!styleSheet) {
throw new Error('Styles do not exist for "' + styleName + '".');

@@ -64,9 +59,21 @@ }

if (typeof declarations !== 'function') {
return declarations;
if (typeof styleSheet === 'function') {
styleSheet = styleSheet(themeName ? this.getTheme(themeName) : {}, props);
}
return declarations(themeName ? this.getTheme(themeName) : {}, parentStyleName ? this.getStyles(parentStyleName, themeName) : {});
if (parentStyleName) {
styleSheet = deepMerge({}, this.createStyleSheet(parentStyleName, themeName, props), styleSheet);
}
return this.adapter.create(styleSheet);
}
}, {
key: 'extendTheme',
value: function extendTheme(parentThemeName, themeName) {
var theme = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var globals = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
return this.registerTheme(themeName, deepMerge({}, this.getTheme(parentThemeName), theme), globals);
}
}, {
key: 'getTheme',

@@ -110,4 +117,6 @@ value: function getTheme() {

this.adapter.transform(':root', globals);
var globalStyleSheet = this.adapter.create(globals);
this.transformStyles(Object.values(globalStyleSheet));
return this;

@@ -119,3 +128,2 @@ }

if (adapter instanceof Adapter || adapter && typeof adapter.transform === 'function') {
adapter.native = this.native;
this.adapter = adapter;

@@ -130,3 +138,3 @@ } else if ("production" !== process.env.NODE_ENV) {

key: 'setStyles',
value: function setStyles(styleName, declarations) {
value: function setStyles(styleName, styleSheet) {
var extendFrom = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';

@@ -137,3 +145,3 @@

throw new Error('Styles have already been set for "' + styleName + '".');
} else if (!isObject(declarations) && typeof declarations !== 'function') {
} else if (!isObject(styleSheet) && typeof styleSheet !== 'function') {
throw new TypeError('Styles defined for "' + styleName + '" must be an object or function.');

@@ -143,3 +151,3 @@ }

this.styles[styleName] = declarations;
this.styles[styleName] = styleSheet;

@@ -162,48 +170,42 @@ if (extendFrom) {

key: 'transformStyles',
value: function transformStyles(styleName, themeName) {
var _this = this;
var fallbackThemeName = themeName || this.options.defaultTheme || '';
var cacheKey = styleName + ':' + fallbackThemeName;
if (this.cache[cacheKey]) {
return this.cache[cacheKey];
value: function transformStyles(styles) {
if (this.cache.has(styles)) {
return this.cache.get(styles);
}
var declarations = this.getStyles(styleName, fallbackThemeName);
var toTransform = {};
var output = {};
var setCount = 0;
var classNames = [];
var toTransform = [];
Object.keys(declarations).forEach(function (setName) {
if (typeof declarations[setName] === 'string') {
output[setName] = _this.native ? {} : declarations[setName];
} else {
toTransform[setName] = declarations[setName];
setCount += 1;
styles.forEach(function (style) {
if (!style) {
return;
} else if (typeof style === 'string' || typeof style === 'number') {
classNames.push.apply(classNames, _toConsumableArray(String(style).split(' ').map(function (s) {
return stripClassPrefix(s).trim();
})));
} else if (isObject(style)) {
toTransform.push(style);
} else if ("production" !== process.env.NODE_ENV) {
throw new Error('Unsupported style type to transform.');
}
});
if (setCount > 0) {
var transformedOutput = this.adapter.transform(styleName, toTransform);
if (toTransform.length > 0) {
var _adapter;
Object.keys(transformedOutput).forEach(function (setName) {
output[setName] = _this.validateTransform(styleName, setName, transformedOutput[setName]);
});
classNames.push((_adapter = this.adapter).transform.apply(_adapter, toTransform));
}
this.cache[cacheKey] = output;
var className = classNames.join(' ').trim();
return output;
this.cache.set(styles, className);
return className;
}
}, {
key: 'validateTransform',
value: function validateTransform(styleName, setName, value) {
if ("production" !== process.env.NODE_ENV) {
if (typeof value !== 'string') {
throw new TypeError('`' + this.adapter.constructor.name + '` must return a mapping of CSS class names. ' + ('"' + styleName + '@' + setName + '" is not a valid string.'));
}
}
key: 'withStyles',
value: function withStyles(styleSheet) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return value;
return _withStyles(this, styleSheet, options);
}

@@ -210,0 +212,0 @@ }]);

@@ -32,14 +32,20 @@ import _classCallCheck from 'babel-runtime/helpers/classCallCheck';

key: 'transform',
value: function transform(styleName, declarations) {
var classNames = {};
value: function transform() {
var _this2 = this;
Object.keys(declarations).forEach(function (setName) {
if (typeof declarations[setName] === 'string') {
classNames[setName] = declarations[setName];
var classNames = [];
for (var _len2 = arguments.length, styles = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
styles[_key2] = arguments[_key2];
}
styles.forEach(function (style) {
if (style && typeof style === 'string') {
classNames.push(style);
} else if ("production" !== process.env.NODE_ENV) {
throw new TypeError('`ClassNameAdapter` expects valid CSS class names; ' + ('non-string provided for "' + setName + '".'));
throw new TypeError(_this2.constructor.name + ' expects valid CSS class names.');
}
});
return classNames;
return classNames.join(' ');
}

@@ -46,0 +52,0 @@ }]);

@@ -8,3 +8,2 @@ /**

import Aesthetic from './Aesthetic';
import style from './style';

@@ -18,8 +17,16 @@ export default function createStyler(aesthetic) {

return function styler() {
var defaultStyles = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return {
style: function style(styleSheet) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return style(aesthetic, defaultStyles, options);
return aesthetic.withStyles(styleSheet, options);
},
transform: function transform() {
for (var _len = arguments.length, styles = Array(_len), _key = 0; _key < _len; _key++) {
styles[_key] = arguments[_key];
}
return aesthetic.transformStyles(styles);
}
};
}
/**
* @copyright 2017, Miles Johnson
* @license https://opensource.org/licenses/MIT
*
*/

@@ -12,9 +13,6 @@

import createStyler from './createStyler';
import classes from './classes';
export var ClassNamesPropType = PropTypes.objectOf(PropTypes.string);
export var StylesPropType = PropTypes.objectOf(PropTypes.object);
export var ClassOrStylesPropType = PropTypes.oneOfType([PropTypes.objectOf(PropTypes.string), PropTypes.objectOf(PropTypes.object)]);
export { Adapter, ClassNameAdapter, ThemeProvider, createStyler, classes };
export { Adapter, ClassNameAdapter, ThemeProvider, createStyler };
export default Aesthetic;

@@ -21,3 +21,3 @@ import _extends from 'babel-runtime/helpers/extends';

export default function style(aesthetic) {
var styles = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var styleSheet = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};

@@ -54,3 +54,3 @@

aesthetic.setStyles(styleName, styles, extendFrom);
aesthetic.setStyles(styleName, styleSheet, extendFrom);

@@ -61,5 +61,15 @@ var StyledComponent = function (_ParentComponent) {

function StyledComponent() {
var _ref, _this$state;
var _temp, _this, _ret;
_classCallCheck(this, StyledComponent);
return _possibleConstructorReturn(this, (StyledComponent.__proto__ || Object.getPrototypeOf(StyledComponent)).apply(this, arguments));
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = StyledComponent.__proto__ || Object.getPrototypeOf(StyledComponent)).call.apply(_ref, [this].concat(args))), _this), _this.state = (_this$state = {
firstMount: true
}, _defineProperty(_this$state, stylesPropName, {}), _defineProperty(_this$state, 'themeName', ''), _defineProperty(_this$state, themePropName, {}), _this$state), _temp), _possibleConstructorReturn(_this, _ret);
}

@@ -70,3 +80,3 @@

value: function componentWillMount() {
this.transformStyles(this.getTheme(this.props));
this.transformStyles(this.props);
}

@@ -76,19 +86,21 @@ }, {

value: function componentWillReceiveProps(nextProps) {
var theme = this.getTheme(nextProps);
if (theme !== this.state[themePropName]) {
this.transformStyles(theme);
}
this.transformStyles(nextProps);
}
}, {
key: 'getTheme',
value: function getTheme(props) {
return props[themePropName] || this.context.themeName || aesthetic.options.defaultTheme || '';
key: 'getThemeName',
value: function getThemeName(props) {
return props.themeName || this.context.themeName || aesthetic.options.defaultTheme || '';
}
}, {
key: 'transformStyles',
value: function transformStyles(theme) {
var _setState;
value: function transformStyles(props) {
var themeName = this.getThemeName(props);
this.setState((_setState = {}, _defineProperty(_setState, stylesPropName, aesthetic.transformStyles(styleName, theme)), _defineProperty(_setState, themePropName, theme), _setState));
if (this.state.firstMount || themeName !== this.state.themeName) {
var _setState;
this.setState((_setState = {
firstMount: false
}, _defineProperty(_setState, stylesPropName, aesthetic.createStyleSheet(styleName, themeName, props)), _defineProperty(_setState, 'themeName', themeName), _defineProperty(_setState, themePropName, themeName ? aesthetic.getTheme(themeName) : {}), _setState));
}
}

@@ -102,3 +114,4 @@ }, {

key: 'extendStyles',
value: function extendStyles(customStyles) {
value: function extendStyles() {
var customStyleSheet = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var extendOptions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

@@ -112,3 +125,3 @@

return style(aesthetic, customStyles, _extends({}, options, extendOptions, {
return style(aesthetic, customStyleSheet, _extends({}, options, extendOptions, {
extendFrom: styleName

@@ -124,7 +137,12 @@ }))(Component);

StyledComponent.styleName = styleName;
StyledComponent.wrappedComponent = Component;
StyledComponent.propTypes = _defineProperty({}, themePropName, PropTypes.string);
StyledComponent.WrappedComponent = Component;
StyledComponent.contextTypes = {
themeName: PropTypes.string
};
StyledComponent.propTypes = {
themeName: PropTypes.string
};
StyledComponent.defaultProps = {
themeName: ''
};

@@ -131,0 +149,0 @@

@@ -11,8 +11,10 @@ import _toConsumableArray from 'babel-runtime/helpers/toConsumableArray';

import { isObject } from 'aesthetic-utils';
import formatFontFace from './helpers/formatFontFace';
import isObject from './helpers/isObject';
import toArray from './helpers/toArray';
export var LOCAL = 'local';
export var GLOBAL = 'global';
export var AT_RULES = ['@fallbacks', '@font-face', '@keyframes', '@media'];
export var GLOBAL_RULES = ['@charset', '@font-face', '@global', '@import', '@keyframes', '@namespace', '@page', '@viewport'];
export var LOCAL_RULES = ['@fallbacks', '@media', '@supports'];
var UnifiedSyntax = function () {

@@ -23,64 +25,214 @@ function UnifiedSyntax() {

this.events = {};
this.fallbacks = {};
this.fontFaces = {};
this.fontFaceNames = {};
this.fontFacesCache = {};
this.keyframes = {};
this.keyframeNames = {};
this.mediaQueries = {};
this.keyframesCache = {};
this.handleProperty = function (declaration, style, property) {
declaration[property] = style;
};
this.on('property', this.handleProperty).on('@charset', this.handleCharset).on('@fallbacks', this.handleFallbacks).on('@font-face', this.handleFontFace).on('@global', this.handleGlobal).on('@import', this.handleImport).on('@keyframes', this.handleKeyframes).on('@media', this.handleMedia).on('@namespace', this.handleNamespace).on('@page', this.handlePage).on('@supports', this.handleSupports).on('@viewport', this.handleViewport);
}
_createClass(UnifiedSyntax, [{
key: 'checkBlock',
value: function checkBlock(value) {
if (isObject(value)) {
return value;
}
throw new Error('Must be a style declaration.');
}
}, {
key: 'convert',
value: function convert(declarations) {
value: function convert(styleSheet) {
var _this = this;
this.resetLocalCache();
this.emit('converting');
var prevStyleSheet = _extends({}, styleSheet);
var nextStyleSheet = {};
var adaptedDeclarations = _extends({}, declarations);
GLOBAL_RULES.forEach(function (rule) {
if (!prevStyleSheet[rule]) {
delete prevStyleSheet[rule];
AT_RULES.forEach(function (atRule) {
if (atRule in adaptedDeclarations) {
_this.extract(':root', atRule, adaptedDeclarations[atRule], GLOBAL);
return;
}
delete adaptedDeclarations[atRule];
switch (rule) {
case '@charset':
case '@import':
case '@namespace':
{
var path = prevStyleSheet[rule];
if (typeof path === 'string') {
_this.emit(rule, [nextStyleSheet, path]);
} else if ("production" !== process.env.NODE_ENV) {
throw new Error(rule + ' value must be a string.');
}
break;
}
case '@font-face':
{
var faces = prevStyleSheet['@font-face'];
Object.keys(_this.checkBlock(faces)).forEach(function (fontFamily) {
if ("production" !== process.env.NODE_ENV) {
if (_this.fontFaces[fontFamily]) {
throw new Error('@font-face "' + fontFamily + '" already exists.');
}
}
_this.fontFaces[fontFamily] = toArray(faces[fontFamily]).map(function (font) {
return _extends({}, font, {
fontFamily: fontFamily
});
});
_this.emit(rule, [nextStyleSheet, _this.fontFaces[fontFamily], fontFamily]);
});
break;
}
case '@global':
{
var globals = prevStyleSheet['@global'];
Object.keys(_this.checkBlock(globals)).forEach(function (selector) {
if (isObject(globals[selector])) {
_this.emit(rule, [nextStyleSheet, _this.convertDeclaration(selector, globals[selector]), selector]);
} else if ("production" !== process.env.NODE_ENV) {
throw new Error('Invalid @global selector style declaration.');
}
});
break;
}
case '@keyframes':
{
var frames = prevStyleSheet['@keyframes'];
Object.keys(_this.checkBlock(frames)).forEach(function (animationName) {
if ("production" !== process.env.NODE_ENV) {
if (_this.keyframes[animationName]) {
throw new Error('@keyframes "' + animationName + '" already exists.');
}
}
_this.keyframes[animationName] = _this.checkBlock(frames[animationName]);
_this.emit(rule, [nextStyleSheet, _this.keyframes[animationName], animationName]);
});
break;
}
case '@page':
case '@viewport':
{
var style = prevStyleSheet[rule];
if (isObject(style)) {
_this.emit(rule, [nextStyleSheet, style]);
} else if ("production" !== process.env.NODE_ENV) {
throw new Error(rule + ' must be a style object.');
}
break;
}
default:
break;
}
delete prevStyleSheet[rule];
});
Object.keys(adaptedDeclarations).forEach(function (setName) {
var declaration = declarations[setName];
Object.keys(prevStyleSheet).forEach(function (selector) {
var declaration = prevStyleSheet[selector];
if (typeof declaration !== 'string') {
adaptedDeclarations[setName] = _this.convertDeclaration(setName, declaration);
delete prevStyleSheet[selector];
if (!declaration) {
return;
}
if (selector.charAt(0) === '@') {
if ("production" !== process.env.NODE_ENV) {
throw new SyntaxError('Unsupported global at-rule "' + selector + '".');
}
} else if (typeof declaration === 'string') {
nextStyleSheet[selector] = declaration;
} else if (isObject(declaration)) {
nextStyleSheet[selector] = _this.convertDeclaration(selector, declaration);
} else if ("production" !== process.env.NODE_ENV) {
throw new Error('Invalid style declaration for "' + selector + '".');
}
});
this.emit('converted');
return adaptedDeclarations;
return nextStyleSheet;
}
}, {
key: 'convertDeclaration',
value: function convertDeclaration(setName, properties) {
value: function convertDeclaration(selector, declaration) {
var _this2 = this;
var nextProperties = _extends({}, properties);
var prevDeclaration = _extends({}, declaration);
var nextDeclaration = {};
AT_RULES.forEach(function (atRule) {
if (atRule in nextProperties) {
_this2.extract(setName, atRule, nextProperties[atRule], LOCAL);
Object.keys(prevDeclaration).forEach(function (key) {
if (key.charAt(0) !== '@') {
_this2.emit('property', [nextDeclaration, prevDeclaration[key], key]);
delete nextProperties[atRule];
delete prevDeclaration[key];
}
});
this.emit('declaration', [setName, nextProperties]);
LOCAL_RULES.forEach(function (rule) {
var style = prevDeclaration[rule];
return nextProperties;
delete prevDeclaration[rule];
if (!style || !isObject(style)) {
return;
}
if (rule === '@fallbacks') {
Object.keys(style).forEach(function (property) {
_this2.emit(rule, [nextDeclaration, toArray(style[property]), property]);
});
} else if (rule === '@media' || rule === '@supports') {
Object.keys(style).forEach(function (condition) {
if (isObject(style[condition])) {
_this2.emit(rule, [nextDeclaration, style[condition], condition]);
} else if ("production" !== process.env.NODE_ENV) {
throw new Error(rule + ' ' + condition + ' must be a mapping of conditions to style objects.');
}
});
}
});
if ("production" !== process.env.NODE_ENV) {
Object.keys(prevDeclaration).forEach(function (key) {
throw new SyntaxError('Unsupported local at-rule "' + key + '".');
});
}
return nextDeclaration;
}
}, {
key: 'createUnsupportedHandler',
value: function createUnsupportedHandler(rule) {
return function () {
throw new Error('Adapter does not support "' + rule + '".');
};
}
}, {
key: 'emit',
value: function emit(eventName) {
var args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
value: function emit(eventName, args) {
if (this.events[eventName]) {

@@ -95,111 +247,87 @@ var _events;

}, {
key: 'extract',
value: function extract(setName, atRule, rules, fromScope) {
if ("production" !== process.env.NODE_ENV) {
if (!isObject(rules)) {
throw new SyntaxError('At-rule declaration "' + atRule + '" must be an object.');
}
}
switch (atRule) {
case '@fallbacks':
this.extractFallbacks(setName, rules, fromScope);
break;
case '@font-face':
this.extractFontFaces(setName, rules, fromScope);
break;
case '@keyframes':
this.extractKeyframes(setName, rules, fromScope);
break;
case '@media':
this.extractMediaQueries(setName, rules, fromScope);
break;
default:
{
if ("production" !== process.env.NODE_ENV) {
throw new SyntaxError('Unsupported at-rule "' + atRule + '".');
}
}
}
key: 'handleCharset',
value: function handleCharset(styleSheet, style) {
styleSheet['@charset'] = style;
}
}, {
key: 'extractFallbacks',
value: function extractFallbacks(setName, properties, fromScope) {
if ("production" !== process.env.NODE_ENV) {
if (fromScope === GLOBAL) {
throw new SyntaxError('Property fallbacks must be defined locally to an element.');
}
}
this.fallbacks[setName] = properties;
this.emit('fallback', [setName, properties]);
key: 'handleFallbacks',
value: function handleFallbacks(declaration, style, property) {
declaration[property] = [declaration[property]].concat(_toConsumableArray(style)).filter(Boolean);
}
}, {
key: 'extractFontFaces',
value: function extractFontFaces(setName, rules, fromScope) {
var _this3 = this;
key: 'handleFontFace',
value: function handleFontFace(styleSheet, style, fontFamily) {
if (Array.isArray(styleSheet['@font-face'])) {
var _styleSheet$FontFac;
if ("production" !== process.env.NODE_ENV) {
if (fromScope === LOCAL) {
throw new SyntaxError('Font faces must be declared in the global scope.');
}
(_styleSheet$FontFac = styleSheet['@font-face']).push.apply(_styleSheet$FontFac, _toConsumableArray(style));
} else {
styleSheet['@font-face'] = style;
}
Object.keys(rules).forEach(function (name) {
var familyName = String(rules[name].fontFamily);
if (_this3.fontFaces[familyName]) {
if ("production" !== process.env.NODE_ENV) {
throw new TypeError('Font face "' + familyName + '" has already been defined.');
}
} else {
_this3.fontFaces[familyName] = rules[name];
}
_this3.emit('fontFace', [setName, familyName, rules[name]]);
});
}
}, {
key: 'extractKeyframes',
value: function extractKeyframes(setName, rules, fromScope) {
var _this4 = this;
key: 'handleGlobal',
value: function handleGlobal(styleSheet, declaration, selector) {}
}, {
key: 'handleImport',
value: function handleImport(styleSheet, style) {
styleSheet['@import'] = style;
}
}, {
key: 'handleKeyframes',
value: function handleKeyframes(styleSheet, style, animationName) {
styleSheet['@keyframes ' + animationName] = style;
}
}, {
key: 'handleMedia',
value: function handleMedia(declaration, style, condition) {
declaration['@media ' + condition] = style;
}
}, {
key: 'handleNamespace',
value: function handleNamespace(styleSheet, style) {
styleSheet['@namespace'] = style;
}
}, {
key: 'handlePage',
value: function handlePage(styleSheet, style) {
styleSheet['@page'] = style;
}
}, {
key: 'handleSupports',
value: function handleSupports(declaration, style, condition) {
declaration['@supports ' + condition] = style;
}
}, {
key: 'handleViewport',
value: function handleViewport(styleSheet, style) {
styleSheet['@viewport'] = style;
}
}, {
key: 'injectFontFaces',
value: function injectFontFaces(value, cache) {
var fontFaces = [];
if ("production" !== process.env.NODE_ENV) {
if (fromScope === LOCAL) {
throw new SyntaxError('Animation keyframes must be declared in the global scope.');
}
}
String(value).split(',').forEach(function (name) {
var familyName = name.trim();
var fonts = cache[familyName];
Object.keys(rules).forEach(function (name) {
if (_this4.keyframes[name]) {
if ("production" !== process.env.NODE_ENV) {
throw new TypeError('Animation keyframe "' + name + '" has already been defined.');
}
if (Array.isArray(fonts)) {
fonts.forEach(function (font) {
fontFaces.push(formatFontFace(font));
});
} else {
_this4.keyframes[name] = rules[name];
fontFaces.push(familyName);
}
});
_this4.emit('keyframe', [setName, name, rules[name]]);
});
return fontFaces;
}
}, {
key: 'extractMediaQueries',
value: function extractMediaQueries(setName, rules, fromScope) {
var _this5 = this;
key: 'injectKeyframes',
value: function injectKeyframes(value, cache) {
return String(value).split(',').map(function (name) {
var animationName = name.trim();
if ("production" !== process.env.NODE_ENV) {
if (fromScope === GLOBAL) {
throw new SyntaxError('Media queries must be defined locally to an element.');
}
}
this.mediaQueries[setName] = rules;
Object.keys(rules).forEach(function (query) {
_this5.emit('mediaQuery', [setName, query, rules[query]]);
return cache[animationName] || animationName;
});

@@ -221,14 +349,2 @@ }

}
}, {
key: 'resetGlobalCache',
value: function resetGlobalCache() {
this.fontFaces = {};
this.keyframes = {};
}
}, {
key: 'resetLocalCache',
value: function resetLocalCache() {
this.fallbacks = {};
this.mediaQueries = {};
}
}]);

@@ -239,4 +355,2 @@

UnifiedSyntax.LOCAL = LOCAL;
UnifiedSyntax.GLOBAL = GLOBAL;
export default UnifiedSyntax;

@@ -25,4 +25,2 @@ 'use strict';

(0, _classCallCheck3.default)(this, Adapter);
this.bypassNativeStyleSheet = false;
this.native = false;
this.options = {};

@@ -34,4 +32,9 @@

(0, _createClass3.default)(Adapter, [{
key: 'create',
value: function create(styleSheet) {
return styleSheet;
}
}, {
key: 'transform',
value: function transform(styleName, declarations) {
value: function transform() {
throw new Error(this.constructor.name + ' must define the `transform` method.');

@@ -38,0 +41,0 @@ }

@@ -7,2 +7,6 @@ 'use strict';

var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
var _extends2 = require('babel-runtime/helpers/extends');

@@ -20,4 +24,2 @@

var _aestheticUtils = require('aesthetic-utils');
var _lodash = require('lodash.merge');

@@ -27,2 +29,10 @@

var _isObject = require('./helpers/isObject');
var _isObject2 = _interopRequireDefault(_isObject);
var _stripClassPrefix = require('./helpers/stripClassPrefix');
var _stripClassPrefix2 = _interopRequireDefault(_stripClassPrefix);
var _Adapter = require('./Adapter');

@@ -32,2 +42,6 @@

var _style = require('./style');
var _style2 = _interopRequireDefault(_style);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -39,4 +53,3 @@

(0, _classCallCheck3.default)(this, Aesthetic);
this.cache = {};
this.native = false;
this.cache = new WeakMap();
this.options = {

@@ -46,3 +59,3 @@ defaultTheme: '',

pure: false,
stylesPropName: 'classNames',
stylesPropName: 'styles',
themePropName: 'theme'

@@ -60,19 +73,12 @@ };

(0, _createClass3.default)(Aesthetic, [{
key: 'extendTheme',
value: function extendTheme(parentThemeName, themeName) {
var theme = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var globals = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
return this.registerTheme(themeName, (0, _lodash2.default)({}, this.getTheme(parentThemeName), theme), globals);
}
}, {
key: 'getStyles',
value: function getStyles(styleName) {
key: 'createStyleSheet',
value: function createStyleSheet(styleName) {
var themeName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
var props = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var parentStyleName = this.parents[styleName];
var declarations = this.styles[styleName];
var styleSheet = this.styles[styleName];
if ("production" !== process.env.NODE_ENV) {
if (!declarations) {
if (!styleSheet) {
throw new Error('Styles do not exist for "' + styleName + '".');

@@ -82,9 +88,21 @@ }

if (typeof declarations !== 'function') {
return declarations;
if (typeof styleSheet === 'function') {
styleSheet = styleSheet(themeName ? this.getTheme(themeName) : {}, props);
}
return declarations(themeName ? this.getTheme(themeName) : {}, parentStyleName ? this.getStyles(parentStyleName, themeName) : {});
if (parentStyleName) {
styleSheet = (0, _lodash2.default)({}, this.createStyleSheet(parentStyleName, themeName, props), styleSheet);
}
return this.adapter.create(styleSheet);
}
}, {
key: 'extendTheme',
value: function extendTheme(parentThemeName, themeName) {
var theme = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var globals = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
return this.registerTheme(themeName, (0, _lodash2.default)({}, this.getTheme(parentThemeName), theme), globals);
}
}, {
key: 'getTheme',

@@ -119,5 +137,5 @@ value: function getTheme() {

throw new Error('Theme "' + themeName + '" already exists.');
} else if (!(0, _aestheticUtils.isObject)(theme)) {
} else if (!(0, _isObject2.default)(theme)) {
throw new TypeError('Theme "' + themeName + '" must be a style object.');
} else if (!(0, _aestheticUtils.isObject)(globals)) {
} else if (!(0, _isObject2.default)(globals)) {
throw new TypeError('Global styles for "' + themeName + '" must be an object.');

@@ -129,4 +147,6 @@ }

this.adapter.transform(':root', globals);
var globalStyleSheet = this.adapter.create(globals);
this.transformStyles(Object.values(globalStyleSheet));
return this;

@@ -138,3 +158,2 @@ }

if (adapter instanceof _Adapter2.default || adapter && typeof adapter.transform === 'function') {
adapter.native = this.native;
this.adapter = adapter;

@@ -149,3 +168,3 @@ } else if ("production" !== process.env.NODE_ENV) {

key: 'setStyles',
value: function setStyles(styleName, declarations) {
value: function setStyles(styleName, styleSheet) {
var extendFrom = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';

@@ -156,3 +175,3 @@

throw new Error('Styles have already been set for "' + styleName + '".');
} else if (!(0, _aestheticUtils.isObject)(declarations) && typeof declarations !== 'function') {
} else if (!(0, _isObject2.default)(styleSheet) && typeof styleSheet !== 'function') {
throw new TypeError('Styles defined for "' + styleName + '" must be an object or function.');

@@ -162,3 +181,3 @@ }

this.styles[styleName] = declarations;
this.styles[styleName] = styleSheet;

@@ -181,48 +200,42 @@ if (extendFrom) {

key: 'transformStyles',
value: function transformStyles(styleName, themeName) {
var _this = this;
var fallbackThemeName = themeName || this.options.defaultTheme || '';
var cacheKey = styleName + ':' + fallbackThemeName;
if (this.cache[cacheKey]) {
return this.cache[cacheKey];
value: function transformStyles(styles) {
if (this.cache.has(styles)) {
return this.cache.get(styles);
}
var declarations = this.getStyles(styleName, fallbackThemeName);
var toTransform = {};
var output = {};
var setCount = 0;
var classNames = [];
var toTransform = [];
Object.keys(declarations).forEach(function (setName) {
if (typeof declarations[setName] === 'string') {
output[setName] = _this.native ? {} : declarations[setName];
} else {
toTransform[setName] = declarations[setName];
setCount += 1;
styles.forEach(function (style) {
if (!style) {
return;
} else if (typeof style === 'string' || typeof style === 'number') {
classNames.push.apply(classNames, (0, _toConsumableArray3.default)(String(style).split(' ').map(function (s) {
return (0, _stripClassPrefix2.default)(s).trim();
})));
} else if ((0, _isObject2.default)(style)) {
toTransform.push(style);
} else if ("production" !== process.env.NODE_ENV) {
throw new Error('Unsupported style type to transform.');
}
});
if (setCount > 0) {
var transformedOutput = this.adapter.transform(styleName, toTransform);
if (toTransform.length > 0) {
var _adapter;
Object.keys(transformedOutput).forEach(function (setName) {
output[setName] = _this.validateTransform(styleName, setName, transformedOutput[setName]);
});
classNames.push((_adapter = this.adapter).transform.apply(_adapter, toTransform));
}
this.cache[cacheKey] = output;
var className = classNames.join(' ').trim();
return output;
this.cache.set(styles, className);
return className;
}
}, {
key: 'validateTransform',
value: function validateTransform(styleName, setName, value) {
if ("production" !== process.env.NODE_ENV) {
if (typeof value !== 'string') {
throw new TypeError('`' + this.adapter.constructor.name + '` must return a mapping of CSS class names. ' + ('"' + styleName + '@' + setName + '" is not a valid string.'));
}
}
key: 'withStyles',
value: function withStyles(styleSheet) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return value;
return (0, _style2.default)(this, styleSheet, options);
}

@@ -229,0 +242,0 @@ }]);

@@ -48,14 +48,20 @@ 'use strict';

key: 'transform',
value: function transform(styleName, declarations) {
var classNames = {};
value: function transform() {
var _this2 = this;
Object.keys(declarations).forEach(function (setName) {
if (typeof declarations[setName] === 'string') {
classNames[setName] = declarations[setName];
var classNames = [];
for (var _len2 = arguments.length, styles = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
styles[_key2] = arguments[_key2];
}
styles.forEach(function (style) {
if (style && typeof style === 'string') {
classNames.push(style);
} else if ("production" !== process.env.NODE_ENV) {
throw new TypeError('`ClassNameAdapter` expects valid CSS class names; ' + ('non-string provided for "' + setName + '".'));
throw new TypeError(_this2.constructor.name + ' expects valid CSS class names.');
}
});
return classNames;
return classNames.join(' ');
}

@@ -62,0 +68,0 @@ }]);

@@ -12,14 +12,4 @@ 'use strict';

var _style = require('./style');
var _style2 = _interopRequireDefault(_style);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* @copyright 2017, Miles Johnson
* @license https://opensource.org/licenses/MIT
*
*/
function createStyler(aesthetic) {

@@ -32,8 +22,20 @@ if ("production" !== process.env.NODE_ENV) {

return function styler() {
var defaultStyles = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return {
style: function style(styleSheet) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return (0, _style2.default)(aesthetic, defaultStyles, options);
return aesthetic.withStyles(styleSheet, options);
},
transform: function transform() {
for (var _len = arguments.length, styles = Array(_len), _key = 0; _key < _len; _key++) {
styles[_key] = arguments[_key];
}
return aesthetic.transformStyles(styles);
}
};
}
} /**
* @copyright 2017, Miles Johnson
* @license https://opensource.org/licenses/MIT
*
*/

@@ -6,3 +6,3 @@ 'use strict';

});
exports.classes = exports.createStyler = exports.ThemeProvider = exports.ClassNameAdapter = exports.Adapter = exports.ClassOrStylesPropType = exports.StylesPropType = exports.ClassNamesPropType = undefined;
exports.createStyler = exports.ThemeProvider = exports.ClassNameAdapter = exports.Adapter = exports.StylesPropType = undefined;

@@ -33,15 +33,11 @@ var _propTypes = require('prop-types');

var _classes = require('./classes');
var _classes2 = _interopRequireDefault(_classes);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var ClassNamesPropType = exports.ClassNamesPropType = _propTypes2.default.objectOf(_propTypes2.default.string); /**
* @copyright 2017, Miles Johnson
* @license https://opensource.org/licenses/MIT
*/
/**
* @copyright 2017, Miles Johnson
* @license https://opensource.org/licenses/MIT
*
*/
var StylesPropType = exports.StylesPropType = _propTypes2.default.objectOf(_propTypes2.default.object);
var ClassOrStylesPropType = exports.ClassOrStylesPropType = _propTypes2.default.oneOfType([_propTypes2.default.objectOf(_propTypes2.default.string), _propTypes2.default.objectOf(_propTypes2.default.object)]);

@@ -52,3 +48,2 @@ exports.Adapter = _Adapter2.default;

exports.createStyler = _createStyler2.default;
exports.classes = _classes2.default;
exports.default = _Aesthetic2.default;

@@ -60,3 +60,3 @@ 'use strict';

function style(aesthetic) {
var styles = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var styleSheet = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};

@@ -93,3 +93,3 @@

aesthetic.setStyles(styleName, styles, extendFrom);
aesthetic.setStyles(styleName, styleSheet, extendFrom);

@@ -100,4 +100,15 @@ var StyledComponent = function (_ParentComponent) {

function StyledComponent() {
var _ref, _this$state;
var _temp, _this, _ret;
(0, _classCallCheck3.default)(this, StyledComponent);
return (0, _possibleConstructorReturn3.default)(this, (StyledComponent.__proto__ || Object.getPrototypeOf(StyledComponent)).apply(this, arguments));
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return _ret = (_temp = (_this = (0, _possibleConstructorReturn3.default)(this, (_ref = StyledComponent.__proto__ || Object.getPrototypeOf(StyledComponent)).call.apply(_ref, [this].concat(args))), _this), _this.state = (_this$state = {
firstMount: true
}, (0, _defineProperty3.default)(_this$state, stylesPropName, {}), (0, _defineProperty3.default)(_this$state, 'themeName', ''), (0, _defineProperty3.default)(_this$state, themePropName, {}), _this$state), _temp), (0, _possibleConstructorReturn3.default)(_this, _ret);
}

@@ -108,3 +119,3 @@

value: function componentWillMount() {
this.transformStyles(this.getTheme(this.props));
this.transformStyles(this.props);
}

@@ -114,19 +125,21 @@ }, {

value: function componentWillReceiveProps(nextProps) {
var theme = this.getTheme(nextProps);
if (theme !== this.state[themePropName]) {
this.transformStyles(theme);
}
this.transformStyles(nextProps);
}
}, {
key: 'getTheme',
value: function getTheme(props) {
return props[themePropName] || this.context.themeName || aesthetic.options.defaultTheme || '';
key: 'getThemeName',
value: function getThemeName(props) {
return props.themeName || this.context.themeName || aesthetic.options.defaultTheme || '';
}
}, {
key: 'transformStyles',
value: function transformStyles(theme) {
var _setState;
value: function transformStyles(props) {
var themeName = this.getThemeName(props);
this.setState((_setState = {}, (0, _defineProperty3.default)(_setState, stylesPropName, aesthetic.transformStyles(styleName, theme)), (0, _defineProperty3.default)(_setState, themePropName, theme), _setState));
if (this.state.firstMount || themeName !== this.state.themeName) {
var _setState;
this.setState((_setState = {
firstMount: false
}, (0, _defineProperty3.default)(_setState, stylesPropName, aesthetic.createStyleSheet(styleName, themeName, props)), (0, _defineProperty3.default)(_setState, 'themeName', themeName), (0, _defineProperty3.default)(_setState, themePropName, themeName ? aesthetic.getTheme(themeName) : {}), _setState));
}
}

@@ -140,3 +153,4 @@ }, {

key: 'extendStyles',
value: function extendStyles(customStyles) {
value: function extendStyles() {
var customStyleSheet = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var extendOptions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

@@ -150,3 +164,3 @@

return style(aesthetic, customStyles, (0, _extends3.default)({}, options, extendOptions, {
return style(aesthetic, customStyleSheet, (0, _extends3.default)({}, options, extendOptions, {
extendFrom: styleName

@@ -161,7 +175,12 @@ }))(Component);

StyledComponent.styleName = styleName;
StyledComponent.wrappedComponent = Component;
StyledComponent.propTypes = (0, _defineProperty3.default)({}, themePropName, _propTypes2.default.string);
StyledComponent.WrappedComponent = Component;
StyledComponent.contextTypes = {
themeName: _propTypes2.default.string
};
StyledComponent.propTypes = {
themeName: _propTypes2.default.string
};
StyledComponent.defaultProps = {
themeName: ''
};

@@ -168,0 +187,0 @@

@@ -6,3 +6,3 @@ 'use strict';

});
exports.AT_RULES = exports.GLOBAL = exports.LOCAL = undefined;
exports.LOCAL_RULES = exports.GLOBAL_RULES = undefined;

@@ -25,14 +25,23 @@ var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');

var _aestheticUtils = require('aesthetic-utils');
var _formatFontFace = require('./helpers/formatFontFace');
var _formatFontFace2 = _interopRequireDefault(_formatFontFace);
var _isObject = require('./helpers/isObject');
var _isObject2 = _interopRequireDefault(_isObject);
var _toArray = require('./helpers/toArray');
var _toArray2 = _interopRequireDefault(_toArray);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var LOCAL = exports.LOCAL = 'local'; /**
* @copyright 2017, Miles Johnson
* @license https://opensource.org/licenses/MIT
*
*/
var GLOBAL_RULES = exports.GLOBAL_RULES = ['@charset', '@font-face', '@global', '@import', '@keyframes', '@namespace', '@page', '@viewport']; /**
* @copyright 2017, Miles Johnson
* @license https://opensource.org/licenses/MIT
*
*/
var GLOBAL = exports.GLOBAL = 'global';
var AT_RULES = exports.AT_RULES = ['@fallbacks', '@font-face', '@keyframes', '@media'];
var LOCAL_RULES = exports.LOCAL_RULES = ['@fallbacks', '@media', '@supports'];

@@ -43,64 +52,214 @@ var UnifiedSyntax = function () {

this.events = {};
this.fallbacks = {};
this.fontFaces = {};
this.fontFaceNames = {};
this.fontFacesCache = {};
this.keyframes = {};
this.keyframeNames = {};
this.mediaQueries = {};
this.keyframesCache = {};
this.handleProperty = function (declaration, style, property) {
declaration[property] = style;
};
this.on('property', this.handleProperty).on('@charset', this.handleCharset).on('@fallbacks', this.handleFallbacks).on('@font-face', this.handleFontFace).on('@global', this.handleGlobal).on('@import', this.handleImport).on('@keyframes', this.handleKeyframes).on('@media', this.handleMedia).on('@namespace', this.handleNamespace).on('@page', this.handlePage).on('@supports', this.handleSupports).on('@viewport', this.handleViewport);
}
(0, _createClass3.default)(UnifiedSyntax, [{
key: 'checkBlock',
value: function checkBlock(value) {
if ((0, _isObject2.default)(value)) {
return value;
}
throw new Error('Must be a style declaration.');
}
}, {
key: 'convert',
value: function convert(declarations) {
value: function convert(styleSheet) {
var _this = this;
this.resetLocalCache();
this.emit('converting');
var prevStyleSheet = (0, _extends3.default)({}, styleSheet);
var nextStyleSheet = {};
var adaptedDeclarations = (0, _extends3.default)({}, declarations);
GLOBAL_RULES.forEach(function (rule) {
if (!prevStyleSheet[rule]) {
delete prevStyleSheet[rule];
AT_RULES.forEach(function (atRule) {
if (atRule in adaptedDeclarations) {
_this.extract(':root', atRule, adaptedDeclarations[atRule], GLOBAL);
return;
}
delete adaptedDeclarations[atRule];
switch (rule) {
case '@charset':
case '@import':
case '@namespace':
{
var path = prevStyleSheet[rule];
if (typeof path === 'string') {
_this.emit(rule, [nextStyleSheet, path]);
} else if ("production" !== process.env.NODE_ENV) {
throw new Error(rule + ' value must be a string.');
}
break;
}
case '@font-face':
{
var faces = prevStyleSheet['@font-face'];
Object.keys(_this.checkBlock(faces)).forEach(function (fontFamily) {
if ("production" !== process.env.NODE_ENV) {
if (_this.fontFaces[fontFamily]) {
throw new Error('@font-face "' + fontFamily + '" already exists.');
}
}
_this.fontFaces[fontFamily] = (0, _toArray2.default)(faces[fontFamily]).map(function (font) {
return (0, _extends3.default)({}, font, {
fontFamily: fontFamily
});
});
_this.emit(rule, [nextStyleSheet, _this.fontFaces[fontFamily], fontFamily]);
});
break;
}
case '@global':
{
var globals = prevStyleSheet['@global'];
Object.keys(_this.checkBlock(globals)).forEach(function (selector) {
if ((0, _isObject2.default)(globals[selector])) {
_this.emit(rule, [nextStyleSheet, _this.convertDeclaration(selector, globals[selector]), selector]);
} else if ("production" !== process.env.NODE_ENV) {
throw new Error('Invalid @global selector style declaration.');
}
});
break;
}
case '@keyframes':
{
var frames = prevStyleSheet['@keyframes'];
Object.keys(_this.checkBlock(frames)).forEach(function (animationName) {
if ("production" !== process.env.NODE_ENV) {
if (_this.keyframes[animationName]) {
throw new Error('@keyframes "' + animationName + '" already exists.');
}
}
_this.keyframes[animationName] = _this.checkBlock(frames[animationName]);
_this.emit(rule, [nextStyleSheet, _this.keyframes[animationName], animationName]);
});
break;
}
case '@page':
case '@viewport':
{
var style = prevStyleSheet[rule];
if ((0, _isObject2.default)(style)) {
_this.emit(rule, [nextStyleSheet, style]);
} else if ("production" !== process.env.NODE_ENV) {
throw new Error(rule + ' must be a style object.');
}
break;
}
default:
break;
}
delete prevStyleSheet[rule];
});
Object.keys(adaptedDeclarations).forEach(function (setName) {
var declaration = declarations[setName];
Object.keys(prevStyleSheet).forEach(function (selector) {
var declaration = prevStyleSheet[selector];
if (typeof declaration !== 'string') {
adaptedDeclarations[setName] = _this.convertDeclaration(setName, declaration);
delete prevStyleSheet[selector];
if (!declaration) {
return;
}
if (selector.charAt(0) === '@') {
if ("production" !== process.env.NODE_ENV) {
throw new SyntaxError('Unsupported global at-rule "' + selector + '".');
}
} else if (typeof declaration === 'string') {
nextStyleSheet[selector] = declaration;
} else if ((0, _isObject2.default)(declaration)) {
nextStyleSheet[selector] = _this.convertDeclaration(selector, declaration);
} else if ("production" !== process.env.NODE_ENV) {
throw new Error('Invalid style declaration for "' + selector + '".');
}
});
this.emit('converted');
return adaptedDeclarations;
return nextStyleSheet;
}
}, {
key: 'convertDeclaration',
value: function convertDeclaration(setName, properties) {
value: function convertDeclaration(selector, declaration) {
var _this2 = this;
var nextProperties = (0, _extends3.default)({}, properties);
var prevDeclaration = (0, _extends3.default)({}, declaration);
var nextDeclaration = {};
AT_RULES.forEach(function (atRule) {
if (atRule in nextProperties) {
_this2.extract(setName, atRule, nextProperties[atRule], LOCAL);
Object.keys(prevDeclaration).forEach(function (key) {
if (key.charAt(0) !== '@') {
_this2.emit('property', [nextDeclaration, prevDeclaration[key], key]);
delete nextProperties[atRule];
delete prevDeclaration[key];
}
});
this.emit('declaration', [setName, nextProperties]);
LOCAL_RULES.forEach(function (rule) {
var style = prevDeclaration[rule];
return nextProperties;
delete prevDeclaration[rule];
if (!style || !(0, _isObject2.default)(style)) {
return;
}
if (rule === '@fallbacks') {
Object.keys(style).forEach(function (property) {
_this2.emit(rule, [nextDeclaration, (0, _toArray2.default)(style[property]), property]);
});
} else if (rule === '@media' || rule === '@supports') {
Object.keys(style).forEach(function (condition) {
if ((0, _isObject2.default)(style[condition])) {
_this2.emit(rule, [nextDeclaration, style[condition], condition]);
} else if ("production" !== process.env.NODE_ENV) {
throw new Error(rule + ' ' + condition + ' must be a mapping of conditions to style objects.');
}
});
}
});
if ("production" !== process.env.NODE_ENV) {
Object.keys(prevDeclaration).forEach(function (key) {
throw new SyntaxError('Unsupported local at-rule "' + key + '".');
});
}
return nextDeclaration;
}
}, {
key: 'createUnsupportedHandler',
value: function createUnsupportedHandler(rule) {
return function () {
throw new Error('Adapter does not support "' + rule + '".');
};
}
}, {
key: 'emit',
value: function emit(eventName) {
var args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
value: function emit(eventName, args) {
if (this.events[eventName]) {

@@ -115,111 +274,87 @@ var _events;

}, {
key: 'extract',
value: function extract(setName, atRule, rules, fromScope) {
if ("production" !== process.env.NODE_ENV) {
if (!(0, _aestheticUtils.isObject)(rules)) {
throw new SyntaxError('At-rule declaration "' + atRule + '" must be an object.');
}
}
switch (atRule) {
case '@fallbacks':
this.extractFallbacks(setName, rules, fromScope);
break;
case '@font-face':
this.extractFontFaces(setName, rules, fromScope);
break;
case '@keyframes':
this.extractKeyframes(setName, rules, fromScope);
break;
case '@media':
this.extractMediaQueries(setName, rules, fromScope);
break;
default:
{
if ("production" !== process.env.NODE_ENV) {
throw new SyntaxError('Unsupported at-rule "' + atRule + '".');
}
}
}
key: 'handleCharset',
value: function handleCharset(styleSheet, style) {
styleSheet['@charset'] = style;
}
}, {
key: 'extractFallbacks',
value: function extractFallbacks(setName, properties, fromScope) {
if ("production" !== process.env.NODE_ENV) {
if (fromScope === GLOBAL) {
throw new SyntaxError('Property fallbacks must be defined locally to an element.');
}
}
this.fallbacks[setName] = properties;
this.emit('fallback', [setName, properties]);
key: 'handleFallbacks',
value: function handleFallbacks(declaration, style, property) {
declaration[property] = [declaration[property]].concat((0, _toConsumableArray3.default)(style)).filter(Boolean);
}
}, {
key: 'extractFontFaces',
value: function extractFontFaces(setName, rules, fromScope) {
var _this3 = this;
key: 'handleFontFace',
value: function handleFontFace(styleSheet, style, fontFamily) {
if (Array.isArray(styleSheet['@font-face'])) {
var _styleSheet$FontFac;
if ("production" !== process.env.NODE_ENV) {
if (fromScope === LOCAL) {
throw new SyntaxError('Font faces must be declared in the global scope.');
}
(_styleSheet$FontFac = styleSheet['@font-face']).push.apply(_styleSheet$FontFac, (0, _toConsumableArray3.default)(style));
} else {
styleSheet['@font-face'] = style;
}
Object.keys(rules).forEach(function (name) {
var familyName = String(rules[name].fontFamily);
if (_this3.fontFaces[familyName]) {
if ("production" !== process.env.NODE_ENV) {
throw new TypeError('Font face "' + familyName + '" has already been defined.');
}
} else {
_this3.fontFaces[familyName] = rules[name];
}
_this3.emit('fontFace', [setName, familyName, rules[name]]);
});
}
}, {
key: 'extractKeyframes',
value: function extractKeyframes(setName, rules, fromScope) {
var _this4 = this;
key: 'handleGlobal',
value: function handleGlobal(styleSheet, declaration, selector) {}
}, {
key: 'handleImport',
value: function handleImport(styleSheet, style) {
styleSheet['@import'] = style;
}
}, {
key: 'handleKeyframes',
value: function handleKeyframes(styleSheet, style, animationName) {
styleSheet['@keyframes ' + animationName] = style;
}
}, {
key: 'handleMedia',
value: function handleMedia(declaration, style, condition) {
declaration['@media ' + condition] = style;
}
}, {
key: 'handleNamespace',
value: function handleNamespace(styleSheet, style) {
styleSheet['@namespace'] = style;
}
}, {
key: 'handlePage',
value: function handlePage(styleSheet, style) {
styleSheet['@page'] = style;
}
}, {
key: 'handleSupports',
value: function handleSupports(declaration, style, condition) {
declaration['@supports ' + condition] = style;
}
}, {
key: 'handleViewport',
value: function handleViewport(styleSheet, style) {
styleSheet['@viewport'] = style;
}
}, {
key: 'injectFontFaces',
value: function injectFontFaces(value, cache) {
var fontFaces = [];
if ("production" !== process.env.NODE_ENV) {
if (fromScope === LOCAL) {
throw new SyntaxError('Animation keyframes must be declared in the global scope.');
}
}
String(value).split(',').forEach(function (name) {
var familyName = name.trim();
var fonts = cache[familyName];
Object.keys(rules).forEach(function (name) {
if (_this4.keyframes[name]) {
if ("production" !== process.env.NODE_ENV) {
throw new TypeError('Animation keyframe "' + name + '" has already been defined.');
}
if (Array.isArray(fonts)) {
fonts.forEach(function (font) {
fontFaces.push((0, _formatFontFace2.default)(font));
});
} else {
_this4.keyframes[name] = rules[name];
fontFaces.push(familyName);
}
});
_this4.emit('keyframe', [setName, name, rules[name]]);
});
return fontFaces;
}
}, {
key: 'extractMediaQueries',
value: function extractMediaQueries(setName, rules, fromScope) {
var _this5 = this;
key: 'injectKeyframes',
value: function injectKeyframes(value, cache) {
return String(value).split(',').map(function (name) {
var animationName = name.trim();
if ("production" !== process.env.NODE_ENV) {
if (fromScope === GLOBAL) {
throw new SyntaxError('Media queries must be defined locally to an element.');
}
}
this.mediaQueries[setName] = rules;
Object.keys(rules).forEach(function (query) {
_this5.emit('mediaQuery', [setName, query, rules[query]]);
return cache[animationName] || animationName;
});

@@ -241,14 +376,2 @@ }

}
}, {
key: 'resetGlobalCache',
value: function resetGlobalCache() {
this.fontFaces = {};
this.keyframes = {};
}
}, {
key: 'resetLocalCache',
value: function resetLocalCache() {
this.fallbacks = {};
this.mediaQueries = {};
}
}]);

@@ -258,4 +381,2 @@ return UnifiedSyntax;

UnifiedSyntax.LOCAL = LOCAL;
UnifiedSyntax.GLOBAL = GLOBAL;
exports.default = UnifiedSyntax;
{
"name": "aesthetic",
"version": "1.7.1",
"version": "2.0.0-0",
"description": "Aesthetic is a powerful React library for styling components through the use of adapters.",

@@ -8,3 +8,2 @@ "keywords": [

"react",
"react-native",
"native",

@@ -28,3 +27,2 @@ "style",

"dependencies": {
"aesthetic-utils": "^1.6.2",
"babel-runtime": "^6.26.0",

@@ -39,5 +37,5 @@ "hoist-non-react-statics": "^2.3.1",

"devDependencies": {
"@milesj/build-tool-config": "^0.41.2",
"react": "^16.1.0"
"@milesj/build-tool-config": "^0.44.0",
"react": "^16.2.0"
}
}

@@ -19,3 +19,3 @@ # Aesthetic

children: PropTypes.node,
classNames: ClassNamesPropType,
classNames: ClassNamesPropType.isRequired,
};

@@ -32,6 +32,6 @@

role="tablist"
className={classes({
className={classes(
classNames.carousel,
animating && classNames.carousel__animating,
})}
)}
>

@@ -130,2 +130,3 @@ <ul className={classNames.list}>

* [Media Queries](#media-queries)
* [Supports](#supports)
* [Font Faces](#font-faces)

@@ -137,3 +138,2 @@ * [Animations](#animations)

* [Adapters](#adapters)
* [React Native Support](#react-native-support)

@@ -174,12 +174,14 @@ ### Initial Setup

| Adapter | Unified Syntax | Pseudos | Fallbacks | Fonts | Animations | Media Queries | React Native |
| :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
| [CSS class names](#external-classes) | | ✓ | ✓ | ✓ | ✓ | ✓ | |
| [CSS modules][css-modules] | | ✓ | ✓ | ✓ | ✓ | ✓ | |
| [Aphrodite][aphrodite] | ✓ | ✓ | | ✓ | ✓ | ✓ | |
| [Fela][fela] | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| [Glamor][glamor] | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | |
| [JSS][jss] | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | |
| [React Native][react-native] | | | | ✓ | ✓ | | ✓ |
| Adapter | Unified Syntax | Globals | Pseudos | Fallbacks | Fonts | Animations | Media Queries | Supports |
| :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
| [CSS class names](#external-classes) | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| [CSS modules][css-modules] | | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| [Aphrodite][aphrodite] | ✓ | ✓¹ | ✓ | | ✓ | ✓ | ✓ | |
| [Fela][fela] | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| [Glamor][glamor] | ✓ | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| [JSS][jss] | ✓ | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| [TypeStyle][typestyle] | ✓ | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
> 1. Only supports `@font-face` and `@keyframes`.
The following libraries are currently not supported.

@@ -223,3 +225,3 @@

object is passed to. Defaults to `classNames`.
* `themePropName` (string) - Name of the prop in which the theme name is passed to.
* `themePropName` (string) - Name of the prop in which the theme style declaration is passed to.
Defaults to `theme`.

@@ -279,3 +281,3 @@ * `pure` (boolean) - When true, the higher-order-component will extend `React.PureComponent`

children: PropTypes.node,
classNames: ClassNamesPropType,
classNames: ClassNamesPropType.isRequired,
icon: PropTypes.node,

@@ -367,3 +369,3 @@ };

as the first argument to the [styler function](#creating-a-styler). This object
represents a mapping of elements (and modifiers) to declarations. For example:
represents a mapping of selectors (and modifiers) to declarations. For example:

@@ -450,11 +452,10 @@ ```javascript

spacing: 5,
font: 'Roboto',
font: 'Open Sans',
bgColor: 'darkgray',
}, {
'@font-face': {
roboto: {
fontFamily: 'Roboto',
'Open Sans': {
fontStyle: 'normal',
fontWeight: 'normal',
src: "url('roboto.woff2') format('roboto')",
src: ['fonts/OpenSans.woff'],
},

@@ -495,2 +496,4 @@ },

> The theme style declaration can be accessed within a component via the `theme` prop.
#### Activating Themes

@@ -513,6 +516,6 @@

Or by passing a `theme` prop to an individual component.
Or by passing a `themeName` prop to an individual component.
```javascript
<Button theme="dark">Save</Button>
<Button themeName="dark">Save</Button>
```

@@ -575,3 +578,3 @@

* Supports camel case property names.
* Units can be written is literal numbers.
* Units can be written as literal numbers.

@@ -600,3 +603,3 @@ ```javascript

Pseudo elements and classes are defined inside an element as nested objects.
Pseudo elements and classes are defined inside a selector as nested objects.

@@ -642,3 +645,4 @@ ```javascript

Media queries are defined inside an element using a `@media` object.
Media queries are defined inside a selector using a `@media` object,
with the query conditional as the key, and style declarations as the value.

@@ -657,14 +661,33 @@ ```javascript

> JSS requires the `jss-nested` plugin.
#### Supports
Feature queries are defined inside a selector using a `@supports` object,
with the feature conditional as the key, and style declarations as the value.
```javascript
grid: {
// ...
float: 'left',
'@supports': {
'(display: flex)': {
float: 'none',
display: 'flex',
},
},
},
```
#### Font Faces
Font faces are defined outside the element using a `@font-face` object
and are referenced by font family name.
Font faces are defined outside the selector (in the root) using a `@font-face` object
and are referenced by the font family name (the object key).
```javascript
'@font-face': {
roboto: {
fontFamily: 'Roboto',
'Open Sans': {
fontStyle: 'normal',
fontWeight: 'normal',
src: "url('roboto.woff2') format('roboto')",
src: ['fonts/OpenSans.woff2', 'fonts/OpenSans.ttf'],
},

@@ -674,13 +697,52 @@ },

// ...
fontFamily: 'Roboto',
fontFamily: 'Open Sans',
},
tooltip: {
// ...
fontFamily: 'Roboto, sans-serif',
fontFamily: 'Open Sans, sans-serif',
},
```
> The `fontFamily` property can be omitted as it'll be inherited from the property name.
To support multiple font variations, like bold and italics, pass an array of properties.
```javascript
'@font-face': {
'Open Sans': [
{
fontStyle: 'normal',
fontWeight: 'normal',
src: ['fonts/OpenSans.woff2', 'fonts/OpenSans.ttf'],
},
{
fontStyle: 'italic',
fontWeight: 'normal',
src: ['fonts/OpenSans-Italic.woff2', 'fonts/OpenSans-Italic.ttf'],
},
{
fontStyle: 'normal',
fontWeight: 'bold',
src: ['fonts/OpenSans-Bold.woff2', 'fonts/OpenSans-Bold.ttf'],
},
],
},
```
Lastly, to define `local()` source aliases, pass an array of strings to a `local` property.
```javascript
'@font-face': {
'Open Sans': {
fontStyle: 'normal',
fontWeight: 'normal',
local: ['OpenSans', 'Open-Sans'],
src: ['fonts/OpenSans.ttf'],
},
},
```
#### Animations
Animation keyframes are defined outside the element using a `@keyframes` object
Animation keyframes are defined outside the selector (in the root) using a `@keyframes` object
and are referenced by animation name (the object key).

@@ -705,3 +767,3 @@

Parent, child, and sibling selectors are purposefully not supported. Use unique and
isolated element names and style declarations instead.
isolated element selectors and style declarations instead.

@@ -733,9 +795,4 @@ ### Competitors Comparison

| [JSS][jss] | ✓ | ✓ | | |
| [React Native][react-native] | ✓ | ✓ | | ||
| [TypeStyle][typestyle] | ✓ | | | |
### React Native Support
Please refer to the [aesthetic-native][react-native] package for more information on how
to integrate React Native with Aesthetic.
[css-modules]: https://github.com/milesj/aesthetic/tree/master/packages/aesthetic-adapter-css-modules

@@ -746,5 +803,5 @@ [aphrodite]: https://github.com/milesj/aesthetic/tree/master/packages/aesthetic-adapter-aphrodite

[jss]: https://github.com/milesj/aesthetic/tree/master/packages/aesthetic-adapter-jss
[typestyle]: https://github.com/milesj/aesthetic/tree/master/packages/aesthetic-adapter-typestyle
[radium]: https://github.com/FormidableLabs/radium
[react-native]: https://github.com/milesj/aesthetic/tree/master/packages/aesthetic-native
[react-with-styles]: https://github.com/airbnb/react-with-styles
[styled-components]: https://github.com/styled-components/styled-components

@@ -7,9 +7,5 @@ /**

import type { StyleDeclarationMap, TransformedStylesMap } from '../../types';
import type { ClassName, StyleDeclaration, StyleSheet } from '../../types';
export default class Adapter {
bypassNativeStyleSheet: boolean = false;
native: boolean = false;
options: Object = {};

@@ -22,7 +18,14 @@

/**
* Transform the unified or native syntax using the registered adapter.
* Create a stylesheet from a component's style styleSheet.
*/
transform(styleName: string, declarations: StyleDeclarationMap): TransformedStylesMap {
create(styleSheet: StyleSheet): StyleSheet {
return styleSheet;
}
/**
* Transform the style declarations using the registered adapter.
*/
transform(...styles: StyleDeclaration[]): ClassName {
throw new Error(`${this.constructor.name} must define the \`transform\` method.`);
}
}

@@ -7,13 +7,17 @@ /**

import { isObject } from 'aesthetic-utils';
import deepMerge from 'lodash.merge';
import isObject from './helpers/isObject';
import stripClassPrefix from './helpers/stripClassPrefix';
import Adapter from './Adapter';
import withStyles from './style';
import type {
AestheticOptions,
ClassName,
HOCOptions,
HOCWrapper,
StyleDeclaration,
StyleDeclarationMap,
StyleDeclarationOrCallback,
TransformedStylesMap,
CSSStyle,
StyleSheet,
StyleSheetCallback,
ThemeSheet,
} from '../../types';

@@ -24,6 +28,4 @@

cache: { [styleName: string]: TransformedStylesMap } = {};
cache: WeakMap<StyleDeclaration[], ClassName> = new WeakMap();
native: boolean = false;
options: AestheticOptions = {

@@ -33,3 +35,3 @@ defaultTheme: '',

pure: false,
stylesPropName: 'classNames',
stylesPropName: 'styles',
themePropName: 'theme',

@@ -40,5 +42,5 @@ };

styles: { [styleName: string]: StyleDeclarationOrCallback } = {};
styles: { [styleName: string]: StyleSheet | StyleSheetCallback } = {};
themes: { [themeName: string]: CSSStyle } = {};
themes: { [themeName: string]: ThemeSheet } = {};

@@ -55,27 +57,11 @@ constructor(adapter: Adapter, options?: Object = {}) {

/**
* Register a theme by extending and merging with a previously defined theme.
*/
extendTheme(
parentThemeName: string,
themeName: string,
theme?: CSSStyle = {},
globals?: StyleDeclarationMap = {},
): this {
return this.registerTheme(
themeName,
deepMerge({}, this.getTheme(parentThemeName), theme),
globals,
);
}
/**
* Extract the defined style declarations. If the declaratin is a function,
* execute it while passing the current theme and previous inherited styles.
* execute it while passing the current theme and React props.
*/
getStyles(styleName: string, themeName?: string = ''): StyleDeclarationMap {
createStyleSheet(styleName: string, themeName?: string = '', props?: Object = {}): StyleSheet {
const parentStyleName = this.parents[styleName];
const declarations = this.styles[styleName];
let styleSheet = this.styles[styleName];
if (__DEV__) {
if (!declarations) {
if (!styleSheet) {
throw new Error(`Styles do not exist for "${styleName}".`);

@@ -85,9 +71,32 @@ }

if (typeof declarations !== 'function') {
return declarations;
// Extract styleSheet from callback
if (typeof styleSheet === 'function') {
styleSheet = styleSheet(themeName ? this.getTheme(themeName) : {}, props);
}
return declarations(
themeName ? this.getTheme(themeName) : {},
parentStyleName ? this.getStyles(parentStyleName, themeName) : {},
// Merge from parent
if (parentStyleName) {
styleSheet = deepMerge(
{},
this.createStyleSheet(parentStyleName, themeName, props),
styleSheet,
);
}
return this.adapter.create(styleSheet);
}
/**
* Register a theme by extending and merging with a previously defined theme.
*/
extendTheme(
parentThemeName: string,
themeName: string,
theme?: ThemeSheet = {},
globals?: StyleSheet = {},
): this {
return this.registerTheme(
themeName,
deepMerge({}, this.getTheme(parentThemeName), theme),
globals,
);

@@ -99,3 +108,3 @@ }

*/
getTheme(themeName?: string = ''): CSSStyle {
getTheme(themeName?: string = ''): ThemeSheet {
const { defaultTheme } = this.options;

@@ -123,4 +132,4 @@

themeName: string,
theme?: CSSStyle = {},
globals?: StyleDeclarationMap = {},
theme?: ThemeSheet = {},
globals?: StyleSheet = {},
): this {

@@ -142,5 +151,8 @@ if (__DEV__) {

// Transform the global styles
this.adapter.transform(':root', globals);
// Create global styles
const globalStyleSheet = this.adapter.create(globals);
// $FlowIgnore
this.transformStyles(Object.values(globalStyleSheet));
return this;

@@ -154,3 +166,2 @@ }

if (adapter instanceof Adapter || (adapter && typeof adapter.transform === 'function')) {
adapter.native = this.native; // eslint-disable-line
this.adapter = adapter;

@@ -170,3 +181,3 @@

styleName: string,
declarations: StyleDeclarationOrCallback,
styleSheet: StyleSheet | StyleSheetCallback,
extendFrom?: string = '',

@@ -178,3 +189,3 @@ ): this {

} else if (!isObject(declarations) && typeof declarations !== 'function') {
} else if (!isObject(styleSheet) && typeof styleSheet !== 'function') {
throw new TypeError(`Styles defined for "${styleName}" must be an object or function.`);

@@ -184,3 +195,3 @@ }

this.styles[styleName] = declarations;
this.styles[styleName] = styleSheet;

@@ -204,58 +215,48 @@ if (extendFrom) {

/**
* Execute the adapter transformer on the set of style declarations for the
* defined component. Optionally support a custom theme.
* Execute the adapter transformer on the list of style declarations.
*/
transformStyles(styleName: string, themeName?: string): TransformedStylesMap {
const fallbackThemeName = themeName || this.options.defaultTheme || '';
const cacheKey = `${styleName}:${fallbackThemeName}`;
if (this.cache[cacheKey]) {
return this.cache[cacheKey];
transformStyles(styles: StyleDeclaration[]): ClassName {
if (this.cache.has(styles)) {
// $FlowIgnore We check return swith has()
return this.cache.get(styles);
}
const declarations = this.getStyles(styleName, fallbackThemeName);
const toTransform = {};
const output = {};
let setCount = 0;
const classNames = [];
const toTransform = [];
// Separate style objects from class names
Object.keys(declarations).forEach((setName: string) => {
if (typeof declarations[setName] === 'string') {
output[setName] = this.native ? {} : declarations[setName];
} else {
toTransform[setName] = declarations[setName];
setCount += 1;
styles.forEach((style) => {
// Empty value or failed condition
if (!style) {
return; // eslint-disable-line
// Acceptable class names
} else if (typeof style === 'string' || typeof style === 'number') {
classNames.push(...String(style).split(' ').map(s => stripClassPrefix(s).trim()));
// Style objects
} else if (isObject(style)) {
toTransform.push(style);
} else if (__DEV__) {
throw new Error('Unsupported style type to transform.');
}
});
// Transform the styles into a map of class names
if (setCount > 0) {
const transformedOutput = this.adapter.transform(styleName, toTransform);
Object.keys(transformedOutput).forEach((setName: string) => {
output[setName] = this.validateTransform(styleName, setName, transformedOutput[setName]);
});
if (toTransform.length > 0) {
classNames.push(this.adapter.transform(...toTransform));
}
// Cache the values
this.cache[cacheKey] = output;
const className = classNames.join(' ').trim();
return output;
this.cache.set(styles, className);
return className;
}
/**
* Validate the object returned contains valid strings.
* Utility method for wrapping a component with a styles HOC.
*/
validateTransform(styleName: string, setName: string, value: StyleDeclaration): StyleDeclaration {
if (__DEV__) {
if (typeof value !== 'string') {
throw new TypeError(
`\`${this.adapter.constructor.name}\` must return a mapping of CSS class names. ` +
`"${styleName}@${setName}" is not a valid string.`,
);
}
}
return value;
withStyles(styleSheet: StyleSheet | StyleSheetCallback, options?: HOCOptions = {}): HOCWrapper {
return withStyles(this, styleSheet, options);
}
}

@@ -9,3 +9,3 @@ /**

import type { StyleDeclarationMap, TransformedStylesMap } from '../../types';
import type { ClassName, StyleDeclaration } from '../../types';

@@ -15,18 +15,15 @@ export default class ClassNameAdapter extends Adapter {

transform(styleName: string, declarations: StyleDeclarationMap): TransformedStylesMap {
const classNames = {};
transform(...styles: StyleDeclaration[]): ClassName {
const classNames = [];
Object.keys(declarations).forEach((setName: string) => {
if (typeof declarations[setName] === 'string') {
classNames[setName] = declarations[setName];
styles.forEach((style) => {
if (style && typeof style === 'string') {
classNames.push(style);
} else if (__DEV__) {
throw new TypeError(
'`ClassNameAdapter` expects valid CSS class names; ' +
`non-string provided for "${setName}".`,
);
throw new TypeError(`${this.constructor.name} expects valid CSS class names.`);
}
});
return classNames;
return classNames.join(' ');
}
}

@@ -8,12 +8,16 @@ /**

import Aesthetic from './Aesthetic';
import style from './style';
import type {
StyleDeclarationOrCallback,
HOCComponent,
ClassName,
HOCOptions,
WrappedComponent,
HOCWrapper,
StyleDeclaration,
StyleSheet,
StyleSheetCallback,
} from '../../types';
export default function createStyler(aesthetic: Aesthetic): * {
export default function createStyler(aesthetic: Aesthetic): {
style: (styleSheet: StyleSheet | StyleSheetCallback, options?: HOCOptions) => HOCWrapper,
transform: (...styles: StyleDeclaration[]) => ClassName,
} {
if (__DEV__) {

@@ -25,8 +29,10 @@ if (!(aesthetic instanceof Aesthetic)) {

return function styler(
defaultStyles?: StyleDeclarationOrCallback = {},
options?: HOCOptions = {},
): (WrappedComponent) => HOCComponent {
return style(aesthetic, defaultStyles, options);
return {
style(styleSheet: StyleSheet | StyleSheetCallback, options?: HOCOptions = {}): HOCWrapper {
return aesthetic.withStyles(styleSheet, options);
},
transform(...styles: StyleDeclaration[]): ClassName {
return aesthetic.transformStyles(styles);
},
};
}
/**
* @copyright 2017, Miles Johnson
* @license https://opensource.org/licenses/MIT
* @flow
*/

@@ -12,12 +13,6 @@

import createStyler from './createStyler';
import classes from './classes';
export const ClassNamesPropType = PropTypes.objectOf(PropTypes.string);
export const StylesPropType = PropTypes.objectOf(PropTypes.object);
export const ClassOrStylesPropType = PropTypes.oneOfType([
PropTypes.objectOf(PropTypes.string),
PropTypes.objectOf(PropTypes.object),
]);
export { Adapter, ClassNameAdapter, ThemeProvider, createStyler, classes };
export { Adapter, ClassNameAdapter, ThemeProvider, createStyler };
export default Aesthetic;

@@ -7,4 +7,2 @@ /**

/* eslint-disable react/require-default-props */
import React from 'react';

@@ -16,18 +14,19 @@ import PropTypes from 'prop-types';

import type {
TransformedStylesMap,
StyleDeclarationOrCallback,
WrappedComponent,
HOCComponent,
HOCOptions,
HOCWrappedComponent,
HOCWrapper,
StyleSheet,
StyleSheetCallback,
ThemeSheet,
} from '../../types';
type StyleProps = {
theme?: string,
[key: string]: *,
themeName: string,
};
type StyleState = {
classNames?: TransformedStylesMap,
theme?: string,
[key: string]: *,
styles?: StyleSheet,
theme?: ThemeSheet,
themeName: string,
};

@@ -40,12 +39,11 @@

aesthetic: Aesthetic,
styles: StyleDeclarationOrCallback = {},
options: HOCOptions = {},
): (WrappedComponent) => HOCComponent {
return function wrapStyles(Component: WrappedComponent): HOCComponent {
styleSheet: StyleSheet | StyleSheetCallback = {},
options?: HOCOptions = {},
): HOCWrapper {
return function wrapStyles(Component: HOCWrappedComponent): HOCComponent {
let styleName = options.styleName || Component.displayName || Component.name;
/*
* Function/constructor name aren't always available when code is minified,
* so only use it in development.
*/
// Function/constructor name aren't always available when code is minified,
// so only use it in development.
/* istanbul ignore else */
if (__DEV__) {

@@ -69,7 +67,5 @@ if (!(aesthetic instanceof Aesthetic)) {

/*
* When in production, we should generate a random string to use as the style name.
* If we don't do this, any minifiers that mangle function names would break
* Aesthetic's caching layer.
*/
// When in production, we should generate a random string to use as the style name.
// If we don't do this, any minifiers that mangle function names would break
// Aesthetic's caching layer.
} else {

@@ -90,5 +86,5 @@ instanceID += 1;

// Set base styles
aesthetic.setStyles(styleName, styles, extendFrom);
aesthetic.setStyles(styleName, styleSheet, extendFrom);
// $FlowIgnore
// $FlowIgnore Silence polymorphic errors
class StyledComponent extends ParentComponent<StyleProps, StyleState> {

@@ -99,15 +95,19 @@ static displayName: ?string = `Aesthetic(${styleName})`;

static wrappedComponent: WrappedComponent = Component;
static WrappedComponent: HOCWrappedComponent = Component;
static propTypes = {
[themePropName]: PropTypes.string,
static contextTypes = {
themeName: PropTypes.string,
};
static contextTypes = {
static propTypes = {
themeName: PropTypes.string,
};
static defaultProps = {
themeName: '',
};
// Allow consumers to customize styles
static extendStyles(
customStyles: StyleDeclarationOrCallback,
customStyleSheet?: StyleSheet | StyleSheetCallback = {},
extendOptions?: HOCOptions = {},

@@ -121,29 +121,26 @@ ): HOCComponent {

return style(
aesthetic,
customStyles,
{
...options,
...extendOptions,
extendFrom: styleName,
},
)(Component);
return style(aesthetic, customStyleSheet, {
...options,
...extendOptions,
extendFrom: styleName,
})(Component);
}
// Start transforming styles before we mount
state = {
firstMount: true,
[stylesPropName]: {},
themeName: '',
[themePropName]: {},
};
componentWillMount() {
this.transformStyles(this.getTheme(this.props));
this.transformStyles(this.props);
}
// Re-transform if the theme changes
componentWillReceiveProps(nextProps: StyleProps) {
const theme = this.getTheme(nextProps);
if (theme !== this.state[themePropName]) {
this.transformStyles(theme);
}
this.transformStyles(nextProps);
}
getTheme(props: StyleProps): string {
return props[themePropName] ||
getThemeName(props: StyleProps): string {
return props.themeName ||
this.context.themeName ||

@@ -154,13 +151,17 @@ aesthetic.options.defaultTheme ||

transformStyles(theme: string) {
this.setState({
[stylesPropName]: aesthetic.transformStyles(styleName, theme),
[themePropName]: theme,
});
transformStyles(props: Object) {
const themeName = this.getThemeName(props);
if (this.state.firstMount || themeName !== this.state.themeName) {
this.setState({
firstMount: false,
[stylesPropName]: aesthetic.createStyleSheet(styleName, themeName, props),
themeName,
[themePropName]: themeName ? aesthetic.getTheme(themeName) : {},
});
}
}
render(): React$Node {
return (
<Component {...this.props} {...this.state} />
);
return <Component {...this.props} {...this.state} />;
}

@@ -167,0 +168,0 @@ }

@@ -7,98 +7,280 @@ /**

import { isObject } from 'aesthetic-utils';
/* eslint-disable no-param-reassign */
import formatFontFace from './helpers/formatFontFace';
import isObject from './helpers/isObject';
import toArray from './helpers/toArray';
import type {
StyleDeclarationMap,
CSSStyle,
AtRuleSet,
AtRuleMap,
AtRuleCache,
AtRule,
EventCallback,
FallbackMap,
Style,
StyleBlock,
StyleDeclaration,
StyleSheet,
} from '../../types';
export const LOCAL = 'local';
export const GLOBAL = 'global';
export const AT_RULES = ['@fallbacks', '@font-face', '@keyframes', '@media'];
export const GLOBAL_RULES: AtRule[] = [
'@charset',
'@font-face',
'@global',
'@import',
'@keyframes',
'@namespace',
'@page',
'@viewport',
];
export const LOCAL_RULES: AtRule[] = [
'@fallbacks',
'@media',
'@supports',
];
export default class UnifiedSyntax {
events: { [eventName: string]: EventCallback } = {};
// Local
fallbacks: FallbackMap = {};
fontFaces: { [fontFamily: string]: StyleBlock[] } = {};
// Global
fontFaces: AtRuleMap = {};
fontFacesCache: { [fontFamily: string]: string } = {};
fontFaceNames: AtRuleCache = {};
keyframes: { [animationName: string]: StyleBlock } = {};
// Global
keyframes: AtRuleMap = {};
keyframesCache: { [animationName: string]: string } = {};
keyframeNames: AtRuleCache = {};
constructor() {
this
.on('property', this.handleProperty)
.on('@charset', this.handleCharset)
.on('@fallbacks', this.handleFallbacks)
.on('@font-face', this.handleFontFace)
.on('@global', this.handleGlobal)
.on('@import', this.handleImport)
.on('@keyframes', this.handleKeyframes)
.on('@media', this.handleMedia)
.on('@namespace', this.handleNamespace)
.on('@page', this.handlePage)
.on('@supports', this.handleSupports)
.on('@viewport', this.handleViewport);
}
// Local
mediaQueries: AtRuleSet = {};
/**
* Check that a value is a style declaration block.
*/
checkBlock(value: *): Object {
if (isObject(value)) {
return value;
}
static LOCAL: string = LOCAL;
throw new Error('Must be a style declaration.');
}
static GLOBAL: string = GLOBAL;
/**
* Convert the unified syntax to adapter specific syntax
* by extracting at-rules and applying conversions at each level.
* Convert a mapping of style declarations to their native syntax.
*/
convert(declarations: StyleDeclarationMap): StyleDeclarationMap {
this.resetLocalCache();
this.emit('converting');
convert(styleSheet: StyleSheet): StyleSheet {
const prevStyleSheet = { ...styleSheet };
const nextStyleSheet = {};
const adaptedDeclarations = { ...declarations };
// Extract global at-rules first
// eslint-disable-next-line complexity
GLOBAL_RULES.forEach((rule) => {
if (!prevStyleSheet[rule]) {
delete prevStyleSheet[rule];
// Extract at-rules first so that they are available for properties
AT_RULES.forEach((atRule: string) => {
if (atRule in adaptedDeclarations) {
this.extract(':root', atRule, adaptedDeclarations[atRule], GLOBAL);
return;
}
delete adaptedDeclarations[atRule];
switch (rule) {
case '@charset':
case '@import':
case '@namespace': {
const path = prevStyleSheet[rule];
if (typeof path === 'string') {
this.emit(rule, [nextStyleSheet, path]);
} else if (__DEV__) {
throw new Error(`${rule} value must be a string.`);
}
break;
}
case '@font-face': {
const faces = prevStyleSheet['@font-face'];
Object.keys(this.checkBlock(faces)).forEach((fontFamily) => {
if (__DEV__) {
if (this.fontFaces[fontFamily]) {
throw new Error(`@font-face "${fontFamily}" already exists.`);
}
}
// $FlowIgnore
this.fontFaces[fontFamily] = toArray(faces[fontFamily])
.map(font => ({
...font,
fontFamily,
}));
this.emit(rule, [nextStyleSheet, this.fontFaces[fontFamily], fontFamily]);
});
break;
}
case '@global': {
const globals = prevStyleSheet['@global'];
Object.keys(this.checkBlock(globals)).forEach((selector) => {
if (isObject(globals[selector])) {
this.emit(rule, [
nextStyleSheet,
this.convertDeclaration(selector, globals[selector]),
selector,
]);
} else if (__DEV__) {
throw new Error('Invalid @global selector style declaration.');
}
});
break;
}
case '@keyframes': {
const frames = prevStyleSheet['@keyframes'];
Object.keys(this.checkBlock(frames)).forEach((animationName) => {
if (__DEV__) {
if (this.keyframes[animationName]) {
throw new Error(`@keyframes "${animationName}" already exists.`);
}
}
this.keyframes[animationName] = this.checkBlock(frames[animationName]);
this.emit(rule, [nextStyleSheet, this.keyframes[animationName], animationName]);
});
break;
}
case '@page':
case '@viewport': {
const style = prevStyleSheet[rule];
if (isObject(style)) {
this.emit(rule, [nextStyleSheet, style]);
} else if (__DEV__) {
throw new Error(`${rule} must be a style object.`);
}
break;
}
/* istanbul ignore next */
default:
break;
}
delete prevStyleSheet[rule];
});
// Apply conversion to properties
Object.keys(adaptedDeclarations).forEach((setName: string) => {
const declaration = declarations[setName];
// Convert declarations last
Object.keys(prevStyleSheet).forEach((selector) => {
const declaration = prevStyleSheet[selector];
if (typeof declaration !== 'string') {
adaptedDeclarations[setName] = this.convertDeclaration(setName, declaration);
delete prevStyleSheet[selector];
if (!declaration) {
return;
}
// At-rule
if (selector.charAt(0) === '@') {
if (__DEV__) {
throw new SyntaxError(`Unsupported global at-rule "${selector}".`);
}
// Class name
} else if (typeof declaration === 'string') {
nextStyleSheet[selector] = declaration;
// Style object
} else if (isObject(declaration)) {
nextStyleSheet[selector] = this.convertDeclaration(selector, declaration);
} else if (__DEV__) {
throw new Error(`Invalid style declaration for "${selector}".`);
}
});
this.emit('converted');
return adaptedDeclarations;
return nextStyleSheet;
}
/**
* Convert an object of properties by extracting local at-rules
* and parsing fallbacks.
* Convert a style declaration including local at-rules and properties.
*/
convertDeclaration(setName: string, properties: CSSStyle): CSSStyle {
const nextProperties = { ...properties };
convertDeclaration(selector: string, declaration: StyleDeclaration): StyleDeclaration {
const prevDeclaration = { ...declaration };
const nextDeclaration = {};
AT_RULES.forEach((atRule: string) => {
if (atRule in nextProperties) {
this.extract(setName, atRule, nextProperties[atRule], LOCAL);
// Convert properties first
Object.keys(prevDeclaration).forEach((key) => {
if (key.charAt(0) !== '@') {
this.emit('property', [nextDeclaration, prevDeclaration[key], key]);
delete nextProperties[atRule];
delete prevDeclaration[key];
}
});
this.emit('declaration', [setName, nextProperties]);
// Extract local at-rules first
LOCAL_RULES.forEach((rule) => {
const style = prevDeclaration[rule];
return nextProperties;
delete prevDeclaration[rule];
if (!style || !isObject(style)) {
return;
}
if (rule === '@fallbacks') {
Object.keys(style).forEach((property) => {
this.emit(rule, [nextDeclaration, toArray(style[property]), property]);
});
} else if (rule === '@media' || rule === '@supports') {
Object.keys(style).forEach((condition) => {
if (isObject(style[condition])) {
this.emit(rule, [nextDeclaration, style[condition], condition]);
} else if (__DEV__) {
throw new Error(`${rule} ${condition} must be a mapping of conditions to style objects.`);
}
});
}
});
// Error for unknown at-rules
if (__DEV__) {
Object.keys(prevDeclaration).forEach((key) => {
throw new SyntaxError(`Unsupported local at-rule "${key}".`);
});
}
return nextDeclaration;
}
/**
* Create a noop function that throws an error for unsupported features.
*/
createUnsupportedHandler(rule: AtRule): () => void {
return () => {
throw new Error(`Adapter does not support "${rule}".`);
};
}
/**
* Execute the defined event listener with the arguments.
*/
emit(eventName: string, args: *[] = []): this {
emit(eventName: string, args: *[]): this {
if (this.events[eventName]) {

@@ -112,114 +294,119 @@ this.events[eventName](...args);

/**
* Extract at-rules and parser rules from both the global and local levels.
* Handle @charset.
*/
extract(setName: string, atRule: string, rules: *, fromScope: string) {
if (__DEV__) {
if (!isObject(rules)) {
throw new SyntaxError(`At-rule declaration "${atRule}" must be an object.`);
}
}
handleCharset(styleSheet: StyleSheet, style: string) {
styleSheet['@charset'] = style;
}
switch (atRule) {
case '@fallbacks':
this.extractFallbacks(setName, (rules: CSSStyle), fromScope);
break;
/**
* Handle fallback properties.
*/
handleFallbacks(declaration: StyleDeclaration, style: Style[], property: string) {
declaration[property] = [declaration[property], ...style].filter(Boolean);
}
case '@font-face':
this.extractFontFaces(setName, (rules: AtRuleMap), fromScope);
break;
/**
* Handle @font-face.
*/
handleFontFace(styleSheet: StyleSheet, style: StyleBlock[], fontFamily: string) {
if (Array.isArray(styleSheet['@font-face'])) {
styleSheet['@font-face'].push(...style);
} else {
styleSheet['@font-face'] = style;
}
}
case '@keyframes':
this.extractKeyframes(setName, (rules: AtRuleMap), fromScope);
break;
/**
* Handle global styles (like body, html, etc).
*/
handleGlobal(styleSheet: StyleSheet, declaration: StyleDeclaration, selector: string) {
// Do nothing
}
case '@media':
this.extractMediaQueries(setName, (rules: AtRuleMap), fromScope);
break;
/**
* Handle @namespace.
*/
handleImport(styleSheet: StyleSheet, style: string) {
styleSheet['@import'] = style;
}
default: {
if (__DEV__) {
throw new SyntaxError(`Unsupported at-rule "${atRule}".`);
}
}
}
/**
* Handle @keyframes.
*/
handleKeyframes(styleSheet: StyleSheet, style: StyleBlock, animationName: string) {
styleSheet[`@keyframes ${animationName}`] = style;
}
/**
* Extract property fallbacks.
* Handle @media.
*/
extractFallbacks(setName: string, properties: CSSStyle, fromScope: string) {
if (__DEV__) {
if (fromScope === GLOBAL) {
throw new SyntaxError('Property fallbacks must be defined locally to an element.');
}
}
handleMedia(declaration: StyleDeclaration, style: StyleBlock, condition: string) {
declaration[`@media ${condition}`] = style;
}
this.fallbacks[setName] = properties;
/**
* Handle @namespace.
*/
handleNamespace(styleSheet: StyleSheet, style: string) {
styleSheet['@namespace'] = style;
}
this.emit('fallback', [setName, properties]);
/**
* Handle @page.
*/
handlePage(styleSheet: StyleSheet, style: StyleBlock) {
styleSheet['@page'] = style;
}
/**
* Extract font face at-rules.
* Handle CSS properties.
*/
extractFontFaces(setName: string, rules: AtRuleMap, fromScope: string) {
if (__DEV__) {
if (fromScope === LOCAL) {
throw new SyntaxError('Font faces must be declared in the global scope.');
}
}
handleProperty = (declaration: StyleDeclaration, style: Style, property: string) => {
declaration[property] = style;
};
Object.keys(rules).forEach((name: string) => {
// Use the family name so raw CSS can reference it
const familyName = String(rules[name].fontFamily);
/**
* Handle @supports.
*/
handleSupports(declaration: StyleDeclaration, style: StyleBlock, condition: string) {
declaration[`@supports ${condition}`] = style;
}
if (this.fontFaces[familyName]) {
if (__DEV__) {
throw new TypeError(`Font face "${familyName}" has already been defined.`);
}
} else {
this.fontFaces[familyName] = rules[name];
}
this.emit('fontFace', [setName, familyName, rules[name]]);
});
/**
* Handle @viewport.
*/
handleViewport(styleSheet: StyleSheet, style: StyleBlock) {
styleSheet['@viewport'] = style;
}
/**
* Extract animation keyframes at-rules.
* Replace a `fontFamily` property with font face objects of the same name.
*/
extractKeyframes(setName: string, rules: AtRuleMap, fromScope: string) {
if (__DEV__) {
if (fromScope === LOCAL) {
throw new SyntaxError('Animation keyframes must be declared in the global scope.');
}
}
injectFontFaces(value: Style, cache: Object): Style[] {
const fontFaces = [];
Object.keys(rules).forEach((name: string) => {
if (this.keyframes[name]) {
if (__DEV__) {
throw new TypeError(`Animation keyframe "${name}" has already been defined.`);
}
String(value).split(',').forEach((name) => {
const familyName = name.trim();
const fonts = cache[familyName];
if (Array.isArray(fonts)) {
fonts.forEach((font) => {
fontFaces.push(formatFontFace(font));
});
} else {
this.keyframes[name] = rules[name];
fontFaces.push(familyName);
}
});
this.emit('keyframe', [setName, name, rules[name]]);
});
return fontFaces;
}
/**
* Extract media query at-rules.
* Replace a `animationName` property with keyframe objects of the same name.
*/
extractMediaQueries(setName: string, rules: AtRuleMap, fromScope: string) {
if (__DEV__) {
if (fromScope === GLOBAL) {
throw new SyntaxError('Media queries must be defined locally to an element.');
}
}
injectKeyframes(value: Style, cache: Object): Style[] {
return String(value).split(',').map((name) => {
const animationName = name.trim();
this.mediaQueries[setName] = rules;
Object.keys(rules).forEach((query: string) => {
this.emit('mediaQuery', [setName, query, rules[query]]);
return cache[animationName] || animationName;
});

@@ -245,18 +432,2 @@ }

}
/**
* Reset cached global at-rules.
*/
resetGlobalCache() {
this.fontFaces = {};
this.keyframes = {};
}
/**
* Reset cached local at-rules.
*/
resetLocalCache() {
this.fallbacks = {};
this.mediaQueries = {};
}
}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc