Skip to content

Commit

Permalink
Implements prepareStyles as composition of functions in muiTheme
Browse files Browse the repository at this point in the history
  • Loading branch information
newoga committed Jan 24, 2016
1 parent 733abf4 commit dbb7bb5
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 19 deletions.
1 change: 1 addition & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"presets": ["es2015", "stage-1", "react"],
"plugins": [
"transform-object-assign",
"transform-decorators-legacy",
"transform-dev-warning",
"add-module-exports"
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"homepage": "http://material-ui.com/",
"dependencies": {
"inline-style-prefixer": "^0.6.6",
"lodash.flowright": "^3.2.1",
"lodash.merge": "^3.3.2",
"lodash.throttle": "~3.0.4",
"react-addons-create-fragment": "^0.14.0",
Expand All @@ -52,6 +53,7 @@
"babel-plugin-add-module-exports": "^0.1.2",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-plugin-transform-dev-warning": "^0.1.0",
"babel-plugin-transform-object-assign": "^6.3.13",
"babel-plugin-transform-react-constant-elements": "^6.3.13",
"babel-plugin-transform-react-inline-elements": "^6.3.13",
"babel-plugin-transform-react-remove-prop-types": "^0.1.0",
Expand Down
11 changes: 7 additions & 4 deletions src/mixins/style-propable.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import {mergeStyles, mergeAndPrefix, prepareStyles as prepare} from '../utils/styles';
import {mergeStyles, mergeAndPrefix} from '../utils/styles';

/**
* This mixin isn't necessary and will be removed soon. DO NOT USE!
Expand All @@ -22,8 +22,11 @@ export default {
mergeAndPrefix,

prepareStyles(...args) {
return prepare((this.state && this.state.muiTheme) ||
this.context.muiTheme ||
(this.props && this.props.muiTheme), ...args);
const {
prepareStyles = (style) => (style),
} = (this.state && this.state.muiTheme) || (this.context && this.context.muiTheme) ||
(this.props && this.props.muiTheme) || {};

return prepareStyles(mergeStyles(...args));
},
};
26 changes: 26 additions & 0 deletions src/styles/getMuiTheme.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,21 @@ import ColorManipulator from '../utils/color-manipulator';
import autoPrefix from './auto-prefix';
import lightBaseTheme from './baseThemes/lightBaseTheme';
import zIndex from './zIndex';
import {autoprefixer, rtl} from './transformers';
import compose from 'lodash.flowright';
import warning from 'warning';

const CALLED_ONCE = Symbol('prepareStyles/calledOnce');

const callOnce = (transformer) => (style) => {
if (style[CALLED_ONCE]) {
warning(false, 'You cannot call prepareStyles() on the same style object more than once.');
return style;
} else {
style[CALLED_ONCE] = true;
return transformer(style);
}
};

/**
* Get the MUI theme corresponding to a base theme.
Expand Down Expand Up @@ -230,7 +245,18 @@ export default function getMuiTheme(baseTheme, muiTheme) {
},
}, muiTheme);

const transformers = [];

if (muiTheme.userAgent !== false) {
transformers.push(autoprefixer);
}

if (muiTheme.isRtl) {
transformers.push(rtl);
}

muiTheme.prefix = autoPrefix.getTransform(muiTheme.userAgent);
muiTheme.prepareStyles = callOnce(compose(...transformers.map(t => t(muiTheme))));

return muiTheme;
}
3 changes: 3 additions & 0 deletions src/styles/transformers/autoprefixer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default (muiTheme) => (style) => {
return muiTheme.prefix(style);
};
7 changes: 7 additions & 0 deletions src/styles/transformers/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import autoprefixer from './autoprefixer';
import rtl from './rtl';

export {
autoprefixer,
rtl,
};
78 changes: 78 additions & 0 deletions src/styles/transformers/rtl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
const reTranslate = /((^|\s)translate(3d|X)?\()(\-?[\d]+)/;
const reSkew = /((^|\s)skew(x|y)?\()\s*(\-?[\d]+)(deg|rad|grad)(,\s*(\-?[\d]+)(deg|rad|grad))?/;

/**
* This function ensures that `style` supports both ltr and rtl directions by
* checking `styleConstants` in `muiTheme` and replacing attribute keys if
* necessary.
*/
export default (muiTheme) => (style) => {
// Left to right is the default. No need to flip anything.
if (!muiTheme || !muiTheme.isRtl) return style;

const flippedAttributes = {
// Keys and their replacements.
right: 'left',
left: 'right',
marginRight: 'marginLeft',
marginLeft: 'marginRight',
paddingRight: 'paddingLeft',
paddingLeft: 'paddingRight',
borderRight: 'borderLeft',
borderLeft: 'borderRight',
};

let newStyle = {};

Object.keys(style).forEach(function(attribute) {
let value = style[attribute];
let key = attribute;

if (flippedAttributes.hasOwnProperty(attribute)) {
key = flippedAttributes[attribute];
}

switch (attribute) {
case 'float':
case 'textAlign':
if (value === 'right') {
value = 'left';
} else if (value === 'left') {
value = 'right';
}
break;

case 'direction':
if (value === 'ltr') {
value = 'rtl';
} else if (value === 'rtl') {
value = 'ltr';
}
break;

case 'transform':
let matches;
if ((matches = value.match(reTranslate))) {
value = value.replace(matches[0], matches[1] + (-parseFloat(matches[4])) );
}
if ((matches = value.match(reSkew))) {
value = value.replace(matches[0], matches[1] + (-parseFloat(matches[4])) + matches[5] +
matches[6] ? ',' + (-parseFloat(matches[7])) + matches[8] : ''
);
}
break;

case 'transformOrigin':
if (value.indexOf('right') > -1) {
value = value.replace('right', 'left');
} else if (value.indexOf('left') > -1) {
value = value.replace('left', 'right');
}
break;
}

newStyle[key] = value;
});

return newStyle;
};
16 changes: 1 addition & 15 deletions src/utils/styles.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
import autoPrefix from '../styles/auto-prefix';
import update from 'react-addons-update';
import warning from 'warning';

const reTranslate = /((^|\s)translate(3d|X)?\()(\-?[\d]+)/;

const reSkew = /((^|\s)skew(x|y)?\()\s*(\-?[\d]+)(deg|rad|grad)(,\s*(\-?[\d]+)(deg|rad|grad))?/;

function mergeSingle(objA, objB) {
if (!objA) return objB;
if (!objB) return objA;
return update(objA, {$merge: objB});
}
export const mergeStyles = (...args) => Object.assign({}, ...args);

/**
* This function ensures that `style` supports both ltr and rtl directions by
Expand Down Expand Up @@ -97,15 +92,6 @@ function ensureDirection(muiTheme, style) {
return newStyle;
}

export function mergeStyles(base, ...args) {
for (let i = 0; i < args.length; i++) {
if (args[i]) {
base = mergeSingle(base, args[i]);
}
}
return base;
}

/**
* `mergeAndPrefix` is used to merge styles and autoprefix them. It has has been deprecated
* and should no longer be used.
Expand Down

0 comments on commit dbb7bb5

Please sign in to comment.